aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c65
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. */
788static Lisp_Object deleted_pid_list;
789#endif
790
781DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, 791DEFUN ("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.
783PROCESS may be a process, a buffer, the name of a process or buffer, or 793PROCESS 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
6338SIGTYPE 6368SIGTYPE
6339sigchld_handler (signo) 6369sigchld_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
6482static Lisp_Object 6525static 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.