diff options
| author | Kim F. Storm | 2006-06-01 14:08:25 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2006-06-01 14:08:25 +0000 |
| commit | a5cfdda8adae935411ed4bf9a11999ccdb8b956a (patch) | |
| tree | 96e3b352e557665b05013f6c8df1a69ae8954b4e /src/process.c | |
| parent | 24a71bb14092f0f789d7412c278c45079f791477 (diff) | |
| download | emacs-a5cfdda8adae935411ed4bf9a11999ccdb8b956a.tar.gz emacs-a5cfdda8adae935411ed4bf9a11999ccdb8b956a.zip | |
2006-06-01 Michaƫl Cadilhac <michael.cadilhac@lrde.org>
(deleted_pid_list): New variable to store the pids
of deleted processes. Declare it only if SIGCHLD is defined.
(init_process): Initialize it.
(syms_of_process): Staticpro it.
(Fdelete_process): Add pid of the deleted process to it. Check after
the addition and before the kill if the process is already stopped,
in which case it is deleted from the list and not killed.
(sigchld_handler): Define it only if SIGCHLD is. Search the process
that signaled Emacs in `deleted_pid_list' before `Vprocess_alist'.
Original idea by Stefan Monnier.
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. |