aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorYuuki Harano2021-01-30 23:37:19 +0900
committerYuuki Harano2021-01-30 23:37:19 +0900
commit50c76b844bc79309b4f5d9e28a2386b9a6f735b7 (patch)
tree29f8273d8afccae1f16b723c36548cee150cb0bc /src/process.c
parent563a0d94c379292bd88e83f18560ed21c497cea9 (diff)
parent96f20120c97a0a329fff81a0cc3747082a8a2c55 (diff)
downloademacs-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.c31
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. */
291static int child_signal_write_fd = -1; 291static int child_signal_write_fd = -1;
292static void child_signal_init (void); 292static void child_signal_init (void);
293#ifndef WINDOWSNT
293static void child_signal_read (int, void *); 294static void child_signal_read (int, void *);
295#endif
294static void child_signal_notify (void); 296static 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
7196static void 7218static 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)
7209static void 7232static void
7210child_signal_notify (void) 7233child_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