Commit a5cfdda8 authored by Kim F. Storm's avatar Kim F. Storm

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.
parent 24a71bb1
......@@ -778,6 +778,16 @@ get_process (name)
return proc;
}
#ifdef SIGCHLD
/* Fdelete_process promises to immediately forget about the process, but in
reality, Emacs needs to remember those processes until they have been
treated by sigchld_handler; otherwise this handler would consider the
process as being synchronous and say that the synchronous process is
dead. */
static Lisp_Object deleted_pid_list;
#endif
DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0,
doc: /* Delete PROCESS: kill it and forget about it immediately.
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. */)
}
else if (XINT (p->infd) >= 0)
{
Fkill_process (process, Qnil);
/* Do this now, since remove_process will make sigchld_handler do nothing. */
p->status
= Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
XSETINT (p->tick, ++process_tick);
status_notify (p);
#ifdef SIGCHLD
Lisp_Object symbol;
/* No problem storing the pid here, as it is still in Vprocess_alist. */
deleted_pid_list = Fcons (make_fixnum_or_float (p->pid),
/* GC treated elements set to nil. */
Fdelq (Qnil, deleted_pid_list));
/* If the process has already signaled, remove it from the list. */
if (p->raw_status_new)
update_status (p);
symbol = p->status;
if (CONSP (p->status))
symbol = XCAR (p->status);
if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
Fdelete (make_fixnum_or_float (p->pid), deleted_pid_list);
else
#endif
{
Fkill_process (process, Qnil);
/* Do this now, since remove_process will make sigchld_handler do nothing. */
p->status
= Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
XSETINT (p->tick, ++process_tick);
status_notify (p);
}
}
remove_process (process);
return Qnil;
......@@ -6335,6 +6364,7 @@ kill_buffer_processes (buffer)
** Malloc WARNING: This should never call malloc either directly or
indirectly; if it does, that is a bug */
#ifdef SIGCHLD
SIGTYPE
sigchld_handler (signo)
int signo;
......@@ -6392,6 +6422,15 @@ sigchld_handler (signo)
/* Find the process that signaled us, and record its status. */
/* The process can have been deleted by Fdelete_process. */
tail = Fmember (make_fixnum_or_float (pid), deleted_pid_list);
if (!NILP (tail))
{
Fsetcar (tail, Qnil);
goto sigchld_end_of_loop;
}
/* Otherwise, if it is asynchronous, it is in Vprocess_alist. */
p = 0;
for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail))
{
......@@ -6443,8 +6482,8 @@ sigchld_handler (signo)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
}
/* There was no asynchronous process found for that id. Check
if we have a synchronous process. */
/* There was no asynchronous process found for that pid: we have
a synchronous process. */
else
{
synch_process_alive = 0;
......@@ -6461,6 +6500,9 @@ sigchld_handler (signo)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
}
sigchld_end_of_loop:
;
/* On some systems, we must return right away.
If any more processes want to signal us, we will
get another signal.
......@@ -6477,6 +6519,7 @@ sigchld_handler (signo)
#endif /* USG, but not HPUX with WNOHANG */
}
}
#endif /* SIGCHLD */
static Lisp_Object
......@@ -6862,6 +6905,9 @@ init_process ()
FD_SET (0, &input_wait_mask);
Vprocess_alist = Qnil;
#ifdef SIGCHLD
deleted_pid_list = Qnil;
#endif
for (i = 0; i < MAXDESC; i++)
{
chan_process[i] = Qnil;
......@@ -7000,6 +7046,9 @@ syms_of_process ()
staticpro (&Qlast_nonmenu_event);
staticpro (&Vprocess_alist);
#ifdef SIGCHLD
staticpro (&deleted_pid_list);
#endif
DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
doc: /* *Non-nil means delete processes immediately when they exit.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment