6 | 6 |
* int rc = -1;
|
7 | 7 |
*/
|
8 | 8 |
struct stat64 buf;
|
|
9 |
int overly_magic_nonblocking = 0;
|
9 | 10 |
int existed = 1;
|
10 | 11 |
int save_errno;
|
|
12 |
sigset_t local_saved_sigmask;
|
11 | 13 |
|
12 | 14 |
/* mask out mode bits appropriately */
|
13 | 15 |
mode = mode & ~pseudo_umask;
|
|
60 | 62 |
errno = save_errno;
|
61 | 63 |
}
|
62 | 64 |
|
|
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 |
}
|
63 | 86 |
/* because we are not actually root, secretly mask in 0600 to the
|
64 | 87 |
* underlying mode. The ", 0" is because the only time mode matters
|
65 | 88 |
* is if a file is going to be created, in which case it's
|
|
70 | 93 |
#else
|
71 | 94 |
rc = real_openat(dirfd, path, flags, PSEUDO_FS_MODE(mode, 0));
|
72 | 95 |
#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 |
}
|
73 | 110 |
|
74 | 111 |
if (rc != -1) {
|
75 | 112 |
save_errno = errno;
|