aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorKenichi Handa2012-09-06 10:49:15 +0900
committerKenichi Handa2012-09-06 10:49:15 +0900
commitfca81a8d405cd4c825e144099c54dd163636aa3b (patch)
treeee09be4b0e079b9c8863c8b570496a169227b218 /src/process.c
parentf41d6f9db69ce77fe9b3a637de407e8b589e0dc4 (diff)
parent067b39d4296765e83f9530eca456168f6cda95fc (diff)
downloademacs-fca81a8d405cd4c825e144099c54dd163636aa3b.tar.gz
emacs-fca81a8d405cd4c825e144099c54dd163636aa3b.zip
merge trunk
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c256
1 files changed, 129 insertions, 127 deletions
diff --git a/src/process.c b/src/process.c
index 5677da36881..3a6615fb505 100644
--- a/src/process.c
+++ b/src/process.c
@@ -124,6 +124,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
124#include "xgselect.h" 124#include "xgselect.h"
125#endif 125#endif
126 126
127#ifndef WNOHANG
128# undef waitpid
129# define waitpid(pid, status, options) wait (status)
130#endif
131#ifndef WUNTRACED
132# define WUNTRACED 0
133#endif
134
127/* Work around GCC 4.7.0 bug with strict overflow checking; see 135/* Work around GCC 4.7.0 bug with strict overflow checking; see
128 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. 136 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>.
129 These lines can be removed once the GCC bug is fixed. */ 137 These lines can be removed once the GCC bug is fixed. */
@@ -801,7 +809,7 @@ get_process (register Lisp_Object name)
801#ifdef SIGCHLD 809#ifdef SIGCHLD
802/* Fdelete_process promises to immediately forget about the process, but in 810/* Fdelete_process promises to immediately forget about the process, but in
803 reality, Emacs needs to remember those processes until they have been 811 reality, Emacs needs to remember those processes until they have been
804 treated by sigchld_handler; otherwise this handler would consider the 812 treated by the SIGCHLD handler; otherwise this handler would consider the
805 process as being synchronous and say that the synchronous process is 813 process as being synchronous and say that the synchronous process is
806 dead. */ 814 dead. */
807static Lisp_Object deleted_pid_list; 815static Lisp_Object deleted_pid_list;
@@ -849,7 +857,8 @@ nil, indicating the current buffer's process. */)
849#endif 857#endif
850 { 858 {
851 Fkill_process (process, Qnil); 859 Fkill_process (process, Qnil);
852 /* Do this now, since remove_process will make sigchld_handler do nothing. */ 860 /* Do this now, since remove_process will make the
861 SIGCHLD handler do nothing. */
853 pset_status (p, Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil))); 862 pset_status (p, Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil)));
854 p->tick = ++process_tick; 863 p->tick = ++process_tick;
855 status_notify (p); 864 status_notify (p);
@@ -1728,7 +1737,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1728 if (inchannel > max_process_desc) 1737 if (inchannel > max_process_desc)
1729 max_process_desc = inchannel; 1738 max_process_desc = inchannel;
1730 1739
1731 /* Until we store the proper pid, enable sigchld_handler 1740 /* Until we store the proper pid, enable the SIGCHLD handler
1732 to recognize an unknown pid as standing for this process. 1741 to recognize an unknown pid as standing for this process.
1733 It is very important not to let this `marker' value stay 1742 It is very important not to let this `marker' value stay
1734 in the table after this function has returned; if it does 1743 in the table after this function has returned; if it does
@@ -4956,8 +4965,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4956 4965
4957 if (p->pid == -2) 4966 if (p->pid == -2)
4958 { 4967 {
4959 /* If the EIO occurs on a pty, sigchld_handler's 4968 /* If the EIO occurs on a pty, the SIGCHLD handler's
4960 waitpid() will not find the process object to 4969 waitpid call will not find the process object to
4961 delete. Do it here. */ 4970 delete. Do it here. */
4962 p->tick = ++process_tick; 4971 p->tick = ++process_tick;
4963 pset_status (p, Qfailed); 4972 pset_status (p, Qfailed);
@@ -5422,18 +5431,19 @@ read_process_output (Lisp_Object proc, register int channel)
5422static jmp_buf send_process_frame; 5431static jmp_buf send_process_frame;
5423static Lisp_Object process_sent_to; 5432static Lisp_Object process_sent_to;
5424 5433
5425#ifndef FORWARD_SIGNAL_TO_MAIN_THREAD 5434static _Noreturn void
5426static _Noreturn void send_process_trap (int); 5435handle_pipe_signal (int sig)
5427#endif
5428
5429static void
5430send_process_trap (int ignore)
5431{ 5436{
5432 SIGNAL_THREAD_CHECK (SIGPIPE);
5433 sigunblock (sigmask (SIGPIPE)); 5437 sigunblock (sigmask (SIGPIPE));
5434 _longjmp (send_process_frame, 1); 5438 _longjmp (send_process_frame, 1);
5435} 5439}
5436 5440
5441static void
5442deliver_pipe_signal (int sig)
5443{
5444 handle_on_main_thread (sig, handle_pipe_signal);
5445}
5446
5437/* In send_process, when a write fails temporarily, 5447/* In send_process, when a write fails temporarily,
5438 wait_reading_process_output is called. It may execute user code, 5448 wait_reading_process_output is called. It may execute user code,
5439 e.g. timers, that attempts to write new data to the same process. 5449 e.g. timers, that attempts to write new data to the same process.
@@ -5663,7 +5673,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5663 /* Send this batch, using one or more write calls. */ 5673 /* Send this batch, using one or more write calls. */
5664 ptrdiff_t written = 0; 5674 ptrdiff_t written = 0;
5665 int outfd = p->outfd; 5675 int outfd = p->outfd;
5666 old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap); 5676 old_sigpipe = signal (SIGPIPE, deliver_pipe_signal);
5667#ifdef DATAGRAM_SOCKETS 5677#ifdef DATAGRAM_SOCKETS
5668 if (DATAGRAM_CHAN_P (outfd)) 5678 if (DATAGRAM_CHAN_P (outfd))
5669 { 5679 {
@@ -6397,143 +6407,135 @@ process has been transmitted to the serial port. */)
6397 indirectly; if it does, that is a bug */ 6407 indirectly; if it does, that is a bug */
6398 6408
6399#ifdef SIGCHLD 6409#ifdef SIGCHLD
6400static void 6410
6401sigchld_handler (int signo) 6411/* Record one child's changed status. Return true if a child was found. */
6412static bool
6413record_child_status_change (void)
6402{ 6414{
6403 int old_errno = errno;
6404 Lisp_Object proc; 6415 Lisp_Object proc;
6405 struct Lisp_Process *p; 6416 struct Lisp_Process *p;
6417 pid_t pid;
6418 int w;
6419 Lisp_Object tail;
6406 6420
6407 SIGNAL_THREAD_CHECK (signo); 6421 do
6408 6422 pid = waitpid (-1, &w, WNOHANG | WUNTRACED);
6409 while (1) 6423 while (pid < 0 && errno == EINTR);
6410 {
6411 pid_t pid;
6412 int w;
6413 Lisp_Object tail;
6414
6415#ifdef WNOHANG
6416#ifndef WUNTRACED
6417#define WUNTRACED 0
6418#endif /* no WUNTRACED */
6419 /* Keep trying to get a status until we get a definitive result. */
6420 do
6421 {
6422 errno = 0;
6423 pid = waitpid (-1, &w, WNOHANG | WUNTRACED);
6424 }
6425 while (pid < 0 && errno == EINTR);
6426
6427 if (pid <= 0)
6428 {
6429 /* PID == 0 means no processes found, PID == -1 means a real
6430 failure. We have done all our job, so return. */
6431 6424
6432 errno = old_errno; 6425 /* PID == 0 means no processes found, PID == -1 means a real failure.
6433 return; 6426 Either way, we have done all our job. */
6434 } 6427 if (pid <= 0)
6435#else 6428 return false;
6436 pid = wait (&w);
6437#endif /* no WNOHANG */
6438 6429
6439 /* Find the process that signaled us, and record its status. */ 6430 /* Find the process that signaled us, and record its status. */
6440 6431
6441 /* The process can have been deleted by Fdelete_process. */ 6432 /* The process can have been deleted by Fdelete_process. */
6442 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) 6433 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail))
6434 {
6435 Lisp_Object xpid = XCAR (tail);
6436 if ((INTEGERP (xpid) && pid == XINT (xpid))
6437 || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid)))
6443 { 6438 {
6444 Lisp_Object xpid = XCAR (tail); 6439 XSETCAR (tail, Qnil);
6445 if ((INTEGERP (xpid) && pid == XINT (xpid)) 6440 return true;
6446 || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid)))
6447 {
6448 XSETCAR (tail, Qnil);
6449 goto sigchld_end_of_loop;
6450 }
6451 } 6441 }
6442 }
6452 6443
6453 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ 6444 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */
6445 p = 0;
6446 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6447 {
6448 proc = XCDR (XCAR (tail));
6449 p = XPROCESS (proc);
6450 if (EQ (p->type, Qreal) && p->pid == pid)
6451 break;
6454 p = 0; 6452 p = 0;
6455 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) 6453 }
6456 {
6457 proc = XCDR (XCAR (tail));
6458 p = XPROCESS (proc);
6459 if (EQ (p->type, Qreal) && p->pid == pid)
6460 break;
6461 p = 0;
6462 }
6463
6464 /* Look for an asynchronous process whose pid hasn't been filled
6465 in yet. */
6466 if (p == 0)
6467 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6468 {
6469 proc = XCDR (XCAR (tail));
6470 p = XPROCESS (proc);
6471 if (p->pid == -1)
6472 break;
6473 p = 0;
6474 }
6475
6476 /* Change the status of the process that was found. */
6477 if (p != 0)
6478 {
6479 int clear_desc_flag = 0;
6480 6454
6481 p->tick = ++process_tick; 6455 /* Look for an asynchronous process whose pid hasn't been filled
6482 p->raw_status = w; 6456 in yet. */
6483 p->raw_status_new = 1; 6457 if (! p)
6458 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6459 {
6460 proc = XCDR (XCAR (tail));
6461 p = XPROCESS (proc);
6462 if (p->pid == -1)
6463 break;
6464 p = 0;
6465 }
6484 6466
6485 /* If process has terminated, stop waiting for its output. */ 6467 /* Change the status of the process that was found. */
6486 if ((WIFSIGNALED (w) || WIFEXITED (w)) 6468 if (p)
6487 && p->infd >= 0) 6469 {
6488 clear_desc_flag = 1; 6470 int clear_desc_flag = 0;
6489 6471
6490 /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ 6472 p->tick = ++process_tick;
6491 if (clear_desc_flag) 6473 p->raw_status = w;
6492 { 6474 p->raw_status_new = 1;
6493 FD_CLR (p->infd, &input_wait_mask);
6494 FD_CLR (p->infd, &non_keyboard_wait_mask);
6495 }
6496 6475
6497 /* Tell wait_reading_process_output that it needs to wake up and 6476 /* If process has terminated, stop waiting for its output. */
6498 look around. */ 6477 if ((WIFSIGNALED (w) || WIFEXITED (w))
6499 if (input_available_clear_time) 6478 && p->infd >= 0)
6500 *input_available_clear_time = make_emacs_time (0, 0); 6479 clear_desc_flag = 1;
6501 }
6502 6480
6503 /* There was no asynchronous process found for that pid: we have 6481 /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */
6504 a synchronous process. */ 6482 if (clear_desc_flag)
6505 else
6506 { 6483 {
6507 synch_process_alive = 0; 6484 FD_CLR (p->infd, &input_wait_mask);
6508 6485 FD_CLR (p->infd, &non_keyboard_wait_mask);
6509 /* Report the status of the synchronous process. */
6510 if (WIFEXITED (w))
6511 synch_process_retcode = WEXITSTATUS (w);
6512 else if (WIFSIGNALED (w))
6513 synch_process_termsig = WTERMSIG (w);
6514
6515 /* Tell wait_reading_process_output that it needs to wake up and
6516 look around. */
6517 if (input_available_clear_time)
6518 *input_available_clear_time = make_emacs_time (0, 0);
6519 } 6486 }
6520 6487
6521 sigchld_end_of_loop: 6488 /* Tell wait_reading_process_output that it needs to wake up and
6522 ; 6489 look around. */
6490 if (input_available_clear_time)
6491 *input_available_clear_time = make_emacs_time (0, 0);
6492 }
6493 /* There was no asynchronous process found for that pid: we have
6494 a synchronous process. */
6495 else
6496 {
6497 synch_process_alive = 0;
6498
6499 /* Report the status of the synchronous process. */
6500 if (WIFEXITED (w))
6501 synch_process_retcode = WEXITSTATUS (w);
6502 else if (WIFSIGNALED (w))
6503 synch_process_termsig = WTERMSIG (w);
6504
6505 /* Tell wait_reading_process_output that it needs to wake up and
6506 look around. */
6507 if (input_available_clear_time)
6508 *input_available_clear_time = make_emacs_time (0, 0);
6509 }
6510
6511 return true;
6512}
6523 6513
6524 /* On some systems, we must return right away. 6514/* On some systems, the SIGCHLD handler must return right away. If
6525 If any more processes want to signal us, we will 6515 any more processes want to signal us, we will get another signal.
6526 get another signal. 6516 Otherwise, loop around to use up all the processes that have
6527 Otherwise (on systems that have WNOHANG), loop around 6517 something to tell us. */
6528 to use up all the processes that have something to tell us. */
6529#if (defined WINDOWSNT \ 6518#if (defined WINDOWSNT \
6530 || (defined USG && !defined GNU_LINUX \ 6519 || (defined USG && !defined GNU_LINUX \
6531 && !(defined HPUX && defined WNOHANG))) 6520 && !(defined HPUX && defined WNOHANG)))
6532 errno = old_errno; 6521enum { CAN_HANDLE_MULTIPLE_CHILDREN = 1 };
6533 return; 6522#else
6534#endif /* USG, but not HPUX with WNOHANG */ 6523enum { CAN_HANDLE_MULTIPLE_CHILDREN = 0 };
6535 } 6524#endif
6525
6526static void
6527handle_child_signal (int sig)
6528{
6529 while (record_child_status_change () && CAN_HANDLE_MULTIPLE_CHILDREN)
6530 continue;
6536} 6531}
6532
6533static void
6534deliver_child_signal (int sig)
6535{
6536 handle_on_main_thread (sig, handle_child_signal);
6537}
6538
6537#endif /* SIGCHLD */ 6539#endif /* SIGCHLD */
6538 6540
6539 6541
@@ -7387,7 +7389,7 @@ init_process_emacs (void)
7387#ifndef CANNOT_DUMP 7389#ifndef CANNOT_DUMP
7388 if (! noninteractive || initialized) 7390 if (! noninteractive || initialized)
7389#endif 7391#endif
7390 signal (SIGCHLD, sigchld_handler); 7392 signal (SIGCHLD, deliver_child_signal);
7391#endif 7393#endif
7392 7394
7393 FD_ZERO (&input_wait_mask); 7395 FD_ZERO (&input_wait_mask);