+2014-05-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don't kill already-reaped process (Bug#17561).
+ * process.c (process_send_signal): Fix race condition where a
+ subprocess was reaped by a signal handler between the check for
+ liveness and calling 'kill', which meant that Emacs could in
+ theory kill an innocent bystander process. Do the fix by blocking
+ SIGCHLD in a critical section that checks liveness before killing.
+
2014-05-26 Eli Zaretskii <eliz@gnu.org>
* w32.c (_ANONYMOUS_UNION, _ANONYMOUS_STRUCT): Define only if
}
#endif
+#ifdef TIOCSIGSEND
+ /* Work around a HP-UX 7.0 bug that mishandles signals to subjobs.
+ We don't know whether the bug is fixed in later HP-UX versions. */
+ if (! NILP (current_group) && ioctl (p->infd, TIOCSIGSEND, signo) != -1)
+ return;
+#endif
+
/* If we don't have process groups, send the signal to the immediate
subprocess. That isn't really right, but it's better than any
obvious alternative. */
- if (no_pgrp)
- {
- kill (p->pid, signo);
- return;
- }
+ pid_t pid = no_pgrp ? gid : - gid;
- /* gid may be a pid, or minus a pgrp's number */
-#ifdef TIOCSIGSEND
- if (!NILP (current_group))
- {
- if (ioctl (p->infd, TIOCSIGSEND, signo) == -1)
- kill (-gid, signo);
- }
- else
- {
- gid = - p->pid;
- kill (gid, signo);
- }
-#else /* ! defined (TIOCSIGSEND) */
- kill (-gid, signo);
-#endif /* ! defined (TIOCSIGSEND) */
+ /* Do not kill an already-reaped process, as that could kill an
+ innocent bystander that happens to have the same process ID. */
+ sigset_t oldset;
+ block_child_signal (&oldset);
+ if (p->alive)
+ kill (pid, signo);
+ unblock_child_signal (&oldset);
}
DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0,