aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/ChangeLog22
-rw-r--r--src/atimer.c38
-rw-r--r--src/callproc.c20
-rw-r--r--src/keyboard.c10
-rw-r--r--src/lisp.h4
-rw-r--r--src/process.c12
-rw-r--r--src/process.h4
-rw-r--r--src/sound.c12
-rw-r--r--src/sysdep.c21
-rw-r--r--src/term.c10
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 @@
12014-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
12014-03-23 Daniel Colascione <dancol@dancol.org> 232014-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
52static void 52static void
53sigmask_atimers (int how) 53block_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}
60static void 60static void
61block_atimers (void) 61unblock_atimers (sigset_t const *oldset)
62{ 62{
63 sigmask_atimers (SIG_BLOCK); 63 pthread_sigmask (SIG_SETMASK, oldset, 0);
64}
65static void
66unblock_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
158cancel_atimer (struct atimer *timer) 154cancel_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)
217void 214void
218stop_other_atimers (struct atimer *t) 215stop_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
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 */
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
10295handle_interrupt (bool in_signal_handler) 10295handle_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);
4238extern void sys_subshell (void); 4238extern void sys_subshell (void);
4239extern void sys_suspend (void); 4239extern void sys_suspend (void);
4240extern void discard_tty_input (void); 4240extern void discard_tty_input (void);
4241extern void block_tty_out_signal (void); 4241extern void block_tty_out_signal (sigset_t *);
4242extern void unblock_tty_out_signal (void); 4242extern void unblock_tty_out_signal (sigset_t const *);
4243extern void init_sys_modes (struct tty_display_info *); 4243extern void init_sys_modes (struct tty_display_info *);
4244extern void reset_sys_modes (struct tty_display_info *); 4244extern void reset_sys_modes (struct tty_display_info *);
4245extern void init_all_sys_modes (void); 4245extern 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
7070catch_child_signal (void) 7071catch_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
216extern void block_child_signal (void); 216extern void block_child_signal (sigset_t *);
217extern void unblock_child_signal (void); 217extern void unblock_child_signal (sigset_t const *);
218extern Lisp_Object encode_current_directory (void); 218extern Lisp_Object encode_current_directory (void);
219extern void record_kill_process (struct Lisp_Process *, Lisp_Object); 219extern 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
694void 694void
695block_tty_out_signal (void) 695block_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
705void 705void
706unblock_tty_out_signal (void) 706unblock_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
721tcsetpgrp_without_stopping (int fd, pid_t pgid) 721tcsetpgrp_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)
1643static _Noreturn void 1641static _Noreturn void
1644handle_arith_signal (int sig) 1642handle_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 {