diff options
Diffstat (limited to 'src/process.c')
-rw-r--r-- | src/process.c | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/src/process.c b/src/process.c index 2c66b9e976e..561aefc6c9f 100644 --- a/src/process.c +++ b/src/process.c @@ -1663,6 +1663,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) bool pty_flag = 0; char pty_name[PTY_NAME_SIZE]; Lisp_Object lisp_pty_name = Qnil; + sigset_t oldset; inchannel = outchannel = -1; @@ -1728,7 +1729,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) setup_process_coding_systems (process); block_input (); - block_child_signal (); + block_child_signal (&oldset); #ifndef WINDOWSNT /* vfork, and prevent local vars from being clobbered by the vfork. */ @@ -1852,7 +1853,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) signal (SIGPIPE, SIG_DFL); /* Stop blocking SIGCHLD in the child. */ - unblock_child_signal (); + unblock_child_signal (&oldset); if (pty_flag) child_setup_tty (xforkout); @@ -1871,7 +1872,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) p->alive = 1; /* Stop blocking in the parent. */ - unblock_child_signal (); + unblock_child_signal (&oldset); unblock_input (); if (pid < 0) @@ -2021,11 +2022,11 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, int len) terminator, however. */ if (name_length > 0 && sockun->sun_path[0] != '\0') { - const char* terminator = - memchr (sockun->sun_path, '\0', name_length); + const char *terminator + = memchr (sockun->sun_path, '\0', name_length); if (terminator) - name_length = terminator - (const char*) sockun->sun_path; + name_length = terminator - (const char *) sockun->sun_path; } return make_unibyte_string (sockun->sun_path, name_length); @@ -5832,30 +5833,25 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, } #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, @@ -7071,8 +7067,9 @@ void catch_child_signal (void) { struct sigaction action, old_action; + sigset_t oldset; emacs_sigaction_init (&action, deliver_child_signal); - block_child_signal (); + block_child_signal (&oldset); sigaction (SIGCHLD, &action, &old_action); eassert (! (old_action.sa_flags & SA_SIGINFO)); @@ -7081,7 +7078,7 @@ catch_child_signal (void) = (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN ? dummy_handler : old_action.sa_handler); - unblock_child_signal (); + unblock_child_signal (&oldset); } #endif /* subprocesses */ |