aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorPaul Eggert2012-12-05 23:31:58 -0800
committerPaul Eggert2012-12-05 23:31:58 -0800
commit35fb8050457a0edc6a09f38fb1dd84a9c7732352 (patch)
tree563dbd821a3efc83e6ad71c7f6a0dc21f26c8c5b /src/process.c
parent565212e5983cdcc478ed34bcdbd63f154e5e418f (diff)
downloademacs-35fb8050457a0edc6a09f38fb1dd84a9c7732352.tar.gz
emacs-35fb8050457a0edc6a09f38fb1dd84a9c7732352.zip
Fix a recently-introduced delete-process race condition.
* callproc.c, process.h (record_kill_process): New function, containing part of the old call_process_kill. (call_process_kill): Use it. This does not change call_process_kill's behavior. * process.c (Fdelete_process): Use record_kill_process to fix a race condition that could cause Emacs to lose track of a child.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/src/process.c b/src/process.c
index 27009882c99..007a07942e6 100644
--- a/src/process.c
+++ b/src/process.c
@@ -813,30 +813,22 @@ nil, indicating the current buffer's process. */)
813 status_notify (p); 813 status_notify (p);
814 redisplay_preserve_echo_area (13); 814 redisplay_preserve_echo_area (13);
815 } 815 }
816 else if (p->infd >= 0) 816 else
817 { 817 {
818#ifdef SIGCHLD 818 if (p->alive)
819 Lisp_Object symbol; 819 record_kill_process (p);
820 pid_t pid = p->pid; 820
821 821 if (p->infd >= 0)
822 /* No problem storing the pid here, as it is still in Vprocess_alist. */
823 record_deleted_pid (pid);
824 /* If the process has already signaled, remove it from the list. */
825 if (p->raw_status_new)
826 update_status (p);
827 symbol = p->status;
828 if (CONSP (p->status))
829 symbol = XCAR (p->status);
830 if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
831 deleted_pid_list
832 = Fdelete (make_fixnum_or_float (pid), deleted_pid_list);
833 else
834#endif
835 { 822 {
836 Fkill_process (process, Qnil); 823 /* Update P's status, since record_kill_process will make the
837 /* Do this now, since remove_process will make the 824 SIGCHLD handler update deleted_pid_list, not *P. */
838 SIGCHLD handler do nothing. */ 825 Lisp_Object symbol;
839 pset_status (p, Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil))); 826 if (p->raw_status_new)
827 update_status (p);
828 symbol = CONSP (p->status) ? XCAR (p->status) : p->status;
829 if (! (EQ (symbol, Qsignal) || EQ (symbol, Qexit)))
830 pset_status (p, list2 (Qsignal, make_number (SIGKILL)));
831
840 p->tick = ++process_tick; 832 p->tick = ++process_tick;
841 status_notify (p); 833 status_notify (p);
842 redisplay_preserve_echo_area (13); 834 redisplay_preserve_echo_area (13);