diff options
| author | Paul Eggert | 2014-05-29 21:12:08 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-05-29 21:12:08 -0700 |
| commit | 8cf1e6e67926683e38809adced986d255124afd5 (patch) | |
| tree | 778900c1d56daa5ffebf44e14c51d0f6a9410a40 /src | |
| parent | acc16b66ffe8e3b0f3568c5ae2e3bf0dff2bc2fa (diff) | |
| download | emacs-8cf1e6e67926683e38809adced986d255124afd5.tar.gz emacs-8cf1e6e67926683e38809adced986d255124afd5.zip | |
Don't let SIGINT handling block SIGCHLD indefinitely.
* atimer.c (block_atimers):
* callproc.c (block_child_signal): Block SIGINT too;
otherwise, its handler might now unblock signals that it shouldn't.
* keyboard.c (read_char): Clear signal mask, since we may
be in a SIGINT handler, and many signals may be masked.
* keyboard.c (handle_interrupt):
* sysdep.c (handle_arith_signal):
Clear signal mask instead of just unblocking the signal that
was received, since several signals may be blocked at this point.
Fixes: debbugs:17561
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/atimer.c | 6 | ||||
| -rw-r--r-- | src/callproc.c | 1 | ||||
| -rw-r--r-- | src/keyboard.c | 11 | ||||
| -rw-r--r-- | src/sysdep.c | 5 |
5 files changed, 25 insertions, 11 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 33952e159bf..6ecf7dbee99 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2014-05-30 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Don't let SIGINT handling block SIGCHLD indefinitely (Bug#17561). | ||
| 4 | * atimer.c (block_atimers): | ||
| 5 | * callproc.c (block_child_signal): Block SIGINT too; | ||
| 6 | otherwise, its handler might now unblock signals that it shouldn't. | ||
| 7 | * keyboard.c (read_char): Clear signal mask, since we may | ||
| 8 | be in a SIGINT handler, and many signals may be masked. | ||
| 9 | * keyboard.c (handle_interrupt): | ||
| 10 | * sysdep.c (handle_arith_signal): | ||
| 11 | Clear signal mask instead of just unblocking the signal that | ||
| 12 | was received, since several signals may be blocked at this point. | ||
| 13 | |||
| 1 | 2014-05-29 Eli Zaretskii <eliz@gnu.org> | 14 | 2014-05-29 Eli Zaretskii <eliz@gnu.org> |
| 2 | 15 | ||
| 3 | * Makefile.in (TEMACS_POST_LINK): Remove target. | 16 | * Makefile.in (TEMACS_POST_LINK): Remove target. |
diff --git a/src/atimer.c b/src/atimer.c index a5a2b0714e3..e457a7fcf1c 100644 --- a/src/atimer.c +++ b/src/atimer.c | |||
| @@ -55,6 +55,7 @@ block_atimers (sigset_t *oldset) | |||
| 55 | sigset_t blocked; | 55 | sigset_t blocked; |
| 56 | sigemptyset (&blocked); | 56 | sigemptyset (&blocked); |
| 57 | sigaddset (&blocked, SIGALRM); | 57 | sigaddset (&blocked, SIGALRM); |
| 58 | sigaddset (&blocked, SIGINT); | ||
| 58 | pthread_sigmask (SIG_BLOCK, &blocked, oldset); | 59 | pthread_sigmask (SIG_BLOCK, &blocked, oldset); |
| 59 | } | 60 | } |
| 60 | static void | 61 | static void |
| @@ -404,7 +405,6 @@ turn_on_atimers (bool on) | |||
| 404 | void | 405 | void |
| 405 | init_atimer (void) | 406 | init_atimer (void) |
| 406 | { | 407 | { |
| 407 | struct sigaction action; | ||
| 408 | #ifdef HAVE_ITIMERSPEC | 408 | #ifdef HAVE_ITIMERSPEC |
| 409 | struct sigevent sigev; | 409 | struct sigevent sigev; |
| 410 | sigev.sigev_notify = SIGEV_SIGNAL; | 410 | sigev.sigev_notify = SIGEV_SIGNAL; |
| @@ -413,7 +413,9 @@ init_atimer (void) | |||
| 413 | alarm_timer_ok = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0; | 413 | alarm_timer_ok = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0; |
| 414 | #endif | 414 | #endif |
| 415 | free_atimers = stopped_atimers = atimers = NULL; | 415 | free_atimers = stopped_atimers = atimers = NULL; |
| 416 | /* pending_signals is initialized in init_keyboard.*/ | 416 | |
| 417 | /* pending_signals is initialized in init_keyboard. */ | ||
| 418 | struct sigaction action; | ||
| 417 | emacs_sigaction_init (&action, handle_alarm_signal); | 419 | emacs_sigaction_init (&action, handle_alarm_signal); |
| 418 | sigaction (SIGALRM, &action, 0); | 420 | sigaction (SIGALRM, &action, 0); |
| 419 | } | 421 | } |
diff --git a/src/callproc.c b/src/callproc.c index a2c52e5b5ba..0506bf53a25 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -115,6 +115,7 @@ block_child_signal (sigset_t *oldset) | |||
| 115 | sigset_t blocked; | 115 | sigset_t blocked; |
| 116 | sigemptyset (&blocked); | 116 | sigemptyset (&blocked); |
| 117 | sigaddset (&blocked, SIGCHLD); | 117 | sigaddset (&blocked, SIGCHLD); |
| 118 | sigaddset (&blocked, SIGINT); | ||
| 118 | pthread_sigmask (SIG_BLOCK, &blocked, oldset); | 119 | pthread_sigmask (SIG_BLOCK, &blocked, oldset); |
| 119 | } | 120 | } |
| 120 | 121 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index e92c86b7dbf..17bfc81b82f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -2664,6 +2664,7 @@ read_char (int commandflag, Lisp_Object map, | |||
| 2664 | /* We must have saved the outer value of getcjmp here, | 2664 | /* We must have saved the outer value of getcjmp here, |
| 2665 | so restore it now. */ | 2665 | so restore it now. */ |
| 2666 | restore_getcjmp (save_jump); | 2666 | restore_getcjmp (save_jump); |
| 2667 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | ||
| 2667 | unbind_to (jmpcount, Qnil); | 2668 | unbind_to (jmpcount, Qnil); |
| 2668 | XSETINT (c, quit_char); | 2669 | XSETINT (c, quit_char); |
| 2669 | internal_last_event_frame = selected_frame; | 2670 | internal_last_event_frame = selected_frame; |
| @@ -10323,9 +10324,6 @@ static void | |||
| 10323 | handle_interrupt (bool in_signal_handler) | 10324 | handle_interrupt (bool in_signal_handler) |
| 10324 | { | 10325 | { |
| 10325 | char c; | 10326 | char c; |
| 10326 | sigset_t blocked; | ||
| 10327 | sigemptyset (&blocked); | ||
| 10328 | sigaddset (&blocked, SIGINT); | ||
| 10329 | 10327 | ||
| 10330 | cancel_echoing (); | 10328 | cancel_echoing (); |
| 10331 | 10329 | ||
| @@ -10337,6 +10335,9 @@ handle_interrupt (bool in_signal_handler) | |||
| 10337 | /* If SIGINT isn't blocked, don't let us be interrupted by | 10335 | /* If SIGINT isn't blocked, don't let us be interrupted by |
| 10338 | a SIGINT. It might be harmful due to non-reentrancy | 10336 | a SIGINT. It might be harmful due to non-reentrancy |
| 10339 | in I/O functions. */ | 10337 | in I/O functions. */ |
| 10338 | sigset_t blocked; | ||
| 10339 | sigemptyset (&blocked); | ||
| 10340 | sigaddset (&blocked, SIGINT); | ||
| 10340 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | 10341 | pthread_sigmask (SIG_BLOCK, &blocked, 0); |
| 10341 | } | 10342 | } |
| 10342 | 10343 | ||
| @@ -10421,7 +10422,7 @@ handle_interrupt (bool in_signal_handler) | |||
| 10421 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 10422 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 10422 | 10423 | ||
| 10423 | immediate_quit = 0; | 10424 | immediate_quit = 0; |
| 10424 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); | 10425 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 10425 | saved = gl_state; | 10426 | saved = gl_state; |
| 10426 | GCPRO4 (saved.object, saved.global_code, | 10427 | GCPRO4 (saved.object, saved.global_code, |
| 10427 | saved.current_syntax_table, saved.old_prop); | 10428 | saved.current_syntax_table, saved.old_prop); |
| @@ -10442,7 +10443,7 @@ handle_interrupt (bool in_signal_handler) | |||
| 10442 | } | 10443 | } |
| 10443 | } | 10444 | } |
| 10444 | 10445 | ||
| 10445 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); | 10446 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 10446 | 10447 | ||
| 10447 | /* TODO: The longjmp in this call throws the NS event loop integration off, | 10448 | /* TODO: The longjmp in this call throws the NS event loop integration off, |
| 10448 | and it seems to do fine without this. Probably some attention | 10449 | and it seems to do fine without this. Probably some attention |
diff --git a/src/sysdep.c b/src/sysdep.c index e5b29205e96..573d419970d 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -1645,10 +1645,7 @@ deliver_fatal_thread_signal (int sig) | |||
| 1645 | static _Noreturn void | 1645 | static _Noreturn void |
| 1646 | handle_arith_signal (int sig) | 1646 | handle_arith_signal (int sig) |
| 1647 | { | 1647 | { |
| 1648 | sigset_t blocked; | 1648 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 1649 | sigemptyset (&blocked); | ||
| 1650 | sigaddset (&blocked, sig); | ||
| 1651 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); | ||
| 1652 | xsignal0 (Qarith_error); | 1649 | xsignal0 (Qarith_error); |
| 1653 | } | 1650 | } |
| 1654 | 1651 | ||