aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoakim Verona2012-12-06 08:40:20 +0100
committerJoakim Verona2012-12-06 08:40:20 +0100
commit6b946658438570898db449b70906d63c00da21ce (patch)
treea811b15dc1f4ecbc517e4f1c049d980b4fb36f0d /src
parentec51343a4e6490c45db57418747c247354b9b6e9 (diff)
parent7fc5e83f7fa6e060596204b1c1cd9a7890de7a66 (diff)
downloademacs-6b946658438570898db449b70906d63c00da21ce.tar.gz
emacs-6b946658438570898db449b70906d63c00da21ce.zip
auto upstream
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog10
-rw-r--r--src/callproc.c30
-rw-r--r--src/process.c36
-rw-r--r--src/process.h6
4 files changed, 53 insertions, 29 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index d9e566eae69..542b2c0174a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
12012-12-06 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix a recently-introduced delete-process race condition.
4 * callproc.c, process.h (record_kill_process):
5 New function, containing part of the old call_process_kill.
6 (call_process_kill): Use it.
7 This does not change call_process_kill's behavior.
8 * process.c (Fdelete_process): Use record_kill_process to fix a
9 race condition that could cause Emacs to lose track of a child.
10
12012-12-06 Dmitry Antipov <dmantipov@yandex.ru> 112012-12-06 Dmitry Antipov <dmantipov@yandex.ru>
2 12
3 Avoid code duplication between prev_frame and next_frame. 13 Avoid code duplication between prev_frame and next_frame.
diff --git a/src/callproc.c b/src/callproc.c
index 6153bc1b6c6..e0528a791ea 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -105,6 +105,25 @@ unblock_child_signal (void)
105#endif 105#endif
106} 106}
107 107
108/* If P is reapable, record it as a deleted process and kill it.
109 Do this in a critical section. Unless PID is wedged it will be
110 reaped on receipt of the first SIGCHLD after the critical section. */
111
112void
113record_kill_process (struct Lisp_Process *p)
114{
115 block_child_signal ();
116
117 if (p->alive)
118 {
119 p->alive = 0;
120 record_deleted_pid (p->pid);
121 EMACS_KILLPG (p->pid, SIGKILL);
122 }
123
124 unblock_child_signal ();
125}
126
108/* Clean up when exiting call_process_cleanup. */ 127/* Clean up when exiting call_process_cleanup. */
109 128
110static Lisp_Object 129static Lisp_Object
@@ -113,15 +132,12 @@ call_process_kill (Lisp_Object ignored)
113 if (0 <= synch_process_fd) 132 if (0 <= synch_process_fd)
114 emacs_close (synch_process_fd); 133 emacs_close (synch_process_fd);
115 134
116 /* If PID is reapable, kill it and record it as a deleted process.
117 Do this in a critical section. Unless PID is wedged it will be
118 reaped on receipt of the first SIGCHLD after the critical section. */
119 if (synch_process_pid) 135 if (synch_process_pid)
120 { 136 {
121 block_child_signal (); 137 struct Lisp_Process proc;
122 record_deleted_pid (synch_process_pid); 138 proc.alive = 1;
123 EMACS_KILLPG (synch_process_pid, SIGKILL); 139 proc.pid = synch_process_pid;
124 unblock_child_signal (); 140 record_kill_process (&proc);
125 } 141 }
126 142
127 return Qnil; 143 return Qnil;
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);
diff --git a/src/process.h b/src/process.h
index 4fa22747ca9..a0521689abf 100644
--- a/src/process.h
+++ b/src/process.h
@@ -198,6 +198,12 @@ extern Lisp_Object QCspeed;
198extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven; 198extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
199extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary; 199extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
200 200
201/* Defined in callproc.c. */
202
203extern void record_kill_process (struct Lisp_Process *);
204
205/* Defined in process.c. */
206
201extern Lisp_Object list_system_processes (void); 207extern Lisp_Object list_system_processes (void);
202extern Lisp_Object system_process_attributes (Lisp_Object); 208extern Lisp_Object system_process_attributes (Lisp_Object);
203 209