Codebase list pseudo / a1fafc4
Try to handle blocking open. This is a heck of a special case: If you call open on a FIFO/pipe, and you didn't have O_NONBLOCK, and you used O_RDONLY or O_WRONLY, but not O_RDWR, the open can block forever. Unfortunately, pseudo assumes syscalls complete. We attempt to drop the lock and restore our state, then recover it later. Why? Because the .NET runtime does this for a debug hook. Seebs 5 years ago
2 changed file(s) with 41 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 2019-04-10:
1 * (seebs) Experimental workaround for special non-blocking open
2 case.
3
04 2019-04-09:
15 * (seebs) Partial fix for db corruption issue.
26 * (seebs) Make a glibc renameat2 wrapper that just fails because
66 * int rc = -1;
77 */
88 struct stat64 buf;
9 int overly_magic_nonblocking = 0;
910 int existed = 1;
1011 int save_errno;
12 sigset_t local_saved_sigmask;
1113
1214 /* mask out mode bits appropriately */
1315 mode = mode & ~pseudo_umask;
6062 errno = save_errno;
6163 }
6264
65 /* if a pipe is opened without O_NONBLOCK, for only reading or
66 * only writing, it can block forever. We need to do extra magic
67 * in that case...
68 */
69 if (!(flags & O_NONBLOCK) && ((flags & (O_WRONLY | O_RDONLY | O_RDWR)) != O_RDWR)) {
70 save_errno = errno;
71 #ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
72 rc = real___xstat64(_STAT_VER, path, &buf);
73 #else
74 rc = real___fxstatat64(_STAT_VER, dirfd, path, &buf, 0);
75 #endif
76 if (rc != -1 && S_ISFIFO(buf.st_mode)) {
77 overly_magic_nonblocking = 1;
78 }
79 }
80
81 /* this is a horrible special case and i do not know whether it will work */
82 if (overly_magic_nonblocking) {
83 pseudo_droplock();
84 sigprocmask(SIG_SETMASK, &pseudo_saved_sigmask, &local_saved_sigmask);
85 }
6386 /* because we are not actually root, secretly mask in 0600 to the
6487 * underlying mode. The ", 0" is because the only time mode matters
6588 * is if a file is going to be created, in which case it's
7093 #else
7194 rc = real_openat(dirfd, path, flags, PSEUDO_FS_MODE(mode, 0));
7295 #endif
96 if (overly_magic_nonblocking) {
97 save_errno = errno;
98 sigprocmask(SIG_SETMASK, &local_saved_sigmask, NULL);
99 /* well this is a problem. we can't NOT proceed; we may have
100 * already opened the file! we can't even return up the call
101 * stack to stuff that's going to try to drop the lock.
102 */
103 if (pseudo_getlock()) {
104 pseudo_diag("PANIC: after opening a readonly/writeonly FIFO (path '%s', fd %d, errno %d, saved errno %d), could not regain lock. unrecoverable. sorry. bye.\n",
105 path, rc, errno, save_errno);
106 abort();
107 }
108 errno = save_errno;
109 }
73110
74111 if (rc != -1) {
75112 save_errno = errno;