aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c215
1 files changed, 103 insertions, 112 deletions
diff --git a/src/process.c b/src/process.c
index 77e99ead01f..43f0239d301 100644
--- a/src/process.c
+++ b/src/process.c
@@ -130,6 +130,10 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
130 EMACS_TIME *, void *); 130 EMACS_TIME *, void *);
131#endif 131#endif
132 132
133/* This is for DOS_NT ports. FIXME: Remove this old portability cruft
134 by having DOS_NT ports implement waitpid instead of wait. Nowadays
135 POSIXish hosts all define waitpid, WNOHANG, and WUNTRACED, as these
136 have been standard since POSIX.1-1988. */
133#ifndef WNOHANG 137#ifndef WNOHANG
134# undef waitpid 138# undef waitpid
135# define waitpid(pid, status, options) wait (status) 139# define waitpid(pid, status, options) wait (status)
@@ -795,9 +799,8 @@ get_process (register Lisp_Object name)
795#ifdef SIGCHLD 799#ifdef SIGCHLD
796/* Fdelete_process promises to immediately forget about the process, but in 800/* Fdelete_process promises to immediately forget about the process, but in
797 reality, Emacs needs to remember those processes until they have been 801 reality, Emacs needs to remember those processes until they have been
798 treated by the SIGCHLD handler; otherwise this handler would consider the 802 treated by the SIGCHLD handler and waitpid has been invoked on them;
799 process as being synchronous and say that the synchronous process is 803 otherwise they might fill up the kernel's process table. */
800 dead. */
801static Lisp_Object deleted_pid_list; 804static Lisp_Object deleted_pid_list;
802#endif 805#endif
803 806
@@ -1704,16 +1707,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1704 if (inchannel > max_process_desc) 1707 if (inchannel > max_process_desc)
1705 max_process_desc = inchannel; 1708 max_process_desc = inchannel;
1706 1709
1707 /* Until we store the proper pid, enable the SIGCHLD handler 1710 /* This may signal an error. */
1708 to recognize an unknown pid as standing for this process.
1709 It is very important not to let this `marker' value stay
1710 in the table after this function has returned; if it does
1711 it might cause call-process to hang and subsequent asynchronous
1712 processes to get their return values scrambled. */
1713 XPROCESS (process)->pid = -1;
1714
1715 /* This must be called after the above line because it may signal an
1716 error. */
1717 setup_process_coding_systems (process); 1711 setup_process_coding_systems (process);
1718 1712
1719 encoded_current_dir = ENCODE_FILE (current_dir); 1713 encoded_current_dir = ENCODE_FILE (current_dir);
@@ -1745,7 +1739,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1745 /* Make the pty be the controlling terminal of the process. */ 1739 /* Make the pty be the controlling terminal of the process. */
1746#ifdef HAVE_PTYS 1740#ifdef HAVE_PTYS
1747 /* First, disconnect its current controlling terminal. */ 1741 /* First, disconnect its current controlling terminal. */
1748#ifdef HAVE_SETSID
1749 /* We tried doing setsid only if pty_flag, but it caused 1742 /* We tried doing setsid only if pty_flag, but it caused
1750 process_set_signal to fail on SGI when using a pipe. */ 1743 process_set_signal to fail on SGI when using a pipe. */
1751 setsid (); 1744 setsid ();
@@ -1758,12 +1751,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1758 ioctl (xforkin, TIOCSCTTY, 0); 1751 ioctl (xforkin, TIOCSCTTY, 0);
1759#endif 1752#endif
1760 } 1753 }
1761#else /* not HAVE_SETSID */
1762 /* It's very important to call setpgid here and no time
1763 afterwards. Otherwise, we lose our controlling tty which
1764 is set when we open the pty. */
1765 setpgid (0, 0);
1766#endif /* not HAVE_SETSID */
1767#if defined (LDISC1) 1754#if defined (LDISC1)
1768 if (pty_flag && xforkin >= 0) 1755 if (pty_flag && xforkin >= 0)
1769 { 1756 {
@@ -1796,22 +1783,15 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1796 ioctl (j, TIOCNOTTY, 0); 1783 ioctl (j, TIOCNOTTY, 0);
1797 emacs_close (j); 1784 emacs_close (j);
1798 } 1785 }
1799#ifndef USG
1800 /* In order to get a controlling terminal on some versions
1801 of BSD, it is necessary to put the process in pgrp 0
1802 before it opens the terminal. */
1803 setpgid (0, 0);
1804#endif
1805 } 1786 }
1806#endif /* TIOCNOTTY */ 1787#endif /* TIOCNOTTY */
1807 1788
1808#if !defined (DONT_REOPEN_PTY) 1789#if !defined (DONT_REOPEN_PTY)
1809/*** There is a suggestion that this ought to be a 1790/*** There is a suggestion that this ought to be a
1810 conditional on TIOCSPGRP, 1791 conditional on TIOCSPGRP, or !defined TIOCSCTTY.
1811 or !(defined (HAVE_SETSID) && defined (TIOCSCTTY)).
1812 Trying the latter gave the wrong results on Debian GNU/Linux 1.1; 1792 Trying the latter gave the wrong results on Debian GNU/Linux 1.1;
1813 that system does seem to need this code, even though 1793 that system does seem to need this code, even though
1814 both HAVE_SETSID and TIOCSCTTY are defined. */ 1794 both TIOCSCTTY is defined. */
1815 /* Now close the pty (if we had it open) and reopen it. 1795 /* Now close the pty (if we had it open) and reopen it.
1816 This makes the pty the controlling terminal of the subprocess. */ 1796 This makes the pty the controlling terminal of the subprocess. */
1817 if (pty_flag) 1797 if (pty_flag)
@@ -1880,6 +1860,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1880#endif 1860#endif
1881 1861
1882 XPROCESS (process)->pid = pid; 1862 XPROCESS (process)->pid = pid;
1863 if (0 <= pid)
1864 XPROCESS (process)->alive = 1;
1883 1865
1884 /* Stop blocking signals in the parent. */ 1866 /* Stop blocking signals in the parent. */
1885#ifdef SIGCHLD 1867#ifdef SIGCHLD
@@ -4437,7 +4419,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4437 if (EMACS_TIME_LT (timer_delay, timeout)) 4419 if (EMACS_TIME_LT (timer_delay, timeout))
4438 { 4420 {
4439 timeout = timer_delay; 4421 timeout = timer_delay;
4440 timeout_reduced_for_timers = 1; 4422 timeout_reduced_for_timers = 1;
4441 } 4423 }
4442 } 4424 }
4443 else 4425 else
@@ -6273,9 +6255,35 @@ process has been transmitted to the serial port. */)
6273 return process; 6255 return process;
6274} 6256}
6275 6257
6276/* On receipt of a signal that a child status has changed, loop asking 6258/* If the status of the process DESIRED has changed, return true and
6277 about children with changed statuses until the system says there 6259 set *STATUS to its exit status; otherwise, return false.
6278 are no more. 6260 If HAVE is nonnegative, assume that HAVE = waitpid (HAVE, STATUS, ...)
6261 has already been invoked, and do not invoke waitpid again. */
6262
6263static bool
6264process_status_retrieved (pid_t desired, pid_t have, int *status)
6265{
6266 if (have < 0)
6267 {
6268 /* Invoke waitpid only with a known process ID; do not invoke
6269 waitpid with a nonpositive argument. Otherwise, Emacs might
6270 reap an unwanted process by mistake. For example, invoking
6271 waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
6272 so that another thread running glib won't find them. */
6273 do
6274 have = waitpid (desired, status, WNOHANG | WUNTRACED);
6275 while (have < 0 && errno == EINTR);
6276 }
6277
6278 return have == desired;
6279}
6280
6281/* If PID is nonnegative, the child process PID with wait status W has
6282 changed its status; record this and return true.
6283
6284 If PID is negative, ignore W, and look for known child processes
6285 of Emacs whose status have changed. For each one found, record its new
6286 status.
6279 6287
6280 All we do is change the status; we do not run sentinels or print 6288 All we do is change the status; we do not run sentinels or print
6281 notifications. That is saved for the next time keyboard input is 6289 notifications. That is saved for the next time keyboard input is
@@ -6298,13 +6306,23 @@ process has been transmitted to the serial port. */)
6298 ** Malloc WARNING: This should never call malloc either directly or 6306 ** Malloc WARNING: This should never call malloc either directly or
6299 indirectly; if it does, that is a bug */ 6307 indirectly; if it does, that is a bug */
6300 6308
6301/* Record the changed status of the child process PID with wait status W. */
6302void 6309void
6303record_child_status_change (pid_t pid, int w) 6310record_child_status_change (pid_t pid, int w)
6304{ 6311{
6305#ifdef SIGCHLD 6312#ifdef SIGCHLD
6306 Lisp_Object proc; 6313
6307 struct Lisp_Process *p; 6314# ifdef WNOHANG
6315 /* On POSIXish hosts, record at most one child only if we already
6316 know one child that has exited. */
6317 bool record_at_most_one_child = 0 <= pid;
6318# else
6319 /* On DOS_NT (the only porting target that lacks WNOHANG),
6320 record the status of at most one child process, since the SIGCHLD
6321 handler must return right away. If any more processes want to
6322 signal us, we will get another signal. */
6323 bool record_at_most_one_child = 1;
6324# endif
6325
6308 Lisp_Object tail; 6326 Lisp_Object tail;
6309 6327
6310 /* Find the process that signaled us, and record its status. */ 6328 /* Find the process that signaled us, and record its status. */
@@ -6312,68 +6330,69 @@ record_child_status_change (pid_t pid, int w)
6312 /* The process can have been deleted by Fdelete_process. */ 6330 /* The process can have been deleted by Fdelete_process. */
6313 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) 6331 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail))
6314 { 6332 {
6333 bool all_pids_are_fixnums
6334 = (MOST_NEGATIVE_FIXNUM <= TYPE_MINIMUM (pid_t)
6335 && TYPE_MAXIMUM (pid_t) <= MOST_POSITIVE_FIXNUM);
6315 Lisp_Object xpid = XCAR (tail); 6336 Lisp_Object xpid = XCAR (tail);
6316 if ((INTEGERP (xpid) && pid == XINT (xpid)) 6337 if (all_pids_are_fixnums ? INTEGERP (xpid) : NUMBERP (xpid))
6317 || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid)))
6318 { 6338 {
6319 XSETCAR (tail, Qnil); 6339 pid_t deleted_pid;
6320 return; 6340 if (INTEGERP (xpid))
6341 deleted_pid = XINT (xpid);
6342 else
6343 deleted_pid = XFLOAT_DATA (xpid);
6344 if (process_status_retrieved (deleted_pid, pid, &w))
6345 {
6346 XSETCAR (tail, Qnil);
6347 if (record_at_most_one_child)
6348 return;
6349 }
6321 } 6350 }
6322 } 6351 }
6323 6352
6324 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ 6353 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */
6325 p = 0;
6326 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) 6354 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6327 { 6355 {
6328 proc = XCDR (XCAR (tail)); 6356 Lisp_Object proc = XCDR (XCAR (tail));
6329 p = XPROCESS (proc); 6357 struct Lisp_Process *p = XPROCESS (proc);
6330 if (EQ (p->type, Qreal) && p->pid == pid) 6358 if (p->alive && process_status_retrieved (p->pid, pid, &w))
6331 break; 6359 {
6332 p = 0; 6360 /* Change the status of the process that was found. */
6333 } 6361 p->tick = ++process_tick;
6334 6362 p->raw_status = w;
6335 /* Look for an asynchronous process whose pid hasn't been filled 6363 p->raw_status_new = 1;
6336 in yet. */
6337 if (! p)
6338 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6339 {
6340 proc = XCDR (XCAR (tail));
6341 p = XPROCESS (proc);
6342 if (p->pid == -1)
6343 break;
6344 p = 0;
6345 }
6346 6364
6347 /* Change the status of the process that was found. */ 6365 /* If process has terminated, stop waiting for its output. */
6348 if (p) 6366 if (WIFSIGNALED (w) || WIFEXITED (w))
6349 { 6367 {
6350 int clear_desc_flag = 0; 6368 int clear_desc_flag = 0;
6369 p->alive = 0;
6370 if (p->infd >= 0)
6371 clear_desc_flag = 1;
6351 6372
6352 p->tick = ++process_tick; 6373 /* clear_desc_flag avoids a compiler bug in Microsoft C. */
6353 p->raw_status = w; 6374 if (clear_desc_flag)
6354 p->raw_status_new = 1; 6375 {
6376 FD_CLR (p->infd, &input_wait_mask);
6377 FD_CLR (p->infd, &non_keyboard_wait_mask);
6378 }
6379 }
6355 6380
6356 /* If process has terminated, stop waiting for its output. */ 6381 /* Tell wait_reading_process_output that it needs to wake up and
6357 if ((WIFSIGNALED (w) || WIFEXITED (w)) 6382 look around. */
6358 && p->infd >= 0) 6383 if (input_available_clear_time)
6359 clear_desc_flag = 1; 6384 *input_available_clear_time = make_emacs_time (0, 0);
6360 6385
6361 /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ 6386 if (record_at_most_one_child)
6362 if (clear_desc_flag) 6387 return;
6363 {
6364 FD_CLR (p->infd, &input_wait_mask);
6365 FD_CLR (p->infd, &non_keyboard_wait_mask);
6366 } 6388 }
6367
6368 /* Tell wait_reading_process_output that it needs to wake up and
6369 look around. */
6370 if (input_available_clear_time)
6371 *input_available_clear_time = make_emacs_time (0, 0);
6372 } 6389 }
6373 /* There was no asynchronous process found for that pid: we have 6390
6374 a synchronous process. */ 6391 if (0 <= pid)
6375 else
6376 { 6392 {
6393 /* The caller successfully waited for a pid but no asynchronous
6394 process was found for it, so this is a synchronous process. */
6395
6377 synch_process_alive = 0; 6396 synch_process_alive = 0;
6378 6397
6379 /* Report the status of the synchronous process. */ 6398 /* Report the status of the synchronous process. */
@@ -6392,38 +6411,10 @@ record_child_status_change (pid_t pid, int w)
6392 6411
6393#ifdef SIGCHLD 6412#ifdef SIGCHLD
6394 6413
6395/* On some systems, the SIGCHLD handler must return right away. If
6396 any more processes want to signal us, we will get another signal.
6397 Otherwise, loop around to use up all the processes that have
6398 something to tell us. */
6399#if (defined WINDOWSNT \
6400 || (defined USG && !defined GNU_LINUX \
6401 && !(defined HPUX && defined WNOHANG)))
6402enum { CAN_HANDLE_MULTIPLE_CHILDREN = 0 };
6403#else
6404enum { CAN_HANDLE_MULTIPLE_CHILDREN = 1 };
6405#endif
6406
6407static void 6414static void
6408handle_child_signal (int sig) 6415handle_child_signal (int sig)
6409{ 6416{
6410 do 6417 record_child_status_change (-1, 0);
6411 {
6412 pid_t pid;
6413 int status;
6414
6415 do
6416 pid = waitpid (-1, &status, WNOHANG | WUNTRACED);
6417 while (pid < 0 && errno == EINTR);
6418
6419 /* PID == 0 means no processes found, PID == -1 means a real failure.
6420 Either way, we have done all our job. */
6421 if (pid <= 0)
6422 break;
6423
6424 record_child_status_change (pid, status);
6425 }
6426 while (CAN_HANDLE_MULTIPLE_CHILDREN);
6427} 6418}
6428 6419
6429static void 6420static void