diff options
| author | Yuuki Harano | 2021-01-30 23:37:19 +0900 |
|---|---|---|
| committer | Yuuki Harano | 2021-01-30 23:37:19 +0900 |
| commit | 50c76b844bc79309b4f5d9e28a2386b9a6f735b7 (patch) | |
| tree | 29f8273d8afccae1f16b723c36548cee150cb0bc /src/process.c | |
| parent | 563a0d94c379292bd88e83f18560ed21c497cea9 (diff) | |
| parent | 96f20120c97a0a329fff81a0cc3747082a8a2c55 (diff) | |
| download | emacs-50c76b844bc79309b4f5d9e28a2386b9a6f735b7.tar.gz emacs-50c76b844bc79309b4f5d9e28a2386b9a6f735b7.zip | |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/process.c b/src/process.c index 4ab194b2b5b..5ac0d20df5b 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -290,7 +290,9 @@ static int child_signal_read_fd = -1; | |||
| 290 | status changes. */ | 290 | status changes. */ |
| 291 | static int child_signal_write_fd = -1; | 291 | static int child_signal_write_fd = -1; |
| 292 | static void child_signal_init (void); | 292 | static void child_signal_init (void); |
| 293 | #ifndef WINDOWSNT | ||
| 293 | static void child_signal_read (int, void *); | 294 | static void child_signal_read (int, void *); |
| 295 | #endif | ||
| 294 | static void child_signal_notify (void); | 296 | static void child_signal_notify (void); |
| 295 | 297 | ||
| 296 | /* Indexed by descriptor, gives the process (if any) for that descriptor. */ | 298 | /* Indexed by descriptor, gives the process (if any) for that descriptor. */ |
| @@ -7152,8 +7154,23 @@ process has been transmitted to the serial port. */) | |||
| 7152 | have the same process ID. | 7154 | have the same process ID. |
| 7153 | 7155 | ||
| 7154 | To avoid a deadlock when receiving SIGCHLD while | 7156 | To avoid a deadlock when receiving SIGCHLD while |
| 7155 | `wait_reading_process_output' is in `pselect', the SIGCHLD handler | 7157 | 'wait_reading_process_output' is in 'pselect', the SIGCHLD handler |
| 7156 | will notify the `pselect' using a pipe. */ | 7158 | will notify the `pselect' using a self-pipe. The deadlock could |
| 7159 | occur if SIGCHLD is delivered outside of the 'pselect' call, in | ||
| 7160 | which case 'pselect' will not be interrupted by the signal, and | ||
| 7161 | will therefore wait on the process's output descriptor for the | ||
| 7162 | output that will never come. | ||
| 7163 | |||
| 7164 | WINDOWSNT doesn't need this facility because its 'pselect' | ||
| 7165 | emulation (see 'sys_select' in w32proc.c) waits on a subprocess | ||
| 7166 | handle, which becomes signaled when the process exits, and also | ||
| 7167 | because that emulation delays the delivery of the simulated SIGCHLD | ||
| 7168 | until all the output from the subprocess has been consumed. */ | ||
| 7169 | |||
| 7170 | /* FIXME: On Unix-like systems that have a proper 'pselect' | ||
| 7171 | (HAVE_PSELECT), we should block SIGCHLD in | ||
| 7172 | 'wait_reading_process_output' and pass a non-NULL signal mask to | ||
| 7173 | 'pselect' to avoid the need for the self-pipe. */ | ||
| 7157 | 7174 | ||
| 7158 | /* Set up `child_signal_read_fd' and `child_signal_write_fd'. */ | 7175 | /* Set up `child_signal_read_fd' and `child_signal_write_fd'. */ |
| 7159 | 7176 | ||
| @@ -7163,6 +7180,7 @@ child_signal_init (void) | |||
| 7163 | /* Either both are initialized, or both are uninitialized. */ | 7180 | /* Either both are initialized, or both are uninitialized. */ |
| 7164 | eassert ((child_signal_read_fd < 0) == (child_signal_write_fd < 0)); | 7181 | eassert ((child_signal_read_fd < 0) == (child_signal_write_fd < 0)); |
| 7165 | 7182 | ||
| 7183 | #ifndef WINDOWSNT | ||
| 7166 | if (0 <= child_signal_read_fd) | 7184 | if (0 <= child_signal_read_fd) |
| 7167 | return; /* already done */ | 7185 | return; /* already done */ |
| 7168 | 7186 | ||
| @@ -7185,12 +7203,16 @@ child_signal_init (void) | |||
| 7185 | eassert (0 <= fds[1]); | 7203 | eassert (0 <= fds[1]); |
| 7186 | if (fcntl (fds[0], F_SETFL, O_NONBLOCK) != 0) | 7204 | if (fcntl (fds[0], F_SETFL, O_NONBLOCK) != 0) |
| 7187 | emacs_perror ("fcntl"); | 7205 | emacs_perror ("fcntl"); |
| 7206 | if (fcntl (fds[1], F_SETFL, O_NONBLOCK) != 0) | ||
| 7207 | emacs_perror ("fcntl"); | ||
| 7188 | add_read_fd (fds[0], child_signal_read, NULL); | 7208 | add_read_fd (fds[0], child_signal_read, NULL); |
| 7189 | fd_callback_info[fds[0]].flags &= ~KEYBOARD_FD; | 7209 | fd_callback_info[fds[0]].flags &= ~KEYBOARD_FD; |
| 7190 | child_signal_read_fd = fds[0]; | 7210 | child_signal_read_fd = fds[0]; |
| 7191 | child_signal_write_fd = fds[1]; | 7211 | child_signal_write_fd = fds[1]; |
| 7212 | #endif /* !WINDOWSNT */ | ||
| 7192 | } | 7213 | } |
| 7193 | 7214 | ||
| 7215 | #ifndef WINDOWSNT | ||
| 7194 | /* Consume a process status change. */ | 7216 | /* Consume a process status change. */ |
| 7195 | 7217 | ||
| 7196 | static void | 7218 | static void |
| @@ -7199,9 +7221,10 @@ child_signal_read (int fd, void *data) | |||
| 7199 | eassert (0 <= fd); | 7221 | eassert (0 <= fd); |
| 7200 | eassert (fd == child_signal_read_fd); | 7222 | eassert (fd == child_signal_read_fd); |
| 7201 | char dummy; | 7223 | char dummy; |
| 7202 | if (emacs_read (fd, &dummy, 1) < 0) | 7224 | if (emacs_read (fd, &dummy, 1) < 0 && errno != EAGAIN) |
| 7203 | emacs_perror ("reading from child signal FD"); | 7225 | emacs_perror ("reading from child signal FD"); |
| 7204 | } | 7226 | } |
| 7227 | #endif /* !WINDOWSNT */ | ||
| 7205 | 7228 | ||
| 7206 | /* Notify `wait_reading_process_output' of a process status | 7229 | /* Notify `wait_reading_process_output' of a process status |
| 7207 | change. */ | 7230 | change. */ |
| @@ -7209,11 +7232,13 @@ child_signal_read (int fd, void *data) | |||
| 7209 | static void | 7232 | static void |
| 7210 | child_signal_notify (void) | 7233 | child_signal_notify (void) |
| 7211 | { | 7234 | { |
| 7235 | #ifndef WINDOWSNT | ||
| 7212 | int fd = child_signal_write_fd; | 7236 | int fd = child_signal_write_fd; |
| 7213 | eassert (0 <= fd); | 7237 | eassert (0 <= fd); |
| 7214 | char dummy = 0; | 7238 | char dummy = 0; |
| 7215 | if (emacs_write (fd, &dummy, 1) != 1) | 7239 | if (emacs_write (fd, &dummy, 1) != 1) |
| 7216 | emacs_perror ("writing to child signal FD"); | 7240 | emacs_perror ("writing to child signal FD"); |
| 7241 | #endif | ||
| 7217 | } | 7242 | } |
| 7218 | 7243 | ||
| 7219 | /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing | 7244 | /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing |