summaryrefslogtreecommitdiff
path: root/src/process.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>2006-06-07 18:05:10 +0000
committerMiles Bader <miles@gnu.org>2006-06-07 18:05:10 +0000
commitb883cdb2fefa8ea9c3b0d82eba7a9ee792f871bb (patch)
treede3804210a8cd955e0d3b9abc15679480930bc82 /src/process.c
parent885b7d0991bd4b4b8f4bd1d3cd21c18a697bbce2 (diff)
parent26c9afc3239e18b03537faaea33e3e82e28099e6 (diff)
Merge from emacs--devo--0
Patches applied: * emacs--devo--0 (patch 285-296) - Update from CVS - Merge from gnus--rel--5.10 - Update from CVS: admin/FOR-RELEASE: Update refcard section. * gnus--rel--5.10 (patch 102-104) - Update from CVS Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-64
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c84
1 files changed, 76 insertions, 8 deletions
diff --git a/src/process.c b/src/process.c
index 1960e6a914c..2281f1ce3f6 100644
--- a/src/process.c
+++ b/src/process.c
@@ -777,6 +777,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
@@ -798,12 +808,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;
@@ -4134,6 +4163,25 @@ wait_reading_process_output_1 ()
{
}
+/* Use a wrapper around select to work around a bug in gdb 5.3.
+ Normally, the wrapper is optimzed away by inlining.
+
+ If emacs is stopped inside select, the gdb backtrace doesn't
+ show the function which called select, so it is practically
+ impossible to step through wait_reading_process_output. */
+
+#ifndef select
+static INLINE int
+select_wrapper (n, rfd, wfd, xfd, tmo)
+ int n;
+ SELECT_TYPE *rfd, *wfd, *xfd;
+ EMACS_TIME *tmo;
+{
+ return select (n, rfd, wfd, xfd, tmo);
+}
+#define select select_wrapper
+#endif
+
/* Read and dispose of subprocess output while waiting for timeout to
elapse and/or keyboard input to be available.
@@ -6304,6 +6352,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;
@@ -6361,6 +6410,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))
{
@@ -6412,8 +6470,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;
@@ -6430,6 +6488,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.
@@ -6446,6 +6507,7 @@ sigchld_handler (signo)
#endif /* USG, but not HPUX with WNOHANG */
}
}
+#endif /* SIGCHLD */
static Lisp_Object
@@ -6831,6 +6893,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;
@@ -6969,6 +7034,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.