aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2012-09-06 18:27:44 -0700
committerPaul Eggert2012-09-06 18:27:44 -0700
commit2fe282993cf9c84f5be424dc93d03f9705a7edd8 (patch)
tree229edb6fe29e66984b2992f3f9fa081cd7fe8920
parent845ce106c0ab157e25416964330875ad6c24b699 (diff)
downloademacs-2fe282993cf9c84f5be424dc93d03f9705a7edd8.tar.gz
emacs-2fe282993cf9c84f5be424dc93d03f9705a7edd8.zip
Signal-handler cleanup.
Emacs's signal handlers were written in the old 4.2BSD style with sigblock and sigmask and so forth, and this led to some inefficiencies and confusion. Rewrite these to use pthread_sigmask etc. without copying signal sets around. Also, get rid of the confusing macros 'SIGNAL_THREAD_CHECK' and 'signal', and instead use functions that do not attempt to take over the system name space. This patch causes Emacs's text segment to shrink by 0.7% on my platform, Fedora 17 x86-64. * configure.ac (PTY_OPEN, PTY_TTY_NAME_SPRINTF): Adjust to syssignal.h changes. (SIGNAL_H_AB): Remove; no longer needed. * src/alloc.c, src/emacsgtkfixed.c, src/nsfns.m, src/widget.c, src/xmenu.c: Do not include <signal.h> or "syssignal.h", as these modules do not use signals. * src/atimer.c, src/callproc.c, src/data.c, src/dispnew.c, src/emacs.c: * src/floatfns.c, src/gtkutil.c, src/keyboard.c, src/process.c, src/sound.c: * src/sysdep.c, src/term.c, src/xterm.c: Do not include <signal.h>, as "syssignal.h" does that for us now. * src/atimer.c (sigmask_atimers): New function. (block_atimers, unblock_atimers): New functions, replacing the old macros BLOCK_ATIMERS and UNBLOCK_ATIMERS. All uses replaced. * src/conf_post.h [SIGNAL_H_AHB]: Do not include <signal.h>; no longer needed here. * src/emacs.c (main): Inspect existing signal handler with sigaction, so that there's no need to block and unblock SIGHUP. * src/sysdep.c (struct save_signal): New member 'action', replacing old member 'handler'. (save_signal_handlers, restore_signal_handlers): Use sigaction instead of 'signal' to save and restore. (get_set_sighandler, set_sighandler) [!WINDOWSNT]: New function. All users of 'signal' modified to use set_sighandler if they're writeonly, and to use sys_signal if they're read+write. (emacs_sigaction_init, forwarded_signal): New functions. (sys_signal): Remove. All uses replaced by calls to sigaction and emacs_sigaction_init, or by direct calls to 'signal'. (sys_sigmask) [!__GNUC__]: Remove; no longer needed. (sys_sigblock, sys_sigunblock, sys_sigsetmask): Remove; all uses replaced by pthread_sigmask etc. calls. * src/syssignal.h: Include <signal.h>. (emacs_sigaction_init, forwarded_signal): New decls. (SIGMASKTYPE): Remove. All uses replaced by its definiens, sigset_t. (SIGEMPTYMASK): Remove; all uses replaced by its definiens, empty_mask. (sigmask, sys_sigmask): Remove; no longer needed. (sigpause): Remove. All uses replaced by its definiens, sigsuspend. (sigblock, sigunblock, sigfree): (sigsetmask) [!defined sigsetmask]: Remove. All uses replaced by pthread_sigmask. (signal): Remove. Its remaining uses (with SIG_DFL and SIG_IGN) no longer need to be replaced, and its typical old uses are now done via emacs_sigaction_init and sigaction. (sys_sigblock, sys_sigunblock, sys_sigsetmask): Remove decls. (sys_sigdel): Remove; unused. (NSIG): Remove a FIXME; the code's fine. Remove an unnecessary ifdef. Fixes: debbugs:12327
-rw-r--r--ChangeLog7
-rw-r--r--configure.ac18
-rw-r--r--src/ChangeLog56
-rw-r--r--src/alloc.c3
-rw-r--r--src/atimer.c49
-rw-r--r--src/callproc.c4
-rw-r--r--src/conf_post.h5
-rw-r--r--src/data.c7
-rw-r--r--src/dispnew.c11
-rw-r--r--src/emacs.c82
-rw-r--r--src/emacsgtkfixed.c1
-rw-r--r--src/floatfns.c1
-rw-r--r--src/gtkutil.c15
-rw-r--r--src/keyboard.c72
-rw-r--r--src/nsfns.m1
-rw-r--r--src/process.c33
-rw-r--r--src/sound.c24
-rw-r--r--src/sysdep.c111
-rw-r--r--src/syssignal.h59
-rw-r--r--src/term.c19
-rw-r--r--src/widget.c3
-rw-r--r--src/xmenu.c5
-rw-r--r--src/xterm.c22
23 files changed, 325 insertions, 283 deletions
diff --git a/ChangeLog b/ChangeLog
index 55223ab8c5e..112532e7ece 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
12012-09-06 Paul Eggert <eggert@cs.ucla.edu>
2
3 Signal-handler cleanup (Bug#12327).
4 * configure.ac (PTY_OPEN, PTY_TTY_NAME_SPRINTF):
5 Adjust to syssignal.h changes.
6 (SIGNAL_H_AB): Remove; no longer needed.
7
12012-09-04 Paul Eggert <eggert@cs.ucla.edu> 82012-09-04 Paul Eggert <eggert@cs.ucla.edu>
2 9
3 Simplify redefinition of 'abort' (Bug#12316). 10 Simplify redefinition of 'abort' (Bug#12316).
diff --git a/configure.ac b/configure.ac
index 16e579c862a..dd5e322194a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3445,7 +3445,7 @@ case $opsys in
3445 cygwin ) 3445 cygwin )
3446 AC_DEFINE(PTY_ITERATION, [int i; for (i = 0; i < 1; i++)]) 3446 AC_DEFINE(PTY_ITERATION, [int i; for (i = 0; i < 1; i++)])
3447 dnl multi-line AC_DEFINEs are hard. :( 3447 dnl multi-line AC_DEFINEs are hard. :(
3448 AC_DEFINE(PTY_OPEN, [ do { int dummy; SIGMASKTYPE mask; mask = sigblock (sigmask (SIGCHLD)); if (-1 == openpty (&fd, &dummy, pty_name, 0, 0)) fd = -1; sigsetmask (mask); if (fd >= 0) emacs_close (dummy); } while (0)]) 3448 AC_DEFINE(PTY_OPEN, [ do { int dummy; sigset_t blocked, procmask; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, &procmask); if (-1 == openpty (&fd, &dummy, pty_name, 0, 0)) fd = -1; pthread_sigmask (SIG_SETMASK, &procmask, 0); if (fd >= 0) emacs_close (dummy); } while (0)])
3449 AC_DEFINE(PTY_NAME_SPRINTF, []) 3449 AC_DEFINE(PTY_NAME_SPRINTF, [])
3450 AC_DEFINE(PTY_TTY_NAME_SPRINTF, []) 3450 AC_DEFINE(PTY_TTY_NAME_SPRINTF, [])
3451 ;; 3451 ;;
@@ -3474,7 +3474,7 @@ case $opsys in
3474 AC_DEFINE(PTY_ITERATION, [int i; for (i = 0; i < 1; i++)]) 3474 AC_DEFINE(PTY_ITERATION, [int i; for (i = 0; i < 1; i++)])
3475 dnl Note that grantpt and unlockpt may fork. We must block SIGCHLD 3475 dnl Note that grantpt and unlockpt may fork. We must block SIGCHLD
3476 dnl to prevent sigchld_handler from intercepting the child's death. 3476 dnl to prevent sigchld_handler from intercepting the child's death.
3477 AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptyname; sigblock (sigmask (SIGCHLD)); if (grantpt (fd) == -1 || unlockpt (fd) == -1 || !(ptyname = ptsname(fd))) { sigunblock (sigmask (SIGCHLD)); close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); sigunblock (sigmask (SIGCHLD)); }]) 3477 AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptyname = 0; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); if (grantpt (fd) != -1 && unlockpt (fd) != -1) ptyname = ptsname(fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (!ptyname) { close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); }])
3478 dnl if HAVE_POSIX_OPENPT 3478 dnl if HAVE_POSIX_OPENPT
3479 if test "x$ac_cv_func_posix_openpt" = xyes; then 3479 if test "x$ac_cv_func_posix_openpt" = xyes; then
3480 AC_DEFINE(PTY_OPEN, [fd = posix_openpt (O_RDWR | O_NOCTTY)]) 3480 AC_DEFINE(PTY_OPEN, [fd = posix_openpt (O_RDWR | O_NOCTTY)])
@@ -3519,18 +3519,15 @@ case $opsys in
3519 ;; 3519 ;;
3520 3520
3521 sol2* ) 3521 sol2* )
3522 dnl Uses sigblock/sigunblock rather than sighold/sigrelse,
3523 dnl which appear to be BSD4.1 specific. It may also be appropriate
3524 dnl for SVR4.x (x<2) but I'm not sure. fnf@cygnus.com
3525 dnl On SysVr4, grantpt(3) forks a subprocess, so keep sigchld_handler() 3522 dnl On SysVr4, grantpt(3) forks a subprocess, so keep sigchld_handler()
3526 dnl from intercepting that death. If any child but grantpt's should die 3523 dnl from intercepting that death. If any child but grantpt's should die
3527 dnl within, it should be caught after sigrelse(2). 3524 dnl within, it should be caught after sigrelse(2).
3528 AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; sigblock (sigmask (SIGCLD)); if (grantpt (fd) == -1) { emacs_close (fd); return -1; } sigunblock (sigmask (SIGCLD)); if (unlockpt (fd) == -1) { emacs_close (fd); return -1; } if (!(ptyname = ptsname (fd))) { emacs_close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); }]) 3525 AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1 || unlockpt (fd) == -1 || !(ptyname = ptsname (fd))) { emacs_close (fd); return -1; } snprintf (pty_name, sizeof pty_name, "%s", ptyname); }])
3529 ;; 3526 ;;
3530 3527
3531 unixware ) 3528 unixware )
3532 dnl Comments are as per sol2*. 3529 dnl Comments are as per sol2*.
3533 AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; sigblock(sigmask(SIGCLD)); if (grantpt(fd) == -1) fatal("could not grant slave pty"); sigunblock(sigmask(SIGCLD)); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, sizeof pty_name, "%s", ptyname); }]) 3530 AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, sizeof pty_name, "%s", ptyname); }])
3534 ;; 3531 ;;
3535esac 3532esac
3536 3533
@@ -3820,13 +3817,6 @@ case $opsys in
3820 AC_DEFINE(XOS_NEEDS_TIME_H, 1, [Compensate for a bug in Xos.h on 3817 AC_DEFINE(XOS_NEEDS_TIME_H, 1, [Compensate for a bug in Xos.h on
3821 some systems, where it requires time.h.]) 3818 some systems, where it requires time.h.])
3822 ;; 3819 ;;
3823
3824 netbsd | openbsd )
3825 dnl Greg A. Woods <woods@weird.com> says we must include signal.h
3826 dnl before syssignal.h is included, to work around interface conflicts
3827 dnl that are handled with CPP __RENAME() macro in signal.h.
3828 AC_DEFINE(SIGNAL_H_AHB, 1, [Define if AH_BOTTOM should include signal.h.])
3829 ;;
3830esac 3820esac
3831 3821
3832 3822
diff --git a/src/ChangeLog b/src/ChangeLog
index 479fb38e60b..3bfa9e929d5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,57 @@
12012-09-06 Paul Eggert <eggert@cs.ucla.edu>
2
3 Signal-handler cleanup (Bug#12327).
4 Emacs's signal handlers were written in the old 4.2BSD style with
5 sigblock and sigmask and so forth, and this led to some
6 inefficiencies and confusion. Rewrite these to use
7 pthread_sigmask etc. without copying signal sets around. Also,
8 get rid of the confusing macros 'SIGNAL_THREAD_CHECK' and
9 'signal', and instead use functions that do not attempt to take
10 over the system name space. This patch causes Emacs's text
11 segment to shrink by 0.7% on my platform, Fedora 17 x86-64.
12 * alloc.c, emacsgtkfixed.c, nsfns.m, widget.c, xmenu.c:
13 Do not include <signal.h> or "syssignal.h", as these
14 modules do not use signals.
15 * atimer.c, callproc.c, data.c, dispnew.c, emacs.c, floatfns.c:
16 * gtkutil.c, keyboard.c, process.c, sound.c, sysdep.c, term.c, xterm.c:
17 Do not include <signal.h>, as "syssignal.h" does that for us now.
18 * atimer.c (sigmask_atimers): New function.
19 (block_atimers, unblock_atimers): New functions,
20 replacing the old macros BLOCK_ATIMERS and UNBLOCK_ATIMERS.
21 All uses replaced.
22 * conf_post.h [SIGNAL_H_AHB]: Do not include <signal.h>;
23 no longer needed here.
24 * emacs.c (main): Inspect existing signal handler with sigaction,
25 so that there's no need to block and unblock SIGHUP.
26 * sysdep.c (struct save_signal): New member 'action', replacing
27 old member 'handler'.
28 (save_signal_handlers, restore_signal_handlers):
29 Use sigaction instead of 'signal' to save and restore.
30 (get_set_sighandler, set_sighandler) [!WINDOWSNT]:
31 New function. All users of 'signal' modified to use set_sighandler
32 if they're writeonly, and to use sys_signal if they're read+write.
33 (emacs_sigaction_init, forwarded_signal): New functions.
34 (sys_signal): Remove. All uses replaced by calls to sigaction
35 and emacs_sigaction_init, or by direct calls to 'signal'.
36 (sys_sigmask) [!__GNUC__]: Remove; no longer needed.
37 (sys_sigblock, sys_sigunblock, sys_sigsetmask): Remove;
38 all uses replaced by pthread_sigmask etc. calls.
39 * syssignal.h: Include <signal.h>.
40 (emacs_sigaction_init, forwarded_signal): New decls.
41 (SIGMASKTYPE): Remove. All uses replaced by its definiens, sigset_t.
42 (SIGEMPTYMASK): Remove; all uses replaced by its definiens, empty_mask.
43 (sigmask, sys_sigmask): Remove; no longer needed.
44 (sigpause): Remove. All uses replaced by its definiens, sigsuspend.
45 (sigblock, sigunblock, sigfree):
46 (sigsetmask) [!defined sigsetmask]:
47 Remove. All uses replaced by pthread_sigmask.
48 (signal): Remove. Its remaining uses (with SIG_DFL and SIG_IGN)
49 no longer need to be replaced, and its typical old uses
50 are now done via emacs_sigaction_init and sigaction.
51 (sys_sigblock, sys_sigunblock, sys_sigsetmask): Remove decls.
52 (sys_sigdel): Remove; unused.
53 (NSIG): Remove a FIXME; the code's fine. Remove an unnecessary ifdef.
54
12012-09-06 Eli Zaretskii <eliz@gnu.org> 552012-09-06 Eli Zaretskii <eliz@gnu.org>
2 56
3 * process.c (CAN_HANDLE_MULTIPLE_CHILDREN): Fix a typo that broke 57 * process.c (CAN_HANDLE_MULTIPLE_CHILDREN): Fix a typo that broke
@@ -50,7 +104,7 @@
50 104
512012-09-05 Paul Eggert <eggert@cs.ucla.edu> 1052012-09-05 Paul Eggert <eggert@cs.ucla.edu>
52 106
53 Fix race conditions with signal handlers and errno. 107 Fix race conditions with signal handlers and errno (Bug#12327).
54 Be more systematic about preserving errno whenever a signal 108 Be more systematic about preserving errno whenever a signal
55 handler returns, even if it's not in the main thread. Do this by 109 handler returns, even if it's not in the main thread. Do this by
56 renaming signal handlers to distinguish between signal delivery 110 renaming signal handlers to distinguish between signal delivery
diff --git a/src/alloc.c b/src/alloc.c
index 1a9718bcb25..bf7c156d321 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -26,8 +26,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26#include <limits.h> /* For CHAR_BIT. */ 26#include <limits.h> /* For CHAR_BIT. */
27#include <setjmp.h> 27#include <setjmp.h>
28 28
29#include <signal.h>
30
31#ifdef HAVE_PTHREAD 29#ifdef HAVE_PTHREAD
32#include <pthread.h> 30#include <pthread.h>
33#endif 31#endif
@@ -42,7 +40,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
42#include "keyboard.h" 40#include "keyboard.h"
43#include "frame.h" 41#include "frame.h"
44#include "blockinput.h" 42#include "blockinput.h"
45#include "syssignal.h"
46#include "termhooks.h" /* For struct terminal. */ 43#include "termhooks.h" /* For struct terminal. */
47#include <setjmp.h> 44#include <setjmp.h>
48#include <verify.h> 45#include <verify.h>
diff --git a/src/atimer.c b/src/atimer.c
index 060dead9b17..34731920af5 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -17,7 +17,6 @@ You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18 18
19#include <config.h> 19#include <config.h>
20#include <signal.h>
21#include <stdio.h> 20#include <stdio.h>
22#include <setjmp.h> 21#include <setjmp.h>
23#include "lisp.h" 22#include "lisp.h"
@@ -51,8 +50,24 @@ int pending_atimers;
51 50
52/* Block/unblock SIGALRM. */ 51/* Block/unblock SIGALRM. */
53 52
54#define BLOCK_ATIMERS sigblock (sigmask (SIGALRM)) 53static void
55#define UNBLOCK_ATIMERS sigunblock (sigmask (SIGALRM)) 54sigmask_atimers (int how)
55{
56 sigset_t blocked;
57 sigemptyset (&blocked);
58 sigaddset (&blocked, SIGALRM);
59 pthread_sigmask (how, &blocked, 0);
60}
61static void
62block_atimers (void)
63{
64 sigmask_atimers (SIG_BLOCK);
65}
66static void
67unblock_atimers (void)
68{
69 sigmask_atimers (SIG_UNBLOCK);
70}
56 71
57/* Function prototypes. */ 72/* Function prototypes. */
58 73
@@ -109,7 +124,7 @@ start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn,
109 t->fn = fn; 124 t->fn = fn;
110 t->client_data = client_data; 125 t->client_data = client_data;
111 126
112 BLOCK_ATIMERS; 127 block_atimers ();
113 128
114 /* Compute the timer's expiration time. */ 129 /* Compute the timer's expiration time. */
115 switch (type) 130 switch (type)
@@ -130,7 +145,7 @@ start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn,
130 145
131 /* Insert the timer in the list of active atimers. */ 146 /* Insert the timer in the list of active atimers. */
132 schedule_atimer (t); 147 schedule_atimer (t);
133 UNBLOCK_ATIMERS; 148 unblock_atimers ();
134 149
135 /* Arrange for a SIGALRM at the time the next atimer is ripe. */ 150 /* Arrange for a SIGALRM at the time the next atimer is ripe. */
136 set_alarm (); 151 set_alarm ();
@@ -146,7 +161,7 @@ cancel_atimer (struct atimer *timer)
146{ 161{
147 int i; 162 int i;
148 163
149 BLOCK_ATIMERS; 164 block_atimers ();
150 165
151 for (i = 0; i < 2; ++i) 166 for (i = 0; i < 2; ++i)
152 { 167 {
@@ -173,7 +188,7 @@ cancel_atimer (struct atimer *timer)
173 } 188 }
174 } 189 }
175 190
176 UNBLOCK_ATIMERS; 191 unblock_atimers ();
177} 192}
178 193
179 194
@@ -204,7 +219,7 @@ append_atimer_lists (struct atimer *list_1, struct atimer *list_2)
204void 219void
205stop_other_atimers (struct atimer *t) 220stop_other_atimers (struct atimer *t)
206{ 221{
207 BLOCK_ATIMERS; 222 block_atimers ();
208 223
209 if (t) 224 if (t)
210 { 225 {
@@ -229,7 +244,7 @@ stop_other_atimers (struct atimer *t)
229 244
230 stopped_atimers = append_atimer_lists (atimers, stopped_atimers); 245 stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
231 atimers = t; 246 atimers = t;
232 UNBLOCK_ATIMERS; 247 unblock_atimers ();
233} 248}
234 249
235 250
@@ -244,7 +259,7 @@ run_all_atimers (void)
244 struct atimer *t = atimers; 259 struct atimer *t = atimers;
245 struct atimer *next; 260 struct atimer *next;
246 261
247 BLOCK_ATIMERS; 262 block_atimers ();
248 atimers = stopped_atimers; 263 atimers = stopped_atimers;
249 stopped_atimers = NULL; 264 stopped_atimers = NULL;
250 265
@@ -255,7 +270,7 @@ run_all_atimers (void)
255 t = next; 270 t = next;
256 } 271 }
257 272
258 UNBLOCK_ATIMERS; 273 unblock_atimers ();
259 } 274 }
260} 275}
261 276
@@ -397,9 +412,9 @@ do_pending_atimers (void)
397{ 412{
398 if (pending_atimers) 413 if (pending_atimers)
399 { 414 {
400 BLOCK_ATIMERS; 415 block_atimers ();
401 run_timers (); 416 run_timers ();
402 UNBLOCK_ATIMERS; 417 unblock_atimers ();
403 } 418 }
404} 419}
405 420
@@ -412,7 +427,9 @@ turn_on_atimers (bool on)
412{ 427{
413 if (on) 428 if (on)
414 { 429 {
415 signal (SIGALRM, deliver_alarm_signal); 430 struct sigaction action;
431 emacs_sigaction_init (&action, deliver_alarm_signal);
432 sigaction (SIGALRM, &action, 0);
416 set_alarm (); 433 set_alarm ();
417 } 434 }
418 else 435 else
@@ -423,8 +440,10 @@ turn_on_atimers (bool on)
423void 440void
424init_atimer (void) 441init_atimer (void)
425{ 442{
443 struct sigaction action;
426 free_atimers = stopped_atimers = atimers = NULL; 444 free_atimers = stopped_atimers = atimers = NULL;
427 pending_atimers = 0; 445 pending_atimers = 0;
428 /* pending_signals is initialized in init_keyboard.*/ 446 /* pending_signals is initialized in init_keyboard.*/
429 signal (SIGALRM, deliver_alarm_signal); 447 emacs_sigaction_init (&action, deliver_alarm_signal);
448 sigaction (SIGALRM, &action, 0);
430} 449}
diff --git a/src/callproc.c b/src/callproc.c
index 2e9a8950700..a92959a1559 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -19,7 +19,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 19
20 20
21#include <config.h> 21#include <config.h>
22#include <signal.h>
23#include <errno.h> 22#include <errno.h>
24#include <stdio.h> 23#include <stdio.h>
25#include <setjmp.h> 24#include <setjmp.h>
@@ -506,9 +505,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
506 505
507 if (fd_output >= 0) 506 if (fd_output >= 0)
508 fd1 = fd_output; 507 fd1 = fd_output;
509#if 0 /* Some systems don't have sigblock. */
510 mask = sigblock (sigmask (SIGCHLD));
511#endif
512 508
513 /* Record that we're about to create a synchronous process. */ 509 /* Record that we're about to create a synchronous process. */
514 synch_process_alive = 1; 510 synch_process_alive = 1;
diff --git a/src/conf_post.h b/src/conf_post.h
index cef55863752..1bf40af260b 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -40,11 +40,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
40#endif 40#endif
41#endif 41#endif
42 42
43#ifdef SIGNAL_H_AHB
44#undef SIGNAL_H_AHB
45#include <signal.h>
46#endif
47
48/* This silences a few compilation warnings on FreeBSD. */ 43/* This silences a few compilation warnings on FreeBSD. */
49#ifdef BSD_SYSTEM_AHB 44#ifdef BSD_SYSTEM_AHB
50#undef BSD_SYSTEM_AHB 45#undef BSD_SYSTEM_AHB
diff --git a/src/data.c b/src/data.c
index 6151d815b29..5fbf43e424e 100644
--- a/src/data.c
+++ b/src/data.c
@@ -19,7 +19,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 19
20 20
21#include <config.h> 21#include <config.h>
22#include <signal.h>
23#include <stdio.h> 22#include <stdio.h>
24#include <setjmp.h> 23#include <setjmp.h>
25 24
@@ -3210,7 +3209,7 @@ syms_of_data (void)
3210static _Noreturn void 3209static _Noreturn void
3211handle_arith_signal (int sig) 3210handle_arith_signal (int sig)
3212{ 3211{
3213 sigsetmask (SIGEMPTYMASK); 3212 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
3214 xsignal0 (Qarith_error); 3213 xsignal0 (Qarith_error);
3215} 3214}
3216 3215
@@ -3223,6 +3222,7 @@ deliver_arith_signal (int sig)
3223void 3222void
3224init_data (void) 3223init_data (void)
3225{ 3224{
3225 struct sigaction action;
3226 /* Don't do this if just dumping out. 3226 /* Don't do this if just dumping out.
3227 We don't want to call `signal' in this case 3227 We don't want to call `signal' in this case
3228 so that we don't have trouble with dumping 3228 so that we don't have trouble with dumping
@@ -3231,5 +3231,6 @@ init_data (void)
3231 if (!initialized) 3231 if (!initialized)
3232 return; 3232 return;
3233#endif /* CANNOT_DUMP */ 3233#endif /* CANNOT_DUMP */
3234 signal (SIGFPE, deliver_arith_signal); 3234 emacs_sigaction_init (&action, deliver_arith_signal);
3235 sigaction (SIGFPE, &action, 0);
3235} 3236}
diff --git a/src/dispnew.c b/src/dispnew.c
index e02b33000d8..85b3254aae3 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -21,7 +21,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#define DISPEXTERN_INLINE EXTERN_INLINE 22#define DISPEXTERN_INLINE EXTERN_INLINE
23 23
24#include <signal.h>
25#include <stdio.h> 24#include <stdio.h>
26#include <setjmp.h> 25#include <setjmp.h>
27#include <unistd.h> 26#include <unistd.h>
@@ -5560,7 +5559,9 @@ handle_window_change_signal (int sig)
5560 int width, height; 5559 int width, height;
5561 struct tty_display_info *tty; 5560 struct tty_display_info *tty;
5562 5561
5563 signal (SIGWINCH, deliver_window_change_signal); 5562 struct sigaction action;
5563 emacs_sigaction_init (&action, deliver_window_change_signal);
5564 sigaction (SIGWINCH, &action, 0);
5564 5565
5565 /* The frame size change obviously applies to a single 5566 /* The frame size change obviously applies to a single
5566 termcap-controlled terminal, but we can't decide which. 5567 termcap-controlled terminal, but we can't decide which.
@@ -6175,7 +6176,11 @@ init_display (void)
6175#ifndef CANNOT_DUMP 6176#ifndef CANNOT_DUMP
6176 if (initialized) 6177 if (initialized)
6177#endif /* CANNOT_DUMP */ 6178#endif /* CANNOT_DUMP */
6178 signal (SIGWINCH, deliver_window_change_signal); 6179 {
6180 struct sigaction action;
6181 emacs_sigaction_init (&action, deliver_window_change_signal);
6182 sigaction (SIGWINCH, &action, 0);
6183 }
6179#endif /* SIGWINCH */ 6184#endif /* SIGWINCH */
6180 6185
6181 /* If running as a daemon, no need to initialize any frames/terminal. */ 6186 /* If running as a daemon, no need to initialize any frames/terminal. */
diff --git a/src/emacs.c b/src/emacs.c
index fc92b30af26..ff50f409d5c 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21 21
22#include <config.h> 22#include <config.h>
23#include <signal.h>
24#include <errno.h> 23#include <errno.h>
25#include <stdio.h> 24#include <stdio.h>
26 25
@@ -322,7 +321,12 @@ fatal_error_backtrace (int sig, int backtrace_limit)
322 going to send is probably blocked, so we have to unblock it if we 321 going to send is probably blocked, so we have to unblock it if we
323 want to really receive it. */ 322 want to really receive it. */
324#ifndef MSDOS 323#ifndef MSDOS
325 sigunblock (sigmask (fatal_error_code)); 324 {
325 sigset_t unblocked;
326 sigemptyset (&unblocked);
327 sigaddset (&unblocked, fatal_error_code);
328 pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
329 }
326#endif 330#endif
327 331
328 kill (getpid (), fatal_error_code); 332 kill (getpid (), fatal_error_code);
@@ -339,7 +343,10 @@ static void deliver_danger_signal (int);
339static void 343static void
340handle_danger_signal (int sig) 344handle_danger_signal (int sig)
341{ 345{
342 signal (sig, deliver_danger_signal); 346 struct sigaction action;
347 emacs_sigaction_init (&action, deliver_danger_signal);
348 sigaction (sig, &action, 0);
349
343 malloc_warning ("Operating system warns that virtual memory is running low.\n"); 350 malloc_warning ("Operating system warns that virtual memory is running low.\n");
344 351
345 /* It might be unsafe to call do_auto_save now. */ 352 /* It might be unsafe to call do_auto_save now. */
@@ -683,6 +690,7 @@ main (int argc, char **argv)
683 char dname_arg2[80]; 690 char dname_arg2[80];
684#endif 691#endif
685 char *ch_to_dir; 692 char *ch_to_dir;
693 struct sigaction fatal_error_action;
686 694
687#if GC_MARK_STACK 695#if GC_MARK_STACK
688 stack_base = &dummy; 696 stack_base = &dummy;
@@ -1103,6 +1111,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1103 } 1111 }
1104 1112
1105 init_signals (); 1113 init_signals ();
1114 emacs_sigaction_init (&fatal_error_action, deliver_fatal_signal);
1106 1115
1107 /* Don't catch SIGHUP if dumping. */ 1116 /* Don't catch SIGHUP if dumping. */
1108 if (1 1117 if (1
@@ -1111,13 +1120,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1111#endif 1120#endif
1112 ) 1121 )
1113 { 1122 {
1114 sigblock (sigmask (SIGHUP));
1115 /* In --batch mode, don't catch SIGHUP if already ignored. 1123 /* In --batch mode, don't catch SIGHUP if already ignored.
1116 That makes nohup work. */ 1124 That makes nohup work. */
1117 if (! noninteractive 1125 bool catch_SIGHUP = !noninteractive;
1118 || signal (SIGHUP, SIG_IGN) != SIG_IGN) 1126 if (!catch_SIGHUP)
1119 signal (SIGHUP, deliver_fatal_signal); 1127 {
1120 sigunblock (sigmask (SIGHUP)); 1128 struct sigaction old_action;
1129 sigaction (SIGHUP, 0, &old_action);
1130 catch_SIGHUP = old_action.sa_handler != SIG_IGN;
1131 }
1132 if (catch_SIGHUP)
1133 sigaction (SIGHUP, &fatal_error_action, 0);
1121 } 1134 }
1122 1135
1123 if ( 1136 if (
@@ -1141,68 +1154,73 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1141 add_user_signal (SIGUSR2, "sigusr2"); 1154 add_user_signal (SIGUSR2, "sigusr2");
1142#endif 1155#endif
1143#ifdef SIGABRT 1156#ifdef SIGABRT
1144 signal (SIGABRT, deliver_fatal_signal); 1157 sigaction (SIGABRT, &fatal_error_action, 0);
1145#endif 1158#endif
1146#ifdef SIGHWE 1159#ifdef SIGHWE
1147 signal (SIGHWE, deliver_fatal_signal); 1160 sigaction (SIGHWE, &fatal_error_action, 0);
1148#endif 1161#endif
1149#ifdef SIGPRE 1162#ifdef SIGPRE
1150 signal (SIGPRE, deliver_fatal_signal); 1163 sigaction (SIGPRE, &fatal_error_action, 0);
1151#endif 1164#endif
1152#ifdef SIGORE 1165#ifdef SIGORE
1153 signal (SIGORE, deliver_fatal_signal); 1166 sigaction (SIGORE, &fatal_error_action, 0);
1154#endif 1167#endif
1155#ifdef SIGUME 1168#ifdef SIGUME
1156 signal (SIGUME, deliver_fatal_signal); 1169 sigaction (SIGUME, &fatal_error_action, 0);
1157#endif 1170#endif
1158#ifdef SIGDLK 1171#ifdef SIGDLK
1159 signal (SIGDLK, deliver_fatal_signal); 1172 sigaction (SIGDLK, &fatal_error_action, 0);
1160#endif 1173#endif
1161#ifdef SIGCPULIM 1174#ifdef SIGCPULIM
1162 signal (SIGCPULIM, deliver_fatal_signal); 1175 sigaction (SIGCPULIM, &fatal_error_action, 0);
1163#endif 1176#endif
1164#ifdef SIGIOT 1177#ifdef SIGIOT
1165 /* This is missing on some systems - OS/2, for example. */ 1178 /* This is missing on some systems - OS/2, for example. */
1166 signal (SIGIOT, deliver_fatal_signal); 1179 sigaction (SIGIOT, &fatal_error_action, 0);
1167#endif 1180#endif
1168#ifdef SIGEMT 1181#ifdef SIGEMT
1169 signal (SIGEMT, deliver_fatal_signal); 1182 sigaction (SIGEMT, &fatal_error_action, 0);
1170#endif 1183#endif
1171 signal (SIGFPE, deliver_fatal_signal); 1184 sigaction (SIGFPE, &fatal_error_action, 0);
1172#ifdef SIGBUS 1185#ifdef SIGBUS
1173 signal (SIGBUS, deliver_fatal_signal); 1186 sigaction (SIGBUS, &fatal_error_action, 0);
1174#endif 1187#endif
1175 signal (SIGSEGV, deliver_fatal_signal); 1188 sigaction (SIGSEGV, &fatal_error_action, 0);
1176#ifdef SIGSYS 1189#ifdef SIGSYS
1177 signal (SIGSYS, deliver_fatal_signal); 1190 sigaction (SIGSYS, &fatal_error_action, 0);
1178#endif 1191#endif
1179 /* May need special treatment on MS-Windows. See 1192 /* May need special treatment on MS-Windows. See
1180 http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html 1193 http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html
1181 Please update the doc of kill-emacs, kill-emacs-hook, and 1194 Please update the doc of kill-emacs, kill-emacs-hook, and
1182 NEWS if you change this. 1195 NEWS if you change this.
1183 */ 1196 */
1184 if (noninteractive) signal (SIGINT, deliver_fatal_signal); 1197 if (noninteractive)
1185 signal (SIGTERM, deliver_fatal_signal); 1198 sigaction (SIGINT, &fatal_error_action, 0);
1199 sigaction (SIGTERM, &fatal_error_action, 0);
1186#ifdef SIGXCPU 1200#ifdef SIGXCPU
1187 signal (SIGXCPU, deliver_fatal_signal); 1201 sigaction (SIGXCPU, &fatal_error_action, 0);
1188#endif 1202#endif
1189#ifdef SIGXFSZ 1203#ifdef SIGXFSZ
1190 signal (SIGXFSZ, deliver_fatal_signal); 1204 sigaction (SIGXFSZ, &fatal_error_action, 0);
1191#endif /* SIGXFSZ */ 1205#endif /* SIGXFSZ */
1192 1206
1193#ifdef SIGDANGER 1207#ifdef SIGDANGER
1194 /* This just means available memory is getting low. */ 1208 /* This just means available memory is getting low. */
1195 signal (SIGDANGER, deliver_danger_signal); 1209 {
1210 struct sigaction action;
1211 emacs_sigaction_init (&action, deliver_danger_signal);
1212 sigaction (SIGDANGER, &action, 0);
1213 }
1196#endif 1214#endif
1197 1215
1198#ifdef AIX 1216#ifdef AIX
1199/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */ 1217/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
1200 signal (SIGXCPU, deliver_fatal_signal); 1218 sigaction (SIGXCPU, &fatal_error_action, 0);
1201 signal (SIGIOINT, deliver_fatal_signal); 1219 sigaction (SIGIOINT, &fatal_error_action, 0);
1202 signal (SIGGRANT, deliver_fatal_signal); 1220 sigaction (SIGGRANT, &fatal_error_action, 0);
1203 signal (SIGRETRACT, deliver_fatal_signal); 1221 sigaction (SIGRETRACT, &fatal_error_action, 0);
1204 signal (SIGSOUND, deliver_fatal_signal); 1222 sigaction (SIGSOUND, &fatal_error_action, 0);
1205 signal (SIGMSG, deliver_fatal_signal); 1223 sigaction (SIGMSG, &fatal_error_action, 0);
1206#endif /* AIX */ 1224#endif /* AIX */
1207 } 1225 }
1208 1226
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index 1a62b59b7af..940482654b3 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -21,7 +21,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21#include <config.h> 21#include <config.h>
22 22
23#include "emacsgtkfixed.h" 23#include "emacsgtkfixed.h"
24#include <signal.h>
25#include <stdio.h> 24#include <stdio.h>
26#include <setjmp.h> 25#include <setjmp.h>
27#include "lisp.h" 26#include "lisp.h"
diff --git a/src/floatfns.c b/src/floatfns.c
index f59cf58228a..e956dc22353 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -45,7 +45,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
45 */ 45 */
46 46
47#include <config.h> 47#include <config.h>
48#include <signal.h>
49#include <setjmp.h> 48#include <setjmp.h>
50#include "lisp.h" 49#include "lisp.h"
51#include "syssignal.h" 50#include "syssignal.h"
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 3bce5be9cd0..884574e1062 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -21,7 +21,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#ifdef USE_GTK 22#ifdef USE_GTK
23#include <float.h> 23#include <float.h>
24#include <signal.h>
25#include <stdio.h> 24#include <stdio.h>
26#include <setjmp.h> 25#include <setjmp.h>
27 26
@@ -1979,7 +1978,10 @@ xg_get_file_name (FRAME_PTR f,
1979 /* I really don't know why this is needed, but without this the GLIBC add on 1978 /* I really don't know why this is needed, but without this the GLIBC add on
1980 library linuxthreads hangs when the Gnome file chooser backend creates 1979 library linuxthreads hangs when the Gnome file chooser backend creates
1981 threads. */ 1980 threads. */
1982 sigblock (sigmask (__SIGRTMIN)); 1981 sigset_t blocked;
1982 sigemptyset (&blocked);
1983 sigaddset (&blocked, __SIGRTMIN);
1984 pthread_sigmask (SIG_BLOCK, &blocked, 0);
1983#endif /* HAVE_PTHREAD */ 1985#endif /* HAVE_PTHREAD */
1984 1986
1985#ifdef HAVE_GTK_FILE_SELECTION_NEW 1987#ifdef HAVE_GTK_FILE_SELECTION_NEW
@@ -2001,7 +2003,7 @@ xg_get_file_name (FRAME_PTR f,
2001 filesel_done = xg_dialog_run (f, w); 2003 filesel_done = xg_dialog_run (f, w);
2002 2004
2003#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN) 2005#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
2004 sigunblock (sigmask (__SIGRTMIN)); 2006 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
2005#endif 2007#endif
2006 2008
2007 if (filesel_done == GTK_RESPONSE_OK) 2009 if (filesel_done == GTK_RESPONSE_OK)
@@ -2057,7 +2059,10 @@ xg_get_font (FRAME_PTR f, const char *default_name)
2057 Lisp_Object font = Qnil; 2059 Lisp_Object font = Qnil;
2058 2060
2059#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN) 2061#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
2060 sigblock (sigmask (__SIGRTMIN)); 2062 sigset_t blocked;
2063 sigemptyset (&blocked);
2064 sigaddset (&blocked, __SIGRTMIN);
2065 pthread_sigmask (SIG_BLOCK, &blocked, 0);
2061#endif /* HAVE_PTHREAD */ 2066#endif /* HAVE_PTHREAD */
2062 2067
2063 w = gtk_font_chooser_dialog_new 2068 w = gtk_font_chooser_dialog_new
@@ -2086,7 +2091,7 @@ xg_get_font (FRAME_PTR f, const char *default_name)
2086 done = xg_dialog_run (f, w); 2091 done = xg_dialog_run (f, w);
2087 2092
2088#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN) 2093#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
2089 sigunblock (sigmask (__SIGRTMIN)); 2094 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
2090#endif 2095#endif
2091 2096
2092 if (done == GTK_RESPONSE_OK) 2097 if (done == GTK_RESPONSE_OK)
diff --git a/src/keyboard.c b/src/keyboard.c
index 128f9280911..d26cf35e108 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -21,7 +21,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 21
22#define KEYBOARD_INLINE EXTERN_INLINE 22#define KEYBOARD_INLINE EXTERN_INLINE
23 23
24#include <signal.h>
25#include <stdio.h> 24#include <stdio.h>
26#include <setjmp.h> 25#include <setjmp.h>
27#include "lisp.h" 26#include "lisp.h"
@@ -3680,7 +3679,7 @@ kbd_buffer_store_event_hold (register struct input_event *event,
3680 if (immediate_quit && NILP (Vinhibit_quit)) 3679 if (immediate_quit && NILP (Vinhibit_quit))
3681 { 3680 {
3682 immediate_quit = 0; 3681 immediate_quit = 0;
3683 sigfree (); 3682 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
3684 QUIT; 3683 QUIT;
3685 } 3684 }
3686 } 3685 }
@@ -3832,7 +3831,11 @@ kbd_buffer_get_event (KBOARD **kbp,
3832 unhold_keyboard_input (); 3831 unhold_keyboard_input ();
3833#ifdef SIGIO 3832#ifdef SIGIO
3834 if (!noninteractive) 3833 if (!noninteractive)
3835 signal (SIGIO, deliver_input_available_signal); 3834 {
3835 struct sigaction action;
3836 emacs_sigaction_init (&action, deliver_input_available_signal);
3837 sigaction (SIGIO, &action, 0);
3838 }
3836#endif /* SIGIO */ 3839#endif /* SIGIO */
3837 start_polling (); 3840 start_polling ();
3838 } 3841 }
@@ -6780,10 +6783,12 @@ gobble_input (int expected)
6780#ifdef SIGIO 6783#ifdef SIGIO
6781 if (interrupt_input) 6784 if (interrupt_input)
6782 { 6785 {
6783 SIGMASKTYPE mask; 6786 sigset_t blocked, procmask;
6784 mask = sigblock (sigmask (SIGIO)); 6787 sigemptyset (&blocked);
6788 sigaddset (&blocked, SIGIO);
6789 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
6785 read_avail_input (expected); 6790 read_avail_input (expected);
6786 sigsetmask (mask); 6791 pthread_sigmask (SIG_SETMASK, &procmask, 0);
6787 } 6792 }
6788 else 6793 else
6789#ifdef POLL_FOR_INPUT 6794#ifdef POLL_FOR_INPUT
@@ -6792,10 +6797,12 @@ gobble_input (int expected)
6792 it's always set. */ 6797 it's always set. */
6793 if (!interrupt_input && poll_suppress_count == 0) 6798 if (!interrupt_input && poll_suppress_count == 0)
6794 { 6799 {
6795 SIGMASKTYPE mask; 6800 sigset_t blocked, procmask;
6796 mask = sigblock (sigmask (SIGALRM)); 6801 sigemptyset (&blocked);
6802 sigaddset (&blocked, SIGALRM);
6803 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
6797 read_avail_input (expected); 6804 read_avail_input (expected);
6798 sigsetmask (mask); 6805 pthread_sigmask (SIG_SETMASK, &procmask, 0);
6799 } 6806 }
6800 else 6807 else
6801#endif 6808#endif
@@ -6831,10 +6838,12 @@ record_asynch_buffer_change (void)
6831#ifdef SIGIO 6838#ifdef SIGIO
6832 if (interrupt_input) 6839 if (interrupt_input)
6833 { 6840 {
6834 SIGMASKTYPE mask; 6841 sigset_t blocked, procmask;
6835 mask = sigblock (sigmask (SIGIO)); 6842 sigemptyset (&blocked);
6843 sigaddset (&blocked, SIGIO);
6844 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
6836 kbd_buffer_store_event (&event); 6845 kbd_buffer_store_event (&event);
6837 sigsetmask (mask); 6846 pthread_sigmask (SIG_SETMASK, &procmask, 0);
6838 } 6847 }
6839 else 6848 else
6840#endif 6849#endif
@@ -7295,6 +7304,7 @@ static struct user_signal_info *user_signals = NULL;
7295void 7304void
7296add_user_signal (int sig, const char *name) 7305add_user_signal (int sig, const char *name)
7297{ 7306{
7307 struct sigaction action;
7298 struct user_signal_info *p; 7308 struct user_signal_info *p;
7299 7309
7300 for (p = user_signals; p; p = p->next) 7310 for (p = user_signals; p; p = p->next)
@@ -7309,7 +7319,8 @@ add_user_signal (int sig, const char *name)
7309 p->next = user_signals; 7319 p->next = user_signals;
7310 user_signals = p; 7320 user_signals = p;
7311 7321
7312 signal (sig, deliver_user_signal); 7322 emacs_sigaction_init (&action, deliver_user_signal);
7323 sigaction (sig, &action, 0);
7313} 7324}
7314 7325
7315static void 7326static void
@@ -7381,7 +7392,7 @@ store_user_signal_events (void)
7381 for (p = user_signals; p; p = p->next) 7392 for (p = user_signals; p; p = p->next)
7382 if (p->npending > 0) 7393 if (p->npending > 0)
7383 { 7394 {
7384 SIGMASKTYPE mask; 7395 sigset_t blocked, procmask;
7385 7396
7386 if (nstored == 0) 7397 if (nstored == 0)
7387 { 7398 {
@@ -7391,7 +7402,10 @@ store_user_signal_events (void)
7391 } 7402 }
7392 nstored += p->npending; 7403 nstored += p->npending;
7393 7404
7394 mask = sigblock (sigmask (p->sig)); 7405 sigemptyset (&blocked);
7406 sigaddset (&blocked, p->sig);
7407 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
7408
7395 do 7409 do
7396 { 7410 {
7397 buf.code = p->sig; 7411 buf.code = p->sig;
@@ -7399,7 +7413,8 @@ store_user_signal_events (void)
7399 p->npending--; 7413 p->npending--;
7400 } 7414 }
7401 while (p->npending > 0); 7415 while (p->npending > 0);
7402 sigsetmask (mask); 7416
7417 pthread_sigmask (SIG_SETMASK, &procmask, 0);
7403 } 7418 }
7404 7419
7405 return nstored; 7420 return nstored;
@@ -10838,7 +10853,10 @@ handle_interrupt (void)
10838 /* If SIGINT isn't blocked, don't let us be interrupted by 10853 /* If SIGINT isn't blocked, don't let us be interrupted by
10839 another SIGINT, it might be harmful due to non-reentrancy 10854 another SIGINT, it might be harmful due to non-reentrancy
10840 in I/O functions. */ 10855 in I/O functions. */
10841 sigblock (sigmask (SIGINT)); 10856 sigset_t blocked;
10857 sigemptyset (&blocked);
10858 sigaddset (&blocked, SIGINT);
10859 pthread_sigmask (SIG_BLOCK, &blocked, 0);
10842 10860
10843 fflush (stdout); 10861 fflush (stdout);
10844 reset_all_sys_modes (); 10862 reset_all_sys_modes ();
@@ -10909,7 +10927,7 @@ handle_interrupt (void)
10909#endif /* not MSDOS */ 10927#endif /* not MSDOS */
10910 fflush (stdout); 10928 fflush (stdout);
10911 init_all_sys_modes (); 10929 init_all_sys_modes ();
10912 sigfree (); 10930 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
10913 } 10931 }
10914 else 10932 else
10915 { 10933 {
@@ -10922,7 +10940,7 @@ handle_interrupt (void)
10922 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 10940 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
10923 10941
10924 immediate_quit = 0; 10942 immediate_quit = 0;
10925 sigfree (); 10943 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
10926 saved = gl_state; 10944 saved = gl_state;
10927 GCPRO4 (saved.object, saved.global_code, 10945 GCPRO4 (saved.object, saved.global_code,
10928 saved.current_syntax_table, saved.old_prop); 10946 saved.current_syntax_table, saved.old_prop);
@@ -10967,7 +10985,7 @@ quit_throw_to_read_char (int from_signal)
10967 if (!from_signal && EQ (Vquit_flag, Qkill_emacs)) 10985 if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
10968 Fkill_emacs (Qnil); 10986 Fkill_emacs (Qnil);
10969 10987
10970 sigfree (); 10988 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
10971 /* Prevent another signal from doing this before we finish. */ 10989 /* Prevent another signal from doing this before we finish. */
10972 clear_waiting_for_input (); 10990 clear_waiting_for_input ();
10973 input_pending = 0; 10991 input_pending = 0;
@@ -11402,17 +11420,23 @@ init_keyboard (void)
11402 SIGINT. There is special code in interrupt_signal to exit 11420 SIGINT. There is special code in interrupt_signal to exit
11403 Emacs on SIGINT when there are no termcap frames on the 11421 Emacs on SIGINT when there are no termcap frames on the
11404 controlling terminal. */ 11422 controlling terminal. */
11405 signal (SIGINT, deliver_interrupt_signal); 11423 struct sigaction action;
11424 emacs_sigaction_init (&action, deliver_interrupt_signal);
11425 sigaction (SIGINT, &action, 0);
11406#ifndef DOS_NT 11426#ifndef DOS_NT
11407 /* For systems with SysV TERMIO, C-g is set up for both SIGINT and 11427 /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
11408 SIGQUIT and we can't tell which one it will give us. */ 11428 SIGQUIT and we can't tell which one it will give us. */
11409 signal (SIGQUIT, deliver_interrupt_signal); 11429 sigaction (SIGQUIT, &action, 0);
11410#endif /* not DOS_NT */ 11430#endif /* not DOS_NT */
11411 } 11431 }
11412/* Note SIGIO has been undef'd if FIONREAD is missing. */ 11432/* Note SIGIO has been undef'd if FIONREAD is missing. */
11413#ifdef SIGIO 11433#ifdef SIGIO
11414 if (!noninteractive) 11434 if (!noninteractive)
11415 signal (SIGIO, deliver_input_available_signal); 11435 {
11436 struct sigaction action;
11437 emacs_sigaction_init (&action, deliver_input_available_signal);
11438 sigaction (SIGIO, &action, 0);
11439 }
11416#endif /* SIGIO */ 11440#endif /* SIGIO */
11417 11441
11418/* Use interrupt input by default, if it works and noninterrupt input 11442/* Use interrupt input by default, if it works and noninterrupt input
@@ -11424,7 +11448,7 @@ init_keyboard (void)
11424 interrupt_input = 0; 11448 interrupt_input = 0;
11425#endif 11449#endif
11426 11450
11427 sigfree (); 11451 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
11428 dribble = 0; 11452 dribble = 0;
11429 11453
11430 if (keyboard_init_hook) 11454 if (keyboard_init_hook)
diff --git a/src/nsfns.m b/src/nsfns.m
index e8b5d22077a..f73086eeee9 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -30,7 +30,6 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
30 interpretation of even the system includes. */ 30 interpretation of even the system includes. */
31#include <config.h> 31#include <config.h>
32 32
33#include <signal.h>
34#include <math.h> 33#include <math.h>
35#include <setjmp.h> 34#include <setjmp.h>
36#include <c-strcase.h> 35#include <c-strcase.h>
diff --git a/src/process.c b/src/process.c
index 9ab8d2720b2..0cc9bc353a1 100644
--- a/src/process.c
+++ b/src/process.c
@@ -23,7 +23,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23 23
24#define PROCESS_INLINE EXTERN_INLINE 24#define PROCESS_INLINE EXTERN_INLINE
25 25
26#include <signal.h>
27#include <stdio.h> 26#include <stdio.h>
28#include <errno.h> 27#include <errno.h>
29#include <setjmp.h> 28#include <setjmp.h>
@@ -1612,8 +1611,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1612#if !defined (WINDOWSNT) && defined (FD_CLOEXEC) 1611#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
1613 int wait_child_setup[2]; 1612 int wait_child_setup[2];
1614#endif 1613#endif
1615 sigset_t procmask; 1614 sigset_t blocked, procmask;
1616 sigset_t blocked;
1617 struct sigaction sigint_action; 1615 struct sigaction sigint_action;
1618 struct sigaction sigquit_action; 1616 struct sigaction sigquit_action;
1619 struct sigaction sigpipe_action; 1617 struct sigaction sigpipe_action;
@@ -1765,12 +1763,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1765 int xforkin = forkin; 1763 int xforkin = forkin;
1766 int xforkout = forkout; 1764 int xforkout = forkout;
1767 1765
1768#if 0 /* This was probably a mistake--it duplicates code later on,
1769 but fails to handle all the cases. */
1770 /* Make sure SIGCHLD is not blocked in the child. */
1771 sigsetmask (SIGEMPTYMASK);
1772#endif
1773
1774 /* Make the pty be the controlling terminal of the process. */ 1766 /* Make the pty be the controlling terminal of the process. */
1775#ifdef HAVE_PTYS 1767#ifdef HAVE_PTYS
1776 /* First, disconnect its current controlling terminal. */ 1768 /* First, disconnect its current controlling terminal. */
@@ -5434,7 +5426,10 @@ static Lisp_Object process_sent_to;
5434static _Noreturn void 5426static _Noreturn void
5435handle_pipe_signal (int sig) 5427handle_pipe_signal (int sig)
5436{ 5428{
5437 sigunblock (sigmask (SIGPIPE)); 5429 sigset_t unblocked;
5430 sigemptyset (&unblocked);
5431 sigaddset (&unblocked, SIGPIPE);
5432 pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
5438 _longjmp (send_process_frame, 1); 5433 _longjmp (send_process_frame, 1);
5439} 5434}
5440 5435
@@ -5534,7 +5529,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5534 struct Lisp_Process *p = XPROCESS (proc); 5529 struct Lisp_Process *p = XPROCESS (proc);
5535 ssize_t rv; 5530 ssize_t rv;
5536 struct coding_system *coding; 5531 struct coding_system *coding;
5537 void (*volatile old_sigpipe) (int); 5532 struct sigaction old_sigpipe_action;
5538 5533
5539 if (p->raw_status_new) 5534 if (p->raw_status_new)
5540 update_status (p); 5535 update_status (p);
@@ -5673,7 +5668,9 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5673 /* Send this batch, using one or more write calls. */ 5668 /* Send this batch, using one or more write calls. */
5674 ptrdiff_t written = 0; 5669 ptrdiff_t written = 0;
5675 int outfd = p->outfd; 5670 int outfd = p->outfd;
5676 old_sigpipe = signal (SIGPIPE, deliver_pipe_signal); 5671 struct sigaction action;
5672 emacs_sigaction_init (&action, deliver_pipe_signal);
5673 sigaction (SIGPIPE, &action, &old_sigpipe_action);
5677#ifdef DATAGRAM_SOCKETS 5674#ifdef DATAGRAM_SOCKETS
5678 if (DATAGRAM_CHAN_P (outfd)) 5675 if (DATAGRAM_CHAN_P (outfd))
5679 { 5676 {
@@ -5684,7 +5681,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5684 written = rv; 5681 written = rv;
5685 else if (errno == EMSGSIZE) 5682 else if (errno == EMSGSIZE)
5686 { 5683 {
5687 signal (SIGPIPE, old_sigpipe); 5684 sigaction (SIGPIPE, &old_sigpipe_action, 0);
5688 report_file_error ("sending datagram", 5685 report_file_error ("sending datagram",
5689 Fcons (proc, Qnil)); 5686 Fcons (proc, Qnil));
5690 } 5687 }
@@ -5709,7 +5706,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5709 } 5706 }
5710#endif 5707#endif
5711 } 5708 }
5712 signal (SIGPIPE, old_sigpipe); 5709 sigaction (SIGPIPE, &old_sigpipe_action, 0);
5713 5710
5714 if (rv < 0) 5711 if (rv < 0)
5715 { 5712 {
@@ -5769,7 +5766,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5769 } 5766 }
5770 else 5767 else
5771 { 5768 {
5772 signal (SIGPIPE, old_sigpipe); 5769 sigaction (SIGPIPE, &old_sigpipe_action, 0);
5773 proc = process_sent_to; 5770 proc = process_sent_to;
5774 p = XPROCESS (proc); 5771 p = XPROCESS (proc);
5775 p->raw_status_new = 0; 5772 p->raw_status_new = 0;
@@ -7389,7 +7386,11 @@ init_process_emacs (void)
7389#ifndef CANNOT_DUMP 7386#ifndef CANNOT_DUMP
7390 if (! noninteractive || initialized) 7387 if (! noninteractive || initialized)
7391#endif 7388#endif
7392 signal (SIGCHLD, deliver_child_signal); 7389 {
7390 struct sigaction action;
7391 emacs_sigaction_init (&action, deliver_child_signal);
7392 sigaction (SIGCHLD, &action, 0);
7393 }
7393#endif 7394#endif
7394 7395
7395 FD_ZERO (&input_wait_mask); 7396 FD_ZERO (&input_wait_mask);
diff --git a/src/sound.c b/src/sound.c
index d20fa5ee8eb..5729d704b6a 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -48,7 +48,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
48#include "lisp.h" 48#include "lisp.h"
49#include "dispextern.h" 49#include "dispextern.h"
50#include "atimer.h" 50#include "atimer.h"
51#include <signal.h>
52#include "syssignal.h" 51#include "syssignal.h"
53/* END: Common Includes */ 52/* END: Common Includes */
54 53
@@ -316,7 +315,12 @@ sound_perror (const char *msg)
316 315
317 turn_on_atimers (1); 316 turn_on_atimers (1);
318#ifdef SIGIO 317#ifdef SIGIO
319 sigunblock (sigmask (SIGIO)); 318 {
319 sigset_t unblocked;
320 sigemptyset (&unblocked);
321 sigaddset (&unblocked, SIGIO);
322 pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
323 }
320#endif 324#endif
321 if (saved_errno != 0) 325 if (saved_errno != 0)
322 error ("%s: %s", msg, strerror (saved_errno)); 326 error ("%s: %s", msg, strerror (saved_errno));
@@ -728,6 +732,9 @@ static void
728vox_configure (struct sound_device *sd) 732vox_configure (struct sound_device *sd)
729{ 733{
730 int val; 734 int val;
735#ifdef SIGIO
736 sigset_t blocked;
737#endif
731 738
732 eassert (sd->fd >= 0); 739 eassert (sd->fd >= 0);
733 740
@@ -736,7 +743,9 @@ vox_configure (struct sound_device *sd)
736 troubles. */ 743 troubles. */
737 turn_on_atimers (0); 744 turn_on_atimers (0);
738#ifdef SIGIO 745#ifdef SIGIO
739 sigblock (sigmask (SIGIO)); 746 sigemptyset (&blocked);
747 sigaddset (&blocked, SIGIO);
748 pthread_sigmask (SIG_BLOCK, &blocked, 0);
740#endif 749#endif
741 750
742 val = sd->format; 751 val = sd->format;
@@ -770,7 +779,7 @@ vox_configure (struct sound_device *sd)
770 779
771 turn_on_atimers (1); 780 turn_on_atimers (1);
772#ifdef SIGIO 781#ifdef SIGIO
773 sigunblock (sigmask (SIGIO)); 782 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
774#endif 783#endif
775} 784}
776 785
@@ -786,7 +795,10 @@ vox_close (struct sound_device *sd)
786 be interrupted by a signal. Block the ones we know to cause 795 be interrupted by a signal. Block the ones we know to cause
787 troubles. */ 796 troubles. */
788#ifdef SIGIO 797#ifdef SIGIO
789 sigblock (sigmask (SIGIO)); 798 sigset_t blocked;
799 sigemptyset (&blocked);
800 sigaddset (&blocked, SIGIO);
801 pthread_sigmask (SIG_BLOCK, &blocked, 0);
790#endif 802#endif
791 turn_on_atimers (0); 803 turn_on_atimers (0);
792 804
@@ -795,7 +807,7 @@ vox_close (struct sound_device *sd)
795 807
796 turn_on_atimers (1); 808 turn_on_atimers (1);
797#ifdef SIGIO 809#ifdef SIGIO
798 sigunblock (sigmask (SIGIO)); 810 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
799#endif 811#endif
800 812
801 /* Close the device. */ 813 /* Close the device. */
diff --git a/src/sysdep.c b/src/sysdep.c
index 42b8baf78e0..0f16d1a7645 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -22,7 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#define SYSTIME_INLINE EXTERN_INLINE 22#define SYSTIME_INLINE EXTERN_INLINE
23 23
24#include <execinfo.h> 24#include <execinfo.h>
25#include <signal.h>
26#include <stdio.h> 25#include <stdio.h>
27#include <setjmp.h> 26#include <setjmp.h>
28#ifdef HAVE_PWD_H 27#ifdef HAVE_PWD_H
@@ -303,27 +302,34 @@ wait_for_termination_1 (pid_t pid, int interruptible)
303 termination of subprocesses, perhaps involving a kernel bug too, 302 termination of subprocesses, perhaps involving a kernel bug too,
304 but no idea what it is. Just as a hunch we signal SIGCHLD to see 303 but no idea what it is. Just as a hunch we signal SIGCHLD to see
305 if that causes the problem to go away or get worse. */ 304 if that causes the problem to go away or get worse. */
306 sigsetmask (sigmask (SIGCHLD)); 305 sigset_t sigchild_mask;
306 sigemptyset (&sigchild_mask);
307 sigaddset (&sigchild_mask, SIGCHLD);
308 pthread_sigmask (SIG_SETMASK, &sigchild_mask, 0);
309
307 if (0 > kill (pid, 0)) 310 if (0 > kill (pid, 0))
308 { 311 {
309 sigsetmask (SIGEMPTYMASK); 312 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
310 kill (getpid (), SIGCHLD); 313 kill (getpid (), SIGCHLD);
311 break; 314 break;
312 } 315 }
313 if (wait_debugging) 316 if (wait_debugging)
314 sleep (1); 317 sleep (1);
315 else 318 else
316 sigpause (SIGEMPTYMASK); 319 sigsuspend (&empty_mask);
317#else /* not BSD_SYSTEM, and not HPUX version >= 6 */ 320#else /* not BSD_SYSTEM, and not HPUX version >= 6 */
318#ifdef WINDOWSNT 321#ifdef WINDOWSNT
319 wait (0); 322 wait (0);
320 break; 323 break;
321#else /* not WINDOWSNT */ 324#else /* not WINDOWSNT */
322 sigblock (sigmask (SIGCHLD)); 325 sigset_t blocked;
326 sigemptyset (&blocked);
327 sigaddset (&blocked, SIGCHLD);
328 pthread_sigmask (SIG_BLOCK, &blocked, 0);
323 errno = 0; 329 errno = 0;
324 if (kill (pid, 0) == -1 && errno == ESRCH) 330 if (kill (pid, 0) == -1 && errno == ESRCH)
325 { 331 {
326 sigunblock (sigmask (SIGCHLD)); 332 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
327 break; 333 break;
328 } 334 }
329 335
@@ -457,11 +463,11 @@ child_setup_tty (int out)
457#endif /* not MSDOS */ 463#endif /* not MSDOS */
458 464
459 465
460/* Record a signal code and the handler for it. */ 466/* Record a signal code and the action for it. */
461struct save_signal 467struct save_signal
462{ 468{
463 int code; 469 int code;
464 void (*handler) (int); 470 struct sigaction action;
465}; 471};
466 472
467static void save_signal_handlers (struct save_signal *); 473static void save_signal_handlers (struct save_signal *);
@@ -619,8 +625,9 @@ save_signal_handlers (struct save_signal *saved_handlers)
619{ 625{
620 while (saved_handlers->code) 626 while (saved_handlers->code)
621 { 627 {
622 saved_handlers->handler 628 struct sigaction action;
623 = (void (*) (int)) signal (saved_handlers->code, SIG_IGN); 629 emacs_sigaction_init (&action, SIG_IGN);
630 sigaction (saved_handlers->code, &action, &saved_handlers->action);
624 saved_handlers++; 631 saved_handlers++;
625 } 632 }
626} 633}
@@ -630,7 +637,7 @@ restore_signal_handlers (struct save_signal *saved_handlers)
630{ 637{
631 while (saved_handlers->code) 638 while (saved_handlers->code)
632 { 639 {
633 signal (saved_handlers->code, saved_handlers->handler); 640 sigaction (saved_handlers->code, &saved_handlers->action, 0);
634 saved_handlers++; 641 saved_handlers++;
635 } 642 }
636} 643}
@@ -687,13 +694,17 @@ reset_sigio (int fd)
687void 694void
688request_sigio (void) 695request_sigio (void)
689{ 696{
697 sigset_t unblocked;
698
690 if (noninteractive) 699 if (noninteractive)
691 return; 700 return;
692 701
702 sigemptyset (&unblocked);
693#ifdef SIGWINCH 703#ifdef SIGWINCH
694 sigunblock (sigmask (SIGWINCH)); 704 sigaddset (&unblocked, SIGWINCH);
695#endif 705#endif
696 sigunblock (sigmask (SIGIO)); 706 sigaddset (&unblocked, SIGIO);
707 pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
697 708
698 interrupts_deferred = 0; 709 interrupts_deferred = 0;
699} 710}
@@ -701,6 +712,8 @@ request_sigio (void)
701void 712void
702unrequest_sigio (void) 713unrequest_sigio (void)
703{ 714{
715 sigset_t blocked;
716
704 if (noninteractive) 717 if (noninteractive)
705 return; 718 return;
706 719
@@ -709,10 +722,12 @@ unrequest_sigio (void)
709 return; 722 return;
710#endif 723#endif
711 724
725 sigemptyset (&blocked);
712#ifdef SIGWINCH 726#ifdef SIGWINCH
713 sigblock (sigmask (SIGWINCH)); 727 sigaddset (&blocked, SIGWINCH);
714#endif 728#endif
715 sigblock (sigmask (SIGIO)); 729 sigaddset (&blocked, SIGIO);
730 pthread_sigmask (SIG_BLOCK, &blocked, 0);
716 interrupts_deferred = 1; 731 interrupts_deferred = 1;
717} 732}
718 733
@@ -1471,20 +1486,16 @@ init_system_name (void)
1471 } 1486 }
1472} 1487}
1473 1488
1474/* POSIX signals support - DJB */
1475/* Anyone with POSIX signals should have ANSI C declarations */
1476
1477sigset_t empty_mask; 1489sigset_t empty_mask;
1478 1490
1479#ifndef WINDOWSNT 1491/* Store into *ACTION a signal action suitable for Emacs, with handler
1480 1492 HANDLER. */
1481signal_handler_t 1493void
1482sys_signal (int signal_number, signal_handler_t action) 1494emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
1483{ 1495{
1484 struct sigaction new_action, old_action; 1496 sigemptyset (&action->sa_mask);
1485 sigemptyset (&new_action.sa_mask); 1497 action->sa_handler = handler;
1486 new_action.sa_handler = action; 1498 action->sa_flags = 0;
1487 new_action.sa_flags = 0;
1488#if defined (SA_RESTART) 1499#if defined (SA_RESTART)
1489 /* Emacs mostly works better with restartable system services. If this 1500 /* Emacs mostly works better with restartable system services. If this
1490 flag exists, we probably want to turn it on here. 1501 flag exists, we probably want to turn it on here.
@@ -1501,54 +1512,8 @@ sys_signal (int signal_number, signal_handler_t action)
1501# if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT) 1512# if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT)
1502 if (noninteractive) 1513 if (noninteractive)
1503# endif 1514# endif
1504 new_action.sa_flags = SA_RESTART; 1515 action->sa_flags = SA_RESTART;
1505#endif 1516#endif
1506 sigaction (signal_number, &new_action, &old_action);
1507 return (old_action.sa_handler);
1508}
1509
1510#endif /* WINDOWSNT */
1511
1512#ifndef __GNUC__
1513/* If we're compiling with GCC, we don't need this function, since it
1514 can be written as a macro. */
1515sigset_t
1516sys_sigmask (int sig)
1517{
1518 sigset_t mask;
1519 sigemptyset (&mask);
1520 sigaddset (&mask, sig);
1521 return mask;
1522}
1523#endif
1524
1525/* I'd like to have these guys return pointers to the mask storage in here,
1526 but there'd be trouble if the code was saving multiple masks. I'll be
1527 safe and pass the structure. It normally won't be more than 2 bytes
1528 anyhow. - DJB */
1529
1530sigset_t
1531sys_sigblock (sigset_t new_mask)
1532{
1533 sigset_t old_mask;
1534 pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask);
1535 return (old_mask);
1536}
1537
1538sigset_t
1539sys_sigunblock (sigset_t new_mask)
1540{
1541 sigset_t old_mask;
1542 pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask);
1543 return (old_mask);
1544}
1545
1546sigset_t
1547sys_sigsetmask (sigset_t new_mask)
1548{
1549 sigset_t old_mask;
1550 pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask);
1551 return (old_mask);
1552} 1517}
1553 1518
1554#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD 1519#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
diff --git a/src/syssignal.h b/src/syssignal.h
index 504aff43083..58290ee3fc7 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -17,6 +17,8 @@ GNU General Public License for more details.
17You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 19
20#include <signal.h>
21
20extern void init_signals (void); 22extern void init_signals (void);
21 23
22#ifdef HAVE_PTHREAD 24#ifdef HAVE_PTHREAD
@@ -26,63 +28,16 @@ extern void init_signals (void);
26#define FORWARD_SIGNAL_TO_MAIN_THREAD 28#define FORWARD_SIGNAL_TO_MAIN_THREAD
27#endif 29#endif
28 30
29/* Don't #include <signal.h>. That header should always be #included
30 before "config.h", because some configuration files (like s/hpux.h)
31 indicate that SIGIO doesn't work by #undef-ing SIGIO. If this file
32 #includes <signal.h>, then that will re-#define SIGIO and confuse
33 things. */
34/* XXX This is not correct anymore, there is a BROKEN_SIGIO macro. */
35
36#define SIGMASKTYPE sigset_t
37
38#define SIGEMPTYMASK (empty_mask)
39extern sigset_t empty_mask; 31extern sigset_t empty_mask;
40 32
41/* POSIX pretty much destroys any possibility of writing sigmask as a
42 macro in standard C. We always define our own version because the
43 predefined macro in Glibc 2.1 is only provided for compatibility for old
44 programs that use int as signal mask type. */
45#undef sigmask
46#ifdef __GNUC__
47#define sigmask(SIG) \
48 ({ \
49 sigset_t _mask; \
50 sigemptyset (&_mask); \
51 sigaddset (&_mask, SIG); \
52 _mask; \
53 })
54#else /* ! defined (__GNUC__) */
55extern sigset_t sys_sigmask ();
56#define sigmask(SIG) (sys_sigmask (SIG))
57#endif /* ! defined (__GNUC__) */
58
59#undef sigpause
60#define sigpause(MASK) sigsuspend (&(MASK))
61
62#define sigblock(SIG) sys_sigblock (SIG)
63#define sigunblock(SIG) sys_sigunblock (SIG)
64#ifndef sigsetmask
65#define sigsetmask(SIG) sys_sigsetmask (SIG)
66#endif
67#undef signal
68#define signal(SIG,ACT) sys_signal(SIG,ACT)
69
70/* Whether this is what all systems want or not, this is what
71 appears to be assumed in the source, for example data.c:arith_error. */
72typedef void (*signal_handler_t) (int); 33typedef void (*signal_handler_t) (int);
73 34
74signal_handler_t sys_signal (int signal_number, signal_handler_t action); 35extern void emacs_sigaction_init (struct sigaction *, signal_handler_t);
75sigset_t sys_sigblock (sigset_t new_mask); 36
76sigset_t sys_sigunblock (sigset_t new_mask);
77sigset_t sys_sigsetmask (sigset_t new_mask);
78#if ! (defined TIOCNOTTY || defined USG5 || defined CYGWIN) 37#if ! (defined TIOCNOTTY || defined USG5 || defined CYGWIN)
79_Noreturn void croak (char *); 38_Noreturn void croak (char *);
80#endif 39#endif
81 40
82#define sys_sigdel(MASK,SIG) sigdelset (&MASK,SIG)
83
84#define sigfree() sigsetmask (SIGEMPTYMASK)
85
86#if defined (SIGIO) && defined (BROKEN_SIGIO) 41#if defined (SIGIO) && defined (BROKEN_SIGIO)
87# undef SIGIO 42# undef SIGIO
88#endif 43#endif
@@ -97,12 +52,8 @@ _Noreturn void croak (char *);
97#undef SIGPTY 52#undef SIGPTY
98#endif 53#endif
99 54
100
101/* FIXME? Emacs only defines NSIG_MINIMUM on some platforms? */
102#if NSIG < NSIG_MINIMUM 55#if NSIG < NSIG_MINIMUM
103# ifdef NSIG 56# undef NSIG
104# undef NSIG
105# endif
106# define NSIG NSIG_MINIMUM 57# define NSIG NSIG_MINIMUM
107#endif 58#endif
108 59
diff --git a/src/term.c b/src/term.c
index 8cc5dfd2a87..0eaf76a13df 100644
--- a/src/term.c
+++ b/src/term.c
@@ -25,7 +25,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25#include <sys/file.h> 25#include <sys/file.h>
26#include <sys/time.h> 26#include <sys/time.h>
27#include <unistd.h> 27#include <unistd.h>
28#include <signal.h>
29#include <setjmp.h> 28#include <setjmp.h>
30 29
31#include "lisp.h" 30#include "lisp.h"
@@ -2932,7 +2931,10 @@ dissociate_if_controlling_tty (int fd)
2932 no_controlling_tty = 1; 2931 no_controlling_tty = 1;
2933#else 2932#else
2934#ifdef TIOCNOTTY /* Try BSD ioctls. */ 2933#ifdef TIOCNOTTY /* Try BSD ioctls. */
2935 sigblock (sigmask (SIGTTOU)); 2934 sigset_t blocked;
2935 sigemptyset (&blocked);
2936 sigaddset (&blocked, SIGTTOU);
2937 pthread_sigmask (SIG_BLOCK, &blocked, 0);
2936 fd = emacs_open (DEV_TTY, O_RDWR, 0); 2938 fd = emacs_open (DEV_TTY, O_RDWR, 0);
2937 if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1) 2939 if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1)
2938 { 2940 {
@@ -2940,7 +2942,7 @@ dissociate_if_controlling_tty (int fd)
2940 } 2942 }
2941 if (fd != -1) 2943 if (fd != -1)
2942 emacs_close (fd); 2944 emacs_close (fd);
2943 sigunblock (sigmask (SIGTTOU)); 2945 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
2944#else 2946#else
2945 /* Unknown system. */ 2947 /* Unknown system. */
2946 croak (); 2948 croak ();
@@ -3074,9 +3076,14 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3074 3076
3075 /* On some systems, tgetent tries to access the controlling 3077 /* On some systems, tgetent tries to access the controlling
3076 terminal. */ 3078 terminal. */
3077 sigblock (sigmask (SIGTTOU)); 3079 {
3078 status = tgetent (tty->termcap_term_buffer, terminal_type); 3080 sigset_t blocked;
3079 sigunblock (sigmask (SIGTTOU)); 3081 sigemptyset (&blocked);
3082 sigaddset (&blocked, SIGTTOU);
3083 pthread_sigmask (SIG_BLOCK, &blocked, 0);
3084 status = tgetent (tty->termcap_term_buffer, terminal_type);
3085 pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
3086 }
3080 3087
3081 if (status < 0) 3088 if (status < 0)
3082 { 3089 {
diff --git a/src/widget.c b/src/widget.c
index 9eaf6d1df6a..0100acc8143 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -50,9 +50,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
50#include <X11/ShellP.h> 50#include <X11/ShellP.h>
51#include "../lwlib/lwlib.h" 51#include "../lwlib/lwlib.h"
52 52
53#include <signal.h>
54#include "syssignal.h"
55
56#include "character.h" 53#include "character.h"
57#include "font.h" 54#include "font.h"
58 55
diff --git a/src/xmenu.c b/src/xmenu.c
index 6f92da1b814..605db13e149 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -32,11 +32,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32 32
33#include <config.h> 33#include <config.h>
34 34
35#if 0 /* Why was this included? And without syssignal.h? */
36/* On 4.3 this loses if it comes after xterm.h. */
37#include <signal.h>
38#endif
39
40#include <stdio.h> 35#include <stdio.h>
41#include <setjmp.h> 36#include <setjmp.h>
42 37
diff --git a/src/xterm.c b/src/xterm.c
index 047b5569bf4..f0f6702cd67 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -21,7 +21,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21/* Xt features made by Fred Pierresteguy. */ 21/* Xt features made by Fred Pierresteguy. */
22 22
23#include <config.h> 23#include <config.h>
24#include <signal.h>
25#include <stdio.h> 24#include <stdio.h>
26#include <setjmp.h> 25#include <setjmp.h>
27 26
@@ -29,9 +28,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29 28
30#include "lisp.h" 29#include "lisp.h"
31#include "blockinput.h" 30#include "blockinput.h"
32
33/* Need syssignal.h for various externs and definitions that may be required
34 by some configurations for calls to signal later in this source file. */
35#include "syssignal.h" 31#include "syssignal.h"
36 32
37/* This may include sys/types.h, and that somehow loses 33/* This may include sys/types.h, and that somehow loses
@@ -7766,7 +7762,9 @@ x_connection_signal (int signalnum) /* If we don't have an argument, */
7766#ifdef USG 7762#ifdef USG
7767 /* USG systems forget handlers when they are used; 7763 /* USG systems forget handlers when they are used;
7768 must reestablish each time */ 7764 must reestablish each time */
7769 signal (signalnum, x_connection_signal); 7765 struct sigaction action;
7766 emacs_sigaction_init (&action, x_connection_signal);
7767 sigaction (signalnum, &action, 0);
7770#endif /* USG */ 7768#endif /* USG */
7771} 7769}
7772 7770
@@ -7876,10 +7874,15 @@ For details, see etc/PROBLEMS.\n",
7876 } 7874 }
7877 7875
7878 /* Ordinary stack unwind doesn't deal with these. */ 7876 /* Ordinary stack unwind doesn't deal with these. */
7877 {
7878 sigset_t unblocked;
7879 sigemptyset (&unblocked);
7879#ifdef SIGIO 7880#ifdef SIGIO
7880 sigunblock (sigmask (SIGIO)); 7881 sigaddset (&unblocked, SIGIO);
7881#endif 7882#endif
7882 sigunblock (sigmask (SIGALRM)); 7883 sigaddset (&unblocked, SIGALRM);
7884 pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
7885 }
7883 TOTALLY_UNBLOCK_INPUT; 7886 TOTALLY_UNBLOCK_INPUT;
7884 7887
7885 unbind_to (idx, Qnil); 7888 unbind_to (idx, Qnil);
@@ -10759,6 +10762,8 @@ x_create_terminal (struct x_display_info *dpyinfo)
10759void 10762void
10760x_initialize (void) 10763x_initialize (void)
10761{ 10764{
10765 struct sigaction action;
10766
10762 baud_rate = 19200; 10767 baud_rate = 19200;
10763 10768
10764 x_noop_count = 0; 10769 x_noop_count = 0;
@@ -10805,7 +10810,8 @@ x_initialize (void)
10805 XSetErrorHandler (x_error_handler); 10810 XSetErrorHandler (x_error_handler);
10806 XSetIOErrorHandler (x_io_error_quitter); 10811 XSetIOErrorHandler (x_io_error_quitter);
10807 10812
10808 signal (SIGPIPE, x_connection_signal); 10813 emacs_sigaction_init (&action, x_connection_signal);
10814 sigaction (SIGPIPE, &action, 0);
10809} 10815}
10810 10816
10811 10817