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 | |
| 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')
| -rw-r--r-- | src/ChangeLog | 22 | ||||
| -rw-r--r-- | src/atimer.c | 38 | ||||
| -rw-r--r-- | src/callproc.c | 20 | ||||
| -rw-r--r-- | src/keyboard.c | 10 | ||||
| -rw-r--r-- | src/lisp.h | 4 | ||||
| -rw-r--r-- | src/process.c | 12 | ||||
| -rw-r--r-- | src/process.h | 4 | ||||
| -rw-r--r-- | src/sound.c | 12 | ||||
| -rw-r--r-- | src/sysdep.c | 21 | ||||
| -rw-r--r-- | src/term.c | 10 |
10 files changed, 91 insertions, 62 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d9e99722319..44ebe76555c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,25 @@ | |||
| 1 | 2014-03-25 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Handle sigmask better with nested signal handlers (Bug#15561). | ||
| 4 | * atimer.c (sigmask_atimers): Remove. | ||
| 5 | Remaining use rewritten to use body of this function. | ||
| 6 | * atimer.c (block_atimers, unblock_atimers): | ||
| 7 | * callproc.c (block_child_signal, unblock_child_signal): | ||
| 8 | * sysdep.c (block_tty_out_signal, unblock_tty_out_signal): | ||
| 9 | New arg OLDSET. All callers changed. | ||
| 10 | * atimer.c (block_atimers, unblock_atimers): | ||
| 11 | * callproc.c (block_child_signal, unblock_child_signal): | ||
| 12 | * keyboard.c (handle_interrupt): | ||
| 13 | * sound.c (vox_configure, vox_close): | ||
| 14 | Restore the old signal mask rather than unilaterally clearing bits | ||
| 15 | from the mask, in case a handler is running within another | ||
| 16 | handler. All callers changed. | ||
| 17 | * lisp.h, process.c, process.h, term.c: | ||
| 18 | Adjust decls and callers to match new API. | ||
| 19 | * sysdep.c (emacs_sigaction_init): Don't worry about masking SIGFPE; | ||
| 20 | signal handlers aren't supposed to use floating point anyway. | ||
| 21 | (handle_arith_signal): Unblock just SIGFPE rather than clearing mask. | ||
| 22 | |||
| 1 | 2014-03-23 Daniel Colascione <dancol@dancol.org> | 23 | 2014-03-23 Daniel Colascione <dancol@dancol.org> |
| 2 | 24 | ||
| 3 | Split gc_sweep into discrete functions for legibility and better | 25 | Split gc_sweep into discrete functions for legibility and better |
diff --git a/src/atimer.c b/src/atimer.c index d98ddac0171..a5a2b0714e3 100644 --- a/src/atimer.c +++ b/src/atimer.c | |||
| @@ -50,22 +50,17 @@ static bool alarm_timer_ok; | |||
| 50 | /* Block/unblock SIGALRM. */ | 50 | /* Block/unblock SIGALRM. */ |
| 51 | 51 | ||
| 52 | static void | 52 | static void |
| 53 | sigmask_atimers (int how) | 53 | block_atimers (sigset_t *oldset) |
| 54 | { | 54 | { |
| 55 | sigset_t blocked; | 55 | sigset_t blocked; |
| 56 | sigemptyset (&blocked); | 56 | sigemptyset (&blocked); |
| 57 | sigaddset (&blocked, SIGALRM); | 57 | sigaddset (&blocked, SIGALRM); |
| 58 | pthread_sigmask (how, &blocked, 0); | 58 | pthread_sigmask (SIG_BLOCK, &blocked, oldset); |
| 59 | } | 59 | } |
| 60 | static void | 60 | static void |
| 61 | block_atimers (void) | 61 | unblock_atimers (sigset_t const *oldset) |
| 62 | { | 62 | { |
| 63 | sigmask_atimers (SIG_BLOCK); | 63 | pthread_sigmask (SIG_SETMASK, oldset, 0); |
| 64 | } | ||
| 65 | static void | ||
| 66 | unblock_atimers (void) | ||
| 67 | { | ||
| 68 | sigmask_atimers (SIG_UNBLOCK); | ||
| 69 | } | 64 | } |
| 70 | 65 | ||
| 71 | /* Function prototypes. */ | 66 | /* Function prototypes. */ |
| @@ -98,6 +93,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp, | |||
| 98 | atimer_callback fn, void *client_data) | 93 | atimer_callback fn, void *client_data) |
| 99 | { | 94 | { |
| 100 | struct atimer *t; | 95 | struct atimer *t; |
| 96 | sigset_t oldset; | ||
| 101 | 97 | ||
| 102 | /* Round TIME up to the next full second if we don't have | 98 | /* Round TIME up to the next full second if we don't have |
| 103 | itimers. */ | 99 | itimers. */ |
| @@ -122,7 +118,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp, | |||
| 122 | t->fn = fn; | 118 | t->fn = fn; |
| 123 | t->client_data = client_data; | 119 | t->client_data = client_data; |
| 124 | 120 | ||
| 125 | block_atimers (); | 121 | block_atimers (&oldset); |
| 126 | 122 | ||
| 127 | /* Compute the timer's expiration time. */ | 123 | /* Compute the timer's expiration time. */ |
| 128 | switch (type) | 124 | switch (type) |
| @@ -143,7 +139,7 @@ start_atimer (enum atimer_type type, struct timespec timestamp, | |||
| 143 | 139 | ||
| 144 | /* Insert the timer in the list of active atimers. */ | 140 | /* Insert the timer in the list of active atimers. */ |
| 145 | schedule_atimer (t); | 141 | schedule_atimer (t); |
| 146 | unblock_atimers (); | 142 | unblock_atimers (&oldset); |
| 147 | 143 | ||
| 148 | /* Arrange for a SIGALRM at the time the next atimer is ripe. */ | 144 | /* Arrange for a SIGALRM at the time the next atimer is ripe. */ |
| 149 | set_alarm (); | 145 | set_alarm (); |
| @@ -158,8 +154,9 @@ void | |||
| 158 | cancel_atimer (struct atimer *timer) | 154 | cancel_atimer (struct atimer *timer) |
| 159 | { | 155 | { |
| 160 | int i; | 156 | int i; |
| 157 | sigset_t oldset; | ||
| 161 | 158 | ||
| 162 | block_atimers (); | 159 | block_atimers (&oldset); |
| 163 | 160 | ||
| 164 | for (i = 0; i < 2; ++i) | 161 | for (i = 0; i < 2; ++i) |
| 165 | { | 162 | { |
| @@ -186,7 +183,7 @@ cancel_atimer (struct atimer *timer) | |||
| 186 | } | 183 | } |
| 187 | } | 184 | } |
| 188 | 185 | ||
| 189 | unblock_atimers (); | 186 | unblock_atimers (&oldset); |
| 190 | } | 187 | } |
| 191 | 188 | ||
| 192 | 189 | ||
| @@ -217,7 +214,8 @@ append_atimer_lists (struct atimer *list_1, struct atimer *list_2) | |||
| 217 | void | 214 | void |
| 218 | stop_other_atimers (struct atimer *t) | 215 | stop_other_atimers (struct atimer *t) |
| 219 | { | 216 | { |
| 220 | block_atimers (); | 217 | sigset_t oldset; |
| 218 | block_atimers (&oldset); | ||
| 221 | 219 | ||
| 222 | if (t) | 220 | if (t) |
| 223 | { | 221 | { |
| @@ -242,7 +240,7 @@ stop_other_atimers (struct atimer *t) | |||
| 242 | 240 | ||
| 243 | stopped_atimers = append_atimer_lists (atimers, stopped_atimers); | 241 | stopped_atimers = append_atimer_lists (atimers, stopped_atimers); |
| 244 | atimers = t; | 242 | atimers = t; |
| 245 | unblock_atimers (); | 243 | unblock_atimers (&oldset); |
| 246 | } | 244 | } |
| 247 | 245 | ||
| 248 | 246 | ||
| @@ -256,8 +254,9 @@ run_all_atimers (void) | |||
| 256 | { | 254 | { |
| 257 | struct atimer *t = atimers; | 255 | struct atimer *t = atimers; |
| 258 | struct atimer *next; | 256 | struct atimer *next; |
| 257 | sigset_t oldset; | ||
| 259 | 258 | ||
| 260 | block_atimers (); | 259 | block_atimers (&oldset); |
| 261 | atimers = stopped_atimers; | 260 | atimers = stopped_atimers; |
| 262 | stopped_atimers = NULL; | 261 | stopped_atimers = NULL; |
| 263 | 262 | ||
| @@ -268,7 +267,7 @@ run_all_atimers (void) | |||
| 268 | t = next; | 267 | t = next; |
| 269 | } | 268 | } |
| 270 | 269 | ||
| 271 | unblock_atimers (); | 270 | unblock_atimers (&oldset); |
| 272 | } | 271 | } |
| 273 | } | 272 | } |
| 274 | 273 | ||
| @@ -381,9 +380,10 @@ do_pending_atimers (void) | |||
| 381 | { | 380 | { |
| 382 | if (atimers) | 381 | if (atimers) |
| 383 | { | 382 | { |
| 384 | block_atimers (); | 383 | sigset_t oldset; |
| 384 | block_atimers (&oldset); | ||
| 385 | run_timers (); | 385 | run_timers (); |
| 386 | unblock_atimers (); | 386 | unblock_atimers (&oldset); |
| 387 | } | 387 | } |
| 388 | } | 388 | } |
| 389 | 389 | ||
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 */ |
diff --git a/src/keyboard.c b/src/keyboard.c index 038ce6ea601..2b3de6e27c2 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -10295,6 +10295,9 @@ static void | |||
| 10295 | handle_interrupt (bool in_signal_handler) | 10295 | handle_interrupt (bool in_signal_handler) |
| 10296 | { | 10296 | { |
| 10297 | char c; | 10297 | char c; |
| 10298 | sigset_t blocked; | ||
| 10299 | sigemptyset (&blocked); | ||
| 10300 | sigaddset (&blocked, SIGINT); | ||
| 10298 | 10301 | ||
| 10299 | cancel_echoing (); | 10302 | cancel_echoing (); |
| 10300 | 10303 | ||
| @@ -10306,9 +10309,6 @@ handle_interrupt (bool in_signal_handler) | |||
| 10306 | /* If SIGINT isn't blocked, don't let us be interrupted by | 10309 | /* If SIGINT isn't blocked, don't let us be interrupted by |
| 10307 | a SIGINT. It might be harmful due to non-reentrancy | 10310 | a SIGINT. It might be harmful due to non-reentrancy |
| 10308 | in I/O functions. */ | 10311 | in I/O functions. */ |
| 10309 | sigset_t blocked; | ||
| 10310 | sigemptyset (&blocked); | ||
| 10311 | sigaddset (&blocked, SIGINT); | ||
| 10312 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | 10312 | pthread_sigmask (SIG_BLOCK, &blocked, 0); |
| 10313 | } | 10313 | } |
| 10314 | 10314 | ||
| @@ -10393,7 +10393,7 @@ handle_interrupt (bool in_signal_handler) | |||
| 10393 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 10393 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 10394 | 10394 | ||
| 10395 | immediate_quit = 0; | 10395 | immediate_quit = 0; |
| 10396 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 10396 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); |
| 10397 | saved = gl_state; | 10397 | saved = gl_state; |
| 10398 | GCPRO4 (saved.object, saved.global_code, | 10398 | GCPRO4 (saved.object, saved.global_code, |
| 10399 | saved.current_syntax_table, saved.old_prop); | 10399 | saved.current_syntax_table, saved.old_prop); |
| @@ -10414,7 +10414,7 @@ handle_interrupt (bool in_signal_handler) | |||
| 10414 | } | 10414 | } |
| 10415 | } | 10415 | } |
| 10416 | 10416 | ||
| 10417 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 10417 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); |
| 10418 | 10418 | ||
| 10419 | /* TODO: The longjmp in this call throws the NS event loop integration off, | 10419 | /* TODO: The longjmp in this call throws the NS event loop integration off, |
| 10420 | and it seems to do fine without this. Probably some attention | 10420 | and it seems to do fine without this. Probably some attention |
diff --git a/src/lisp.h b/src/lisp.h index df8f3120a8e..98f6c8b4d8d 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4238,8 +4238,8 @@ extern void init_sigio (int); | |||
| 4238 | extern void sys_subshell (void); | 4238 | extern void sys_subshell (void); |
| 4239 | extern void sys_suspend (void); | 4239 | extern void sys_suspend (void); |
| 4240 | extern void discard_tty_input (void); | 4240 | extern void discard_tty_input (void); |
| 4241 | extern void block_tty_out_signal (void); | 4241 | extern void block_tty_out_signal (sigset_t *); |
| 4242 | extern void unblock_tty_out_signal (void); | 4242 | extern void unblock_tty_out_signal (sigset_t const *); |
| 4243 | extern void init_sys_modes (struct tty_display_info *); | 4243 | extern void init_sys_modes (struct tty_display_info *); |
| 4244 | extern void reset_sys_modes (struct tty_display_info *); | 4244 | extern void reset_sys_modes (struct tty_display_info *); |
| 4245 | extern void init_all_sys_modes (void); | 4245 | extern void init_all_sys_modes (void); |
diff --git a/src/process.c b/src/process.c index fd34eb08d9d..fe365a136de 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) | |||
| 1663 | bool pty_flag = 0; | 1663 | bool pty_flag = 0; |
| 1664 | char pty_name[PTY_NAME_SIZE]; | 1664 | char pty_name[PTY_NAME_SIZE]; |
| 1665 | Lisp_Object lisp_pty_name = Qnil; | 1665 | Lisp_Object lisp_pty_name = Qnil; |
| 1666 | sigset_t oldset; | ||
| 1666 | 1667 | ||
| 1667 | inchannel = outchannel = -1; | 1668 | inchannel = outchannel = -1; |
| 1668 | 1669 | ||
| @@ -1728,7 +1729,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1728 | setup_process_coding_systems (process); | 1729 | setup_process_coding_systems (process); |
| 1729 | 1730 | ||
| 1730 | block_input (); | 1731 | block_input (); |
| 1731 | block_child_signal (); | 1732 | block_child_signal (&oldset); |
| 1732 | 1733 | ||
| 1733 | #ifndef WINDOWSNT | 1734 | #ifndef WINDOWSNT |
| 1734 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 1735 | /* 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) | |||
| 1852 | signal (SIGPIPE, SIG_DFL); | 1853 | signal (SIGPIPE, SIG_DFL); |
| 1853 | 1854 | ||
| 1854 | /* Stop blocking SIGCHLD in the child. */ | 1855 | /* Stop blocking SIGCHLD in the child. */ |
| 1855 | unblock_child_signal (); | 1856 | unblock_child_signal (&oldset); |
| 1856 | 1857 | ||
| 1857 | if (pty_flag) | 1858 | if (pty_flag) |
| 1858 | child_setup_tty (xforkout); | 1859 | child_setup_tty (xforkout); |
| @@ -1871,7 +1872,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1871 | p->alive = 1; | 1872 | p->alive = 1; |
| 1872 | 1873 | ||
| 1873 | /* Stop blocking in the parent. */ | 1874 | /* Stop blocking in the parent. */ |
| 1874 | unblock_child_signal (); | 1875 | unblock_child_signal (&oldset); |
| 1875 | unblock_input (); | 1876 | unblock_input (); |
| 1876 | 1877 | ||
| 1877 | if (pid < 0) | 1878 | if (pid < 0) |
| @@ -7070,8 +7071,9 @@ void | |||
| 7070 | catch_child_signal (void) | 7071 | catch_child_signal (void) |
| 7071 | { | 7072 | { |
| 7072 | struct sigaction action, old_action; | 7073 | struct sigaction action, old_action; |
| 7074 | sigset_t oldset; | ||
| 7073 | emacs_sigaction_init (&action, deliver_child_signal); | 7075 | emacs_sigaction_init (&action, deliver_child_signal); |
| 7074 | block_child_signal (); | 7076 | block_child_signal (&oldset); |
| 7075 | sigaction (SIGCHLD, &action, &old_action); | 7077 | sigaction (SIGCHLD, &action, &old_action); |
| 7076 | eassert (! (old_action.sa_flags & SA_SIGINFO)); | 7078 | eassert (! (old_action.sa_flags & SA_SIGINFO)); |
| 7077 | 7079 | ||
| @@ -7080,7 +7082,7 @@ catch_child_signal (void) | |||
| 7080 | = (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN | 7082 | = (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN |
| 7081 | ? dummy_handler | 7083 | ? dummy_handler |
| 7082 | : old_action.sa_handler); | 7084 | : old_action.sa_handler); |
| 7083 | unblock_child_signal (); | 7085 | unblock_child_signal (&oldset); |
| 7084 | } | 7086 | } |
| 7085 | 7087 | ||
| 7086 | 7088 | ||
diff --git a/src/process.h b/src/process.h index c3481f295f5..842554bdef4 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -213,8 +213,8 @@ enum | |||
| 213 | 213 | ||
| 214 | /* Defined in callproc.c. */ | 214 | /* Defined in callproc.c. */ |
| 215 | 215 | ||
| 216 | extern void block_child_signal (void); | 216 | extern void block_child_signal (sigset_t *); |
| 217 | extern void unblock_child_signal (void); | 217 | extern void unblock_child_signal (sigset_t const *); |
| 218 | extern Lisp_Object encode_current_directory (void); | 218 | extern Lisp_Object encode_current_directory (void); |
| 219 | extern void record_kill_process (struct Lisp_Process *, Lisp_Object); | 219 | extern void record_kill_process (struct Lisp_Process *, Lisp_Object); |
| 220 | 220 | ||
diff --git a/src/sound.c b/src/sound.c index a95678812e1..7046f4e8e32 100644 --- a/src/sound.c +++ b/src/sound.c | |||
| @@ -702,7 +702,7 @@ vox_configure (struct sound_device *sd) | |||
| 702 | { | 702 | { |
| 703 | int val; | 703 | int val; |
| 704 | #ifdef USABLE_SIGIO | 704 | #ifdef USABLE_SIGIO |
| 705 | sigset_t blocked; | 705 | sigset_t oldset, blocked; |
| 706 | #endif | 706 | #endif |
| 707 | 707 | ||
| 708 | eassert (sd->fd >= 0); | 708 | eassert (sd->fd >= 0); |
| @@ -714,7 +714,7 @@ vox_configure (struct sound_device *sd) | |||
| 714 | #ifdef USABLE_SIGIO | 714 | #ifdef USABLE_SIGIO |
| 715 | sigemptyset (&blocked); | 715 | sigemptyset (&blocked); |
| 716 | sigaddset (&blocked, SIGIO); | 716 | sigaddset (&blocked, SIGIO); |
| 717 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | 717 | pthread_sigmask (SIG_BLOCK, &blocked, &oldset); |
| 718 | #endif | 718 | #endif |
| 719 | 719 | ||
| 720 | val = sd->format; | 720 | val = sd->format; |
| @@ -748,7 +748,7 @@ vox_configure (struct sound_device *sd) | |||
| 748 | 748 | ||
| 749 | turn_on_atimers (1); | 749 | turn_on_atimers (1); |
| 750 | #ifdef USABLE_SIGIO | 750 | #ifdef USABLE_SIGIO |
| 751 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); | 751 | pthread_sigmask (SIG_SETMASK, &oldset, 0); |
| 752 | #endif | 752 | #endif |
| 753 | } | 753 | } |
| 754 | 754 | ||
| @@ -764,10 +764,10 @@ vox_close (struct sound_device *sd) | |||
| 764 | be interrupted by a signal. Block the ones we know to cause | 764 | be interrupted by a signal. Block the ones we know to cause |
| 765 | troubles. */ | 765 | troubles. */ |
| 766 | #ifdef USABLE_SIGIO | 766 | #ifdef USABLE_SIGIO |
| 767 | sigset_t blocked; | 767 | sigset_t blocked, oldset; |
| 768 | sigemptyset (&blocked); | 768 | sigemptyset (&blocked); |
| 769 | sigaddset (&blocked, SIGIO); | 769 | sigaddset (&blocked, SIGIO); |
| 770 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | 770 | pthread_sigmask (SIG_BLOCK, &blocked, &oldset); |
| 771 | #endif | 771 | #endif |
| 772 | turn_on_atimers (0); | 772 | turn_on_atimers (0); |
| 773 | 773 | ||
| @@ -776,7 +776,7 @@ vox_close (struct sound_device *sd) | |||
| 776 | 776 | ||
| 777 | turn_on_atimers (1); | 777 | turn_on_atimers (1); |
| 778 | #ifdef USABLE_SIGIO | 778 | #ifdef USABLE_SIGIO |
| 779 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); | 779 | pthread_sigmask (SIG_SETMASK, &oldset, 0); |
| 780 | #endif | 780 | #endif |
| 781 | 781 | ||
| 782 | /* Close the device. */ | 782 | /* Close the device. */ |
diff --git a/src/sysdep.c b/src/sysdep.c index 6ec8eecb287..af9f4801cec 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -692,21 +692,21 @@ init_foreground_group (void) | |||
| 692 | /* Block and unblock SIGTTOU. */ | 692 | /* Block and unblock SIGTTOU. */ |
| 693 | 693 | ||
| 694 | void | 694 | void |
| 695 | block_tty_out_signal (void) | 695 | block_tty_out_signal (sigset_t *oldset) |
| 696 | { | 696 | { |
| 697 | #ifdef SIGTTOU | 697 | #ifdef SIGTTOU |
| 698 | sigset_t blocked; | 698 | sigset_t blocked; |
| 699 | sigemptyset (&blocked); | 699 | sigemptyset (&blocked); |
| 700 | sigaddset (&blocked, SIGTTOU); | 700 | sigaddset (&blocked, SIGTTOU); |
| 701 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | 701 | pthread_sigmask (SIG_BLOCK, &blocked, oldset); |
| 702 | #endif | 702 | #endif |
| 703 | } | 703 | } |
| 704 | 704 | ||
| 705 | void | 705 | void |
| 706 | unblock_tty_out_signal (void) | 706 | unblock_tty_out_signal (sigset_t const *oldset) |
| 707 | { | 707 | { |
| 708 | #ifdef SIGTTOU | 708 | #ifdef SIGTTOU |
| 709 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 709 | pthread_sigmask (SIG_SETMASK, oldset, 0); |
| 710 | #endif | 710 | #endif |
| 711 | } | 711 | } |
| 712 | 712 | ||
| @@ -721,10 +721,11 @@ static void | |||
| 721 | tcsetpgrp_without_stopping (int fd, pid_t pgid) | 721 | tcsetpgrp_without_stopping (int fd, pid_t pgid) |
| 722 | { | 722 | { |
| 723 | #ifdef SIGTTOU | 723 | #ifdef SIGTTOU |
| 724 | sigset_t oldset; | ||
| 724 | block_input (); | 725 | block_input (); |
| 725 | block_tty_out_signal (); | 726 | block_tty_out_signal (&oldset); |
| 726 | tcsetpgrp (fd, pgid); | 727 | tcsetpgrp (fd, pgid); |
| 727 | unblock_tty_out_signal (); | 728 | unblock_tty_out_signal (&oldset); |
| 728 | unblock_input (); | 729 | unblock_input (); |
| 729 | #endif | 730 | #endif |
| 730 | } | 731 | } |
| @@ -1525,9 +1526,6 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) | |||
| 1525 | #endif | 1526 | #endif |
| 1526 | } | 1527 | } |
| 1527 | 1528 | ||
| 1528 | if (! IEEE_FLOATING_POINT) | ||
| 1529 | sigaddset (&action->sa_mask, SIGFPE); | ||
| 1530 | |||
| 1531 | action->sa_handler = handler; | 1529 | action->sa_handler = handler; |
| 1532 | action->sa_flags = emacs_sigaction_flags (); | 1530 | action->sa_flags = emacs_sigaction_flags (); |
| 1533 | } | 1531 | } |
| @@ -1643,7 +1641,10 @@ deliver_fatal_thread_signal (int sig) | |||
| 1643 | static _Noreturn void | 1641 | static _Noreturn void |
| 1644 | handle_arith_signal (int sig) | 1642 | handle_arith_signal (int sig) |
| 1645 | { | 1643 | { |
| 1646 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 1644 | sigset_t blocked; |
| 1645 | sigemptyset (&blocked); | ||
| 1646 | sigaddset (&blocked, sig); | ||
| 1647 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); | ||
| 1647 | xsignal0 (Qarith_error); | 1648 | xsignal0 (Qarith_error); |
| 1648 | } | 1649 | } |
| 1649 | 1650 | ||
diff --git a/src/term.c b/src/term.c index 3bcbb70aff6..df5fc17a0c0 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -3944,9 +3944,10 @@ dissociate_if_controlling_tty (int fd) | |||
| 3944 | /* setsid failed, presumably because Emacs is already a process | 3944 | /* setsid failed, presumably because Emacs is already a process |
| 3945 | group leader. Fall back on the obsolescent way to dissociate | 3945 | group leader. Fall back on the obsolescent way to dissociate |
| 3946 | a controlling tty. */ | 3946 | a controlling tty. */ |
| 3947 | block_tty_out_signal (); | 3947 | sigset_t oldset; |
| 3948 | block_tty_out_signal (&oldset); | ||
| 3948 | ioctl (fd, TIOCNOTTY, 0); | 3949 | ioctl (fd, TIOCNOTTY, 0); |
| 3949 | unblock_tty_out_signal (); | 3950 | unblock_tty_out_signal (&oldset); |
| 3950 | #endif | 3951 | #endif |
| 3951 | } | 3952 | } |
| 3952 | } | 3953 | } |
| @@ -3970,6 +3971,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) | |||
| 3970 | int status; | 3971 | int status; |
| 3971 | struct tty_display_info *tty = NULL; | 3972 | struct tty_display_info *tty = NULL; |
| 3972 | struct terminal *terminal = NULL; | 3973 | struct terminal *terminal = NULL; |
| 3974 | sigset_t oldset; | ||
| 3973 | bool ctty = false; /* True if asked to open controlling tty. */ | 3975 | bool ctty = false; /* True if asked to open controlling tty. */ |
| 3974 | 3976 | ||
| 3975 | if (!terminal_type) | 3977 | if (!terminal_type) |
| @@ -4059,11 +4061,11 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed) | |||
| 4059 | 4061 | ||
| 4060 | /* On some systems, tgetent tries to access the controlling | 4062 | /* On some systems, tgetent tries to access the controlling |
| 4061 | terminal. */ | 4063 | terminal. */ |
| 4062 | block_tty_out_signal (); | 4064 | block_tty_out_signal (&oldset); |
| 4063 | status = tgetent (tty->termcap_term_buffer, terminal_type); | 4065 | status = tgetent (tty->termcap_term_buffer, terminal_type); |
| 4064 | if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1]) | 4066 | if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1]) |
| 4065 | emacs_abort (); | 4067 | emacs_abort (); |
| 4066 | unblock_tty_out_signal (); | 4068 | unblock_tty_out_signal (&oldset); |
| 4067 | 4069 | ||
| 4068 | if (status < 0) | 4070 | if (status < 0) |
| 4069 | { | 4071 | { |