diff options
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/src/process.c b/src/process.c index 3366a3f1006..f2c2ddf3e14 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -778,6 +778,16 @@ get_process (name) | |||
| 778 | return proc; | 778 | return proc; |
| 779 | } | 779 | } |
| 780 | 780 | ||
| 781 | |||
| 782 | #ifdef SIGCHLD | ||
| 783 | /* Fdelete_process promises to immediately forget about the process, but in | ||
| 784 | reality, Emacs needs to remember those processes until they have been | ||
| 785 | treated by sigchld_handler; otherwise this handler would consider the | ||
| 786 | process as being synchronous and say that the synchronous process is | ||
| 787 | dead. */ | ||
| 788 | static Lisp_Object deleted_pid_list; | ||
| 789 | #endif | ||
| 790 | |||
| 781 | DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, | 791 | DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, |
| 782 | doc: /* Delete PROCESS: kill it and forget about it immediately. | 792 | doc: /* Delete PROCESS: kill it and forget about it immediately. |
| 783 | PROCESS may be a process, a buffer, the name of a process or buffer, or | 793 | PROCESS may be a process, a buffer, the name of a process or buffer, or |
| @@ -799,12 +809,31 @@ nil, indicating the current buffer's process. */) | |||
| 799 | } | 809 | } |
| 800 | else if (XINT (p->infd) >= 0) | 810 | else if (XINT (p->infd) >= 0) |
| 801 | { | 811 | { |
| 802 | Fkill_process (process, Qnil); | 812 | #ifdef SIGCHLD |
| 803 | /* Do this now, since remove_process will make sigchld_handler do nothing. */ | 813 | Lisp_Object symbol; |
| 804 | p->status | 814 | |
| 805 | = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil)); | 815 | /* No problem storing the pid here, as it is still in Vprocess_alist. */ |
| 806 | XSETINT (p->tick, ++process_tick); | 816 | deleted_pid_list = Fcons (make_fixnum_or_float (p->pid), |
| 807 | status_notify (p); | 817 | /* GC treated elements set to nil. */ |
| 818 | Fdelq (Qnil, deleted_pid_list)); | ||
| 819 | /* If the process has already signaled, remove it from the list. */ | ||
| 820 | if (p->raw_status_new) | ||
| 821 | update_status (p); | ||
| 822 | symbol = p->status; | ||
| 823 | if (CONSP (p->status)) | ||
| 824 | symbol = XCAR (p->status); | ||
| 825 | if (EQ (symbol, Qsignal) || EQ (symbol, Qexit)) | ||
| 826 | Fdelete (make_fixnum_or_float (p->pid), deleted_pid_list); | ||
| 827 | else | ||
| 828 | #endif | ||
| 829 | { | ||
| 830 | Fkill_process (process, Qnil); | ||
| 831 | /* Do this now, since remove_process will make sigchld_handler do nothing. */ | ||
| 832 | p->status | ||
| 833 | = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil)); | ||
| 834 | XSETINT (p->tick, ++process_tick); | ||
| 835 | status_notify (p); | ||
| 836 | } | ||
| 808 | } | 837 | } |
| 809 | remove_process (process); | 838 | remove_process (process); |
| 810 | return Qnil; | 839 | return Qnil; |
| @@ -6335,6 +6364,7 @@ kill_buffer_processes (buffer) | |||
| 6335 | ** Malloc WARNING: This should never call malloc either directly or | 6364 | ** Malloc WARNING: This should never call malloc either directly or |
| 6336 | indirectly; if it does, that is a bug */ | 6365 | indirectly; if it does, that is a bug */ |
| 6337 | 6366 | ||
| 6367 | #ifdef SIGCHLD | ||
| 6338 | SIGTYPE | 6368 | SIGTYPE |
| 6339 | sigchld_handler (signo) | 6369 | sigchld_handler (signo) |
| 6340 | int signo; | 6370 | int signo; |
| @@ -6392,6 +6422,15 @@ sigchld_handler (signo) | |||
| 6392 | 6422 | ||
| 6393 | /* Find the process that signaled us, and record its status. */ | 6423 | /* Find the process that signaled us, and record its status. */ |
| 6394 | 6424 | ||
| 6425 | /* The process can have been deleted by Fdelete_process. */ | ||
| 6426 | tail = Fmember (make_fixnum_or_float (pid), deleted_pid_list); | ||
| 6427 | if (!NILP (tail)) | ||
| 6428 | { | ||
| 6429 | Fsetcar (tail, Qnil); | ||
| 6430 | goto sigchld_end_of_loop; | ||
| 6431 | } | ||
| 6432 | |||
| 6433 | /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ | ||
| 6395 | p = 0; | 6434 | p = 0; |
| 6396 | for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail)) | 6435 | for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail)) |
| 6397 | { | 6436 | { |
| @@ -6443,8 +6482,8 @@ sigchld_handler (signo) | |||
| 6443 | EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); | 6482 | EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); |
| 6444 | } | 6483 | } |
| 6445 | 6484 | ||
| 6446 | /* There was no asynchronous process found for that id. Check | 6485 | /* There was no asynchronous process found for that pid: we have |
| 6447 | if we have a synchronous process. */ | 6486 | a synchronous process. */ |
| 6448 | else | 6487 | else |
| 6449 | { | 6488 | { |
| 6450 | synch_process_alive = 0; | 6489 | synch_process_alive = 0; |
| @@ -6461,6 +6500,9 @@ sigchld_handler (signo) | |||
| 6461 | EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); | 6500 | EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); |
| 6462 | } | 6501 | } |
| 6463 | 6502 | ||
| 6503 | sigchld_end_of_loop: | ||
| 6504 | ; | ||
| 6505 | |||
| 6464 | /* On some systems, we must return right away. | 6506 | /* On some systems, we must return right away. |
| 6465 | If any more processes want to signal us, we will | 6507 | If any more processes want to signal us, we will |
| 6466 | get another signal. | 6508 | get another signal. |
| @@ -6477,6 +6519,7 @@ sigchld_handler (signo) | |||
| 6477 | #endif /* USG, but not HPUX with WNOHANG */ | 6519 | #endif /* USG, but not HPUX with WNOHANG */ |
| 6478 | } | 6520 | } |
| 6479 | } | 6521 | } |
| 6522 | #endif /* SIGCHLD */ | ||
| 6480 | 6523 | ||
| 6481 | 6524 | ||
| 6482 | static Lisp_Object | 6525 | static Lisp_Object |
| @@ -6862,6 +6905,9 @@ init_process () | |||
| 6862 | FD_SET (0, &input_wait_mask); | 6905 | FD_SET (0, &input_wait_mask); |
| 6863 | 6906 | ||
| 6864 | Vprocess_alist = Qnil; | 6907 | Vprocess_alist = Qnil; |
| 6908 | #ifdef SIGCHLD | ||
| 6909 | deleted_pid_list = Qnil; | ||
| 6910 | #endif | ||
| 6865 | for (i = 0; i < MAXDESC; i++) | 6911 | for (i = 0; i < MAXDESC; i++) |
| 6866 | { | 6912 | { |
| 6867 | chan_process[i] = Qnil; | 6913 | chan_process[i] = Qnil; |
| @@ -7000,6 +7046,9 @@ syms_of_process () | |||
| 7000 | staticpro (&Qlast_nonmenu_event); | 7046 | staticpro (&Qlast_nonmenu_event); |
| 7001 | 7047 | ||
| 7002 | staticpro (&Vprocess_alist); | 7048 | staticpro (&Vprocess_alist); |
| 7049 | #ifdef SIGCHLD | ||
| 7050 | staticpro (&deleted_pid_list); | ||
| 7051 | #endif | ||
| 7003 | 7052 | ||
| 7004 | DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes, | 7053 | DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes, |
| 7005 | doc: /* *Non-nil means delete processes immediately when they exit. | 7054 | doc: /* *Non-nil means delete processes immediately when they exit. |