diff options
| author | Paul Eggert | 2014-03-25 07:43:26 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-03-25 07:43:26 -0700 |
| commit | 1e952f0a7a1d0cc533438dcad37db08d8af6855f (patch) | |
| tree | 423d42b20476efd08fa7c0e4b62756c1b09c8cdd /src/callproc.c | |
| parent | 1edb4a2ec657c305880901e78317daf1990b5358 (diff) | |
| download | emacs-1e952f0a7a1d0cc533438dcad37db08d8af6855f.tar.gz emacs-1e952f0a7a1d0cc533438dcad37db08d8af6855f.zip | |
Handle sigmask better with nested signal handlers.
* atimer.c (sigmask_atimers): Remove.
Remaining use rewritten to use body of this function.
* atimer.c (block_atimers, unblock_atimers):
* callproc.c (block_child_signal, unblock_child_signal):
* sysdep.c (block_tty_out_signal, unblock_tty_out_signal):
New arg OLDSET. All callers changed.
* atimer.c (block_atimers, unblock_atimers):
* callproc.c (block_child_signal, unblock_child_signal):
* keyboard.c (handle_interrupt):
* sound.c (vox_configure, vox_close):
Restore the old signal mask rather than unilaterally clearing bits
from the mask, in case a handler is running within another
handler. All callers changed.
* lisp.h, process.c, process.h, term.c:
Adjust decls and callers to match new API.
* sysdep.c (emacs_sigaction_init): Don't worry about masking SIGFPE;
signal handlers aren't supposed to use floating point anyway.
(handle_arith_signal): Unblock just SIGFPE rather than clearing mask.
Fixes: debbugs:15561
Diffstat (limited to 'src/callproc.c')
| -rw-r--r-- | src/callproc.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/src/callproc.c b/src/callproc.c index 0831291b0dd..2147c173655 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -108,20 +108,20 @@ static Lisp_Object call_process (ptrdiff_t, Lisp_Object *, int, ptrdiff_t); | |||
| 108 | /* Block SIGCHLD. */ | 108 | /* Block SIGCHLD. */ |
| 109 | 109 | ||
| 110 | void | 110 | void |
| 111 | block_child_signal (void) | 111 | block_child_signal (sigset_t *oldset) |
| 112 | { | 112 | { |
| 113 | sigset_t blocked; | 113 | sigset_t blocked; |
| 114 | sigemptyset (&blocked); | 114 | sigemptyset (&blocked); |
| 115 | sigaddset (&blocked, SIGCHLD); | 115 | sigaddset (&blocked, SIGCHLD); |
| 116 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | 116 | pthread_sigmask (SIG_BLOCK, &blocked, oldset); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | /* Unblock SIGCHLD. */ | 119 | /* Unblock SIGCHLD. */ |
| 120 | 120 | ||
| 121 | void | 121 | void |
| 122 | unblock_child_signal (void) | 122 | unblock_child_signal (sigset_t const *oldset) |
| 123 | { | 123 | { |
| 124 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 124 | pthread_sigmask (SIG_SETMASK, oldset, 0); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | /* Return the current buffer's working directory, or the home | 127 | /* Return the current buffer's working directory, or the home |
| @@ -162,7 +162,8 @@ encode_current_directory (void) | |||
| 162 | void | 162 | void |
| 163 | record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) | 163 | record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) |
| 164 | { | 164 | { |
| 165 | block_child_signal (); | 165 | sigset_t oldset; |
| 166 | block_child_signal (&oldset); | ||
| 166 | 167 | ||
| 167 | if (p->alive) | 168 | if (p->alive) |
| 168 | { | 169 | { |
| @@ -171,7 +172,7 @@ record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) | |||
| 171 | kill (- p->pid, SIGKILL); | 172 | kill (- p->pid, SIGKILL); |
| 172 | } | 173 | } |
| 173 | 174 | ||
| 174 | unblock_child_signal (); | 175 | unblock_child_signal (&oldset); |
| 175 | } | 176 | } |
| 176 | 177 | ||
| 177 | /* Clean up files, file descriptors and processes created by Fcall_process. */ | 178 | /* Clean up files, file descriptors and processes created by Fcall_process. */ |
| @@ -313,6 +314,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 313 | char *tempfile = NULL; | 314 | char *tempfile = NULL; |
| 314 | int pid; | 315 | int pid; |
| 315 | #else | 316 | #else |
| 317 | sigset_t oldset; | ||
| 316 | pid_t pid; | 318 | pid_t pid; |
| 317 | #endif | 319 | #endif |
| 318 | int child_errno; | 320 | int child_errno; |
| @@ -629,7 +631,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 629 | #ifndef MSDOS | 631 | #ifndef MSDOS |
| 630 | 632 | ||
| 631 | block_input (); | 633 | block_input (); |
| 632 | block_child_signal (); | 634 | block_child_signal (&oldset); |
| 633 | 635 | ||
| 634 | #ifdef WINDOWSNT | 636 | #ifdef WINDOWSNT |
| 635 | pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); | 637 | pid = child_setup (filefd, fd_output, fd_error, new_argv, 0, current_dir); |
| @@ -671,7 +673,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 671 | 673 | ||
| 672 | if (pid == 0) | 674 | if (pid == 0) |
| 673 | { | 675 | { |
| 674 | unblock_child_signal (); | 676 | unblock_child_signal (&oldset); |
| 675 | 677 | ||
| 676 | setsid (); | 678 | setsid (); |
| 677 | 679 | ||
| @@ -707,7 +709,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, | |||
| 707 | } | 709 | } |
| 708 | } | 710 | } |
| 709 | 711 | ||
| 710 | unblock_child_signal (); | 712 | unblock_child_signal (&oldset); |
| 711 | unblock_input (); | 713 | unblock_input (); |
| 712 | 714 | ||
| 713 | #endif /* not MSDOS */ | 715 | #endif /* not MSDOS */ |