aboutsummaryrefslogtreecommitdiffstats
path: root/src/callproc.c
diff options
context:
space:
mode:
authorPaul Eggert2014-03-25 07:43:26 -0700
committerPaul Eggert2014-03-25 07:43:26 -0700
commit1e952f0a7a1d0cc533438dcad37db08d8af6855f (patch)
tree423d42b20476efd08fa7c0e4b62756c1b09c8cdd /src/callproc.c
parent1edb4a2ec657c305880901e78317daf1990b5358 (diff)
downloademacs-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.c20
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
110void 110void
111block_child_signal (void) 111block_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
121void 121void
122unblock_child_signal (void) 122unblock_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)
162void 162void
163record_kill_process (struct Lisp_Process *p, Lisp_Object tempfile) 163record_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 */