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
This commit is contained in:
parent
acc16b66ff
commit
8cf1e6e679
5 changed files with 25 additions and 11 deletions
|
@ -1,3 +1,16 @@
|
|||
2014-05-30 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Don't let SIGINT handling block SIGCHLD indefinitely (Bug#17561).
|
||||
* 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.
|
||||
|
||||
2014-05-29 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* Makefile.in (TEMACS_POST_LINK): Remove target.
|
||||
|
|
|
@ -55,6 +55,7 @@ block_atimers (sigset_t *oldset)
|
|||
sigset_t blocked;
|
||||
sigemptyset (&blocked);
|
||||
sigaddset (&blocked, SIGALRM);
|
||||
sigaddset (&blocked, SIGINT);
|
||||
pthread_sigmask (SIG_BLOCK, &blocked, oldset);
|
||||
}
|
||||
static void
|
||||
|
@ -404,7 +405,6 @@ turn_on_atimers (bool on)
|
|||
void
|
||||
init_atimer (void)
|
||||
{
|
||||
struct sigaction action;
|
||||
#ifdef HAVE_ITIMERSPEC
|
||||
struct sigevent sigev;
|
||||
sigev.sigev_notify = SIGEV_SIGNAL;
|
||||
|
@ -413,7 +413,9 @@ init_atimer (void)
|
|||
alarm_timer_ok = timer_create (CLOCK_REALTIME, &sigev, &alarm_timer) == 0;
|
||||
#endif
|
||||
free_atimers = stopped_atimers = atimers = NULL;
|
||||
/* pending_signals is initialized in init_keyboard.*/
|
||||
|
||||
/* pending_signals is initialized in init_keyboard. */
|
||||
struct sigaction action;
|
||||
emacs_sigaction_init (&action, handle_alarm_signal);
|
||||
sigaction (SIGALRM, &action, 0);
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ block_child_signal (sigset_t *oldset)
|
|||
sigset_t blocked;
|
||||
sigemptyset (&blocked);
|
||||
sigaddset (&blocked, SIGCHLD);
|
||||
sigaddset (&blocked, SIGINT);
|
||||
pthread_sigmask (SIG_BLOCK, &blocked, oldset);
|
||||
}
|
||||
|
||||
|
|
|
@ -2664,6 +2664,7 @@ read_char (int commandflag, Lisp_Object map,
|
|||
/* We must have saved the outer value of getcjmp here,
|
||||
so restore it now. */
|
||||
restore_getcjmp (save_jump);
|
||||
pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
|
||||
unbind_to (jmpcount, Qnil);
|
||||
XSETINT (c, quit_char);
|
||||
internal_last_event_frame = selected_frame;
|
||||
|
@ -10323,9 +10324,6 @@ static void
|
|||
handle_interrupt (bool in_signal_handler)
|
||||
{
|
||||
char c;
|
||||
sigset_t blocked;
|
||||
sigemptyset (&blocked);
|
||||
sigaddset (&blocked, SIGINT);
|
||||
|
||||
cancel_echoing ();
|
||||
|
||||
|
@ -10337,6 +10335,9 @@ handle_interrupt (bool in_signal_handler)
|
|||
/* If SIGINT isn't blocked, don't let us be interrupted by
|
||||
a SIGINT. It might be harmful due to non-reentrancy
|
||||
in I/O functions. */
|
||||
sigset_t blocked;
|
||||
sigemptyset (&blocked);
|
||||
sigaddset (&blocked, SIGINT);
|
||||
pthread_sigmask (SIG_BLOCK, &blocked, 0);
|
||||
}
|
||||
|
||||
|
@ -10421,7 +10422,7 @@ handle_interrupt (bool in_signal_handler)
|
|||
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
|
||||
|
||||
immediate_quit = 0;
|
||||
pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
|
||||
pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
|
||||
saved = gl_state;
|
||||
GCPRO4 (saved.object, saved.global_code,
|
||||
saved.current_syntax_table, saved.old_prop);
|
||||
|
@ -10442,7 +10443,7 @@ handle_interrupt (bool in_signal_handler)
|
|||
}
|
||||
}
|
||||
|
||||
pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
|
||||
pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
|
||||
|
||||
/* TODO: The longjmp in this call throws the NS event loop integration off,
|
||||
and it seems to do fine without this. Probably some attention
|
||||
|
|
|
@ -1645,10 +1645,7 @@ deliver_fatal_thread_signal (int sig)
|
|||
static _Noreturn void
|
||||
handle_arith_signal (int sig)
|
||||
{
|
||||
sigset_t blocked;
|
||||
sigemptyset (&blocked);
|
||||
sigaddset (&blocked, sig);
|
||||
pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
|
||||
pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
|
||||
xsignal0 (Qarith_error);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue