summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 @@
+2012-09-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ Signal-handler cleanup (Bug#12327).
+ * configure.ac (PTY_OPEN, PTY_TTY_NAME_SPRINTF):
+ Adjust to syssignal.h changes.
+ (SIGNAL_H_AB): Remove; no longer needed.
+
2012-09-04 Paul Eggert <eggert@cs.ucla.edu>
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
cygwin )
AC_DEFINE(PTY_ITERATION, [int i; for (i = 0; i < 1; i++)])
dnl multi-line AC_DEFINEs are hard. :(
- 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)])
+ 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)])
AC_DEFINE(PTY_NAME_SPRINTF, [])
AC_DEFINE(PTY_TTY_NAME_SPRINTF, [])
;;
@@ -3474,7 +3474,7 @@ case $opsys in
AC_DEFINE(PTY_ITERATION, [int i; for (i = 0; i < 1; i++)])
dnl Note that grantpt and unlockpt may fork. We must block SIGCHLD
dnl to prevent sigchld_handler from intercepting the child's death.
- 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)); }])
+ 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); }])
dnl if HAVE_POSIX_OPENPT
if test "x$ac_cv_func_posix_openpt" = xyes; then
AC_DEFINE(PTY_OPEN, [fd = posix_openpt (O_RDWR | O_NOCTTY)])
@@ -3519,18 +3519,15 @@ case $opsys in
;;
sol2* )
- dnl Uses sigblock/sigunblock rather than sighold/sigrelse,
- dnl which appear to be BSD4.1 specific. It may also be appropriate
- dnl for SVR4.x (x<2) but I'm not sure. fnf@cygnus.com
dnl On SysVr4, grantpt(3) forks a subprocess, so keep sigchld_handler()
dnl from intercepting that death. If any child but grantpt's should die
dnl within, it should be caught after sigrelse(2).
- 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); }])
+ 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); }])
;;
unixware )
dnl Comments are as per sol2*.
- 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); }])
+ 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); }])
;;
esac
@@ -3820,13 +3817,6 @@ case $opsys in
AC_DEFINE(XOS_NEEDS_TIME_H, 1, [Compensate for a bug in Xos.h on
some systems, where it requires time.h.])
;;
-
- netbsd | openbsd )
- dnl Greg A. Woods <woods@weird.com> says we must include signal.h
- dnl before syssignal.h is included, to work around interface conflicts
- dnl that are handled with CPP __RENAME() macro in signal.h.
- AC_DEFINE(SIGNAL_H_AHB, 1, [Define if AH_BOTTOM should include signal.h.])
- ;;
esac
diff --git a/src/ChangeLog b/src/ChangeLog
index 479fb38e60b..3bfa9e929d5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,57 @@
+2012-09-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ Signal-handler cleanup (Bug#12327).
+ 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.
+ * alloc.c, emacsgtkfixed.c, nsfns.m, widget.c, xmenu.c:
+ Do not include <signal.h> or "syssignal.h", as these
+ modules do not use signals.
+ * atimer.c, callproc.c, data.c, dispnew.c, emacs.c, floatfns.c:
+ * gtkutil.c, keyboard.c, process.c, sound.c, sysdep.c, term.c, xterm.c:
+ Do not include <signal.h>, as "syssignal.h" does that for us now.
+ * atimer.c (sigmask_atimers): New function.
+ (block_atimers, unblock_atimers): New functions,
+ replacing the old macros BLOCK_ATIMERS and UNBLOCK_ATIMERS.
+ All uses replaced.
+ * conf_post.h [SIGNAL_H_AHB]: Do not include <signal.h>;
+ no longer needed here.
+ * emacs.c (main): Inspect existing signal handler with sigaction,
+ so that there's no need to block and unblock SIGHUP.
+ * 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.
+ * 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.
+
2012-09-06 Eli Zaretskii <eliz@gnu.org>
* process.c (CAN_HANDLE_MULTIPLE_CHILDREN): Fix a typo that broke
@@ -50,7 +104,7 @@
2012-09-05 Paul Eggert <eggert@cs.ucla.edu>
- Fix race conditions with signal handlers and errno.
+ Fix race conditions with signal handlers and errno (Bug#12327).
Be more systematic about preserving errno whenever a signal
handler returns, even if it's not in the main thread. Do this by
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/>. */
#include <limits.h> /* For CHAR_BIT. */
#include <setjmp.h>
-#include <signal.h>
-
#ifdef HAVE_PTHREAD
#include <pthread.h>
#endif
@@ -42,7 +40,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "keyboard.h"
#include "frame.h"
#include "blockinput.h"
-#include "syssignal.h"
#include "termhooks.h" /* For struct terminal. */
#include <setjmp.h>
#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
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
-#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#include "lisp.h"
@@ -51,8 +50,24 @@ int pending_atimers;
/* Block/unblock SIGALRM. */
-#define BLOCK_ATIMERS sigblock (sigmask (SIGALRM))
-#define UNBLOCK_ATIMERS sigunblock (sigmask (SIGALRM))
+static void
+sigmask_atimers (int how)
+{
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGALRM);
+ pthread_sigmask (how, &blocked, 0);
+}
+static void
+block_atimers (void)
+{
+ sigmask_atimers (SIG_BLOCK);
+}
+static void
+unblock_atimers (void)
+{
+ sigmask_atimers (SIG_UNBLOCK);
+}
/* Function prototypes. */
@@ -109,7 +124,7 @@ start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn,
t->fn = fn;
t->client_data = client_data;
- BLOCK_ATIMERS;
+ block_atimers ();
/* Compute the timer's expiration time. */
switch (type)
@@ -130,7 +145,7 @@ start_atimer (enum atimer_type type, EMACS_TIME timestamp, atimer_callback fn,
/* Insert the timer in the list of active atimers. */
schedule_atimer (t);
- UNBLOCK_ATIMERS;
+ unblock_atimers ();
/* Arrange for a SIGALRM at the time the next atimer is ripe. */
set_alarm ();
@@ -146,7 +161,7 @@ cancel_atimer (struct atimer *timer)
{
int i;
- BLOCK_ATIMERS;
+ block_atimers ();
for (i = 0; i < 2; ++i)
{
@@ -173,7 +188,7 @@ cancel_atimer (struct atimer *timer)
}
}
- UNBLOCK_ATIMERS;
+ unblock_atimers ();
}
@@ -204,7 +219,7 @@ append_atimer_lists (struct atimer *list_1, struct atimer *list_2)
void
stop_other_atimers (struct atimer *t)
{
- BLOCK_ATIMERS;
+ block_atimers ();
if (t)
{
@@ -229,7 +244,7 @@ stop_other_atimers (struct atimer *t)
stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
atimers = t;
- UNBLOCK_ATIMERS;
+ unblock_atimers ();
}
@@ -244,7 +259,7 @@ run_all_atimers (void)
struct atimer *t = atimers;
struct atimer *next;
- BLOCK_ATIMERS;
+ block_atimers ();
atimers = stopped_atimers;
stopped_atimers = NULL;
@@ -255,7 +270,7 @@ run_all_atimers (void)
t = next;
}
- UNBLOCK_ATIMERS;
+ unblock_atimers ();
}
}
@@ -397,9 +412,9 @@ do_pending_atimers (void)
{
if (pending_atimers)
{
- BLOCK_ATIMERS;
+ block_atimers ();
run_timers ();
- UNBLOCK_ATIMERS;
+ unblock_atimers ();
}
}
@@ -412,7 +427,9 @@ turn_on_atimers (bool on)
{
if (on)
{
- signal (SIGALRM, deliver_alarm_signal);
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_alarm_signal);
+ sigaction (SIGALRM, &action, 0);
set_alarm ();
}
else
@@ -423,8 +440,10 @@ turn_on_atimers (bool on)
void
init_atimer (void)
{
+ struct sigaction action;
free_atimers = stopped_atimers = atimers = NULL;
pending_atimers = 0;
/* pending_signals is initialized in init_keyboard.*/
- signal (SIGALRM, deliver_alarm_signal);
+ emacs_sigaction_init (&action, deliver_alarm_signal);
+ sigaction (SIGALRM, &action, 0);
}
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/>. */
#include <config.h>
-#include <signal.h>
#include <errno.h>
#include <stdio.h>
#include <setjmp.h>
@@ -506,9 +505,6 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
if (fd_output >= 0)
fd1 = fd_output;
-#if 0 /* Some systems don't have sigblock. */
- mask = sigblock (sigmask (SIGCHLD));
-#endif
/* Record that we're about to create a synchronous process. */
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/>. */
#endif
#endif
-#ifdef SIGNAL_H_AHB
-#undef SIGNAL_H_AHB
-#include <signal.h>
-#endif
-
/* This silences a few compilation warnings on FreeBSD. */
#ifdef BSD_SYSTEM_AHB
#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/>. */
#include <config.h>
-#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
@@ -3210,7 +3209,7 @@ syms_of_data (void)
static _Noreturn void
handle_arith_signal (int sig)
{
- sigsetmask (SIGEMPTYMASK);
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
xsignal0 (Qarith_error);
}
@@ -3223,6 +3222,7 @@ deliver_arith_signal (int sig)
void
init_data (void)
{
+ struct sigaction action;
/* Don't do this if just dumping out.
We don't want to call `signal' in this case
so that we don't have trouble with dumping
@@ -3231,5 +3231,6 @@ init_data (void)
if (!initialized)
return;
#endif /* CANNOT_DUMP */
- signal (SIGFPE, deliver_arith_signal);
+ emacs_sigaction_init (&action, deliver_arith_signal);
+ sigaction (SIGFPE, &action, 0);
}
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/>. */
#define DISPEXTERN_INLINE EXTERN_INLINE
-#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#include <unistd.h>
@@ -5560,7 +5559,9 @@ handle_window_change_signal (int sig)
int width, height;
struct tty_display_info *tty;
- signal (SIGWINCH, deliver_window_change_signal);
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_window_change_signal);
+ sigaction (SIGWINCH, &action, 0);
/* The frame size change obviously applies to a single
termcap-controlled terminal, but we can't decide which.
@@ -6175,7 +6176,11 @@ init_display (void)
#ifndef CANNOT_DUMP
if (initialized)
#endif /* CANNOT_DUMP */
- signal (SIGWINCH, deliver_window_change_signal);
+ {
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_window_change_signal);
+ sigaction (SIGWINCH, &action, 0);
+ }
#endif /* SIGWINCH */
/* 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/>. */
#include <config.h>
-#include <signal.h>
#include <errno.h>
#include <stdio.h>
@@ -322,7 +321,12 @@ fatal_error_backtrace (int sig, int backtrace_limit)
going to send is probably blocked, so we have to unblock it if we
want to really receive it. */
#ifndef MSDOS
- sigunblock (sigmask (fatal_error_code));
+ {
+ sigset_t unblocked;
+ sigemptyset (&unblocked);
+ sigaddset (&unblocked, fatal_error_code);
+ pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
+ }
#endif
kill (getpid (), fatal_error_code);
@@ -339,7 +343,10 @@ static void deliver_danger_signal (int);
static void
handle_danger_signal (int sig)
{
- signal (sig, deliver_danger_signal);
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_danger_signal);
+ sigaction (sig, &action, 0);
+
malloc_warning ("Operating system warns that virtual memory is running low.\n");
/* It might be unsafe to call do_auto_save now. */
@@ -683,6 +690,7 @@ main (int argc, char **argv)
char dname_arg2[80];
#endif
char *ch_to_dir;
+ struct sigaction fatal_error_action;
#if GC_MARK_STACK
stack_base = &dummy;
@@ -1103,6 +1111,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
}
init_signals ();
+ emacs_sigaction_init (&fatal_error_action, deliver_fatal_signal);
/* Don't catch SIGHUP if dumping. */
if (1
@@ -1111,13 +1120,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#endif
)
{
- sigblock (sigmask (SIGHUP));
/* In --batch mode, don't catch SIGHUP if already ignored.
That makes nohup work. */
- if (! noninteractive
- || signal (SIGHUP, SIG_IGN) != SIG_IGN)
- signal (SIGHUP, deliver_fatal_signal);
- sigunblock (sigmask (SIGHUP));
+ bool catch_SIGHUP = !noninteractive;
+ if (!catch_SIGHUP)
+ {
+ struct sigaction old_action;
+ sigaction (SIGHUP, 0, &old_action);
+ catch_SIGHUP = old_action.sa_handler != SIG_IGN;
+ }
+ if (catch_SIGHUP)
+ sigaction (SIGHUP, &fatal_error_action, 0);
}
if (
@@ -1141,68 +1154,73 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
add_user_signal (SIGUSR2, "sigusr2");
#endif
#ifdef SIGABRT
- signal (SIGABRT, deliver_fatal_signal);
+ sigaction (SIGABRT, &fatal_error_action, 0);
#endif
#ifdef SIGHWE
- signal (SIGHWE, deliver_fatal_signal);
+ sigaction (SIGHWE, &fatal_error_action, 0);
#endif
#ifdef SIGPRE
- signal (SIGPRE, deliver_fatal_signal);
+ sigaction (SIGPRE, &fatal_error_action, 0);
#endif
#ifdef SIGORE
- signal (SIGORE, deliver_fatal_signal);
+ sigaction (SIGORE, &fatal_error_action, 0);
#endif
#ifdef SIGUME
- signal (SIGUME, deliver_fatal_signal);
+ sigaction (SIGUME, &fatal_error_action, 0);
#endif
#ifdef SIGDLK
- signal (SIGDLK, deliver_fatal_signal);
+ sigaction (SIGDLK, &fatal_error_action, 0);
#endif
#ifdef SIGCPULIM
- signal (SIGCPULIM, deliver_fatal_signal);
+ sigaction (SIGCPULIM, &fatal_error_action, 0);
#endif
#ifdef SIGIOT
/* This is missing on some systems - OS/2, for example. */
- signal (SIGIOT, deliver_fatal_signal);
+ sigaction (SIGIOT, &fatal_error_action, 0);
#endif
#ifdef SIGEMT
- signal (SIGEMT, deliver_fatal_signal);
+ sigaction (SIGEMT, &fatal_error_action, 0);
#endif
- signal (SIGFPE, deliver_fatal_signal);
+ sigaction (SIGFPE, &fatal_error_action, 0);
#ifdef SIGBUS
- signal (SIGBUS, deliver_fatal_signal);
+ sigaction (SIGBUS, &fatal_error_action, 0);
#endif
- signal (SIGSEGV, deliver_fatal_signal);
+ sigaction (SIGSEGV, &fatal_error_action, 0);
#ifdef SIGSYS
- signal (SIGSYS, deliver_fatal_signal);
+ sigaction (SIGSYS, &fatal_error_action, 0);
#endif
/* May need special treatment on MS-Windows. See
http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html
Please update the doc of kill-emacs, kill-emacs-hook, and
NEWS if you change this.
*/
- if (noninteractive) signal (SIGINT, deliver_fatal_signal);
- signal (SIGTERM, deliver_fatal_signal);
+ if (noninteractive)
+ sigaction (SIGINT, &fatal_error_action, 0);
+ sigaction (SIGTERM, &fatal_error_action, 0);
#ifdef SIGXCPU
- signal (SIGXCPU, deliver_fatal_signal);
+ sigaction (SIGXCPU, &fatal_error_action, 0);
#endif
#ifdef SIGXFSZ
- signal (SIGXFSZ, deliver_fatal_signal);
+ sigaction (SIGXFSZ, &fatal_error_action, 0);
#endif /* SIGXFSZ */
#ifdef SIGDANGER
/* This just means available memory is getting low. */
- signal (SIGDANGER, deliver_danger_signal);
+ {
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_danger_signal);
+ sigaction (SIGDANGER, &action, 0);
+ }
#endif
#ifdef AIX
/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
- signal (SIGXCPU, deliver_fatal_signal);
- signal (SIGIOINT, deliver_fatal_signal);
- signal (SIGGRANT, deliver_fatal_signal);
- signal (SIGRETRACT, deliver_fatal_signal);
- signal (SIGSOUND, deliver_fatal_signal);
- signal (SIGMSG, deliver_fatal_signal);
+ sigaction (SIGXCPU, &fatal_error_action, 0);
+ sigaction (SIGIOINT, &fatal_error_action, 0);
+ sigaction (SIGGRANT, &fatal_error_action, 0);
+ sigaction (SIGRETRACT, &fatal_error_action, 0);
+ sigaction (SIGSOUND, &fatal_error_action, 0);
+ sigaction (SIGMSG, &fatal_error_action, 0);
#endif /* AIX */
}
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/>. */
#include <config.h>
#include "emacsgtkfixed.h"
-#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#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/>. */
*/
#include <config.h>
-#include <signal.h>
#include <setjmp.h>
#include "lisp.h"
#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/>. */
#ifdef USE_GTK
#include <float.h>
-#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
@@ -1979,7 +1978,10 @@ xg_get_file_name (FRAME_PTR f,
/* I really don't know why this is needed, but without this the GLIBC add on
library linuxthreads hangs when the Gnome file chooser backend creates
threads. */
- sigblock (sigmask (__SIGRTMIN));
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, __SIGRTMIN);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
#endif /* HAVE_PTHREAD */
#ifdef HAVE_GTK_FILE_SELECTION_NEW
@@ -2001,7 +2003,7 @@ xg_get_file_name (FRAME_PTR f,
filesel_done = xg_dialog_run (f, w);
#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
- sigunblock (sigmask (__SIGRTMIN));
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
#endif
if (filesel_done == GTK_RESPONSE_OK)
@@ -2057,7 +2059,10 @@ xg_get_font (FRAME_PTR f, const char *default_name)
Lisp_Object font = Qnil;
#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
- sigblock (sigmask (__SIGRTMIN));
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, __SIGRTMIN);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
#endif /* HAVE_PTHREAD */
w = gtk_font_chooser_dialog_new
@@ -2086,7 +2091,7 @@ xg_get_font (FRAME_PTR f, const char *default_name)
done = xg_dialog_run (f, w);
#if defined (HAVE_PTHREAD) && defined (__SIGRTMIN)
- sigunblock (sigmask (__SIGRTMIN));
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
#endif
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/>. */
#define KEYBOARD_INLINE EXTERN_INLINE
-#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#include "lisp.h"
@@ -3680,7 +3679,7 @@ kbd_buffer_store_event_hold (register struct input_event *event,
if (immediate_quit && NILP (Vinhibit_quit))
{
immediate_quit = 0;
- sigfree ();
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
QUIT;
}
}
@@ -3832,7 +3831,11 @@ kbd_buffer_get_event (KBOARD **kbp,
unhold_keyboard_input ();
#ifdef SIGIO
if (!noninteractive)
- signal (SIGIO, deliver_input_available_signal);
+ {
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_input_available_signal);
+ sigaction (SIGIO, &action, 0);
+ }
#endif /* SIGIO */
start_polling ();
}
@@ -6780,10 +6783,12 @@ gobble_input (int expected)
#ifdef SIGIO
if (interrupt_input)
{
- SIGMASKTYPE mask;
- mask = sigblock (sigmask (SIGIO));
+ sigset_t blocked, procmask;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGIO);
+ pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
read_avail_input (expected);
- sigsetmask (mask);
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
}
else
#ifdef POLL_FOR_INPUT
@@ -6792,10 +6797,12 @@ gobble_input (int expected)
it's always set. */
if (!interrupt_input && poll_suppress_count == 0)
{
- SIGMASKTYPE mask;
- mask = sigblock (sigmask (SIGALRM));
+ sigset_t blocked, procmask;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGALRM);
+ pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
read_avail_input (expected);
- sigsetmask (mask);
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
}
else
#endif
@@ -6831,10 +6838,12 @@ record_asynch_buffer_change (void)
#ifdef SIGIO
if (interrupt_input)
{
- SIGMASKTYPE mask;
- mask = sigblock (sigmask (SIGIO));
+ sigset_t blocked, procmask;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGIO);
+ pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
kbd_buffer_store_event (&event);
- sigsetmask (mask);
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
}
else
#endif
@@ -7295,6 +7304,7 @@ static struct user_signal_info *user_signals = NULL;
void
add_user_signal (int sig, const char *name)
{
+ struct sigaction action;
struct user_signal_info *p;
for (p = user_signals; p; p = p->next)
@@ -7309,7 +7319,8 @@ add_user_signal (int sig, const char *name)
p->next = user_signals;
user_signals = p;
- signal (sig, deliver_user_signal);
+ emacs_sigaction_init (&action, deliver_user_signal);
+ sigaction (sig, &action, 0);
}
static void
@@ -7381,7 +7392,7 @@ store_user_signal_events (void)
for (p = user_signals; p; p = p->next)
if (p->npending > 0)
{
- SIGMASKTYPE mask;
+ sigset_t blocked, procmask;
if (nstored == 0)
{
@@ -7391,7 +7402,10 @@ store_user_signal_events (void)
}
nstored += p->npending;
- mask = sigblock (sigmask (p->sig));
+ sigemptyset (&blocked);
+ sigaddset (&blocked, p->sig);
+ pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
+
do
{
buf.code = p->sig;
@@ -7399,7 +7413,8 @@ store_user_signal_events (void)
p->npending--;
}
while (p->npending > 0);
- sigsetmask (mask);
+
+ pthread_sigmask (SIG_SETMASK, &procmask, 0);
}
return nstored;
@@ -10838,7 +10853,10 @@ handle_interrupt (void)
/* If SIGINT isn't blocked, don't let us be interrupted by
another SIGINT, it might be harmful due to non-reentrancy
in I/O functions. */
- sigblock (sigmask (SIGINT));
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGINT);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
fflush (stdout);
reset_all_sys_modes ();
@@ -10909,7 +10927,7 @@ handle_interrupt (void)
#endif /* not MSDOS */
fflush (stdout);
init_all_sys_modes ();
- sigfree ();
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
}
else
{
@@ -10922,7 +10940,7 @@ handle_interrupt (void)
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
immediate_quit = 0;
- sigfree ();
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
saved = gl_state;
GCPRO4 (saved.object, saved.global_code,
saved.current_syntax_table, saved.old_prop);
@@ -10967,7 +10985,7 @@ quit_throw_to_read_char (int from_signal)
if (!from_signal && EQ (Vquit_flag, Qkill_emacs))
Fkill_emacs (Qnil);
- sigfree ();
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
/* Prevent another signal from doing this before we finish. */
clear_waiting_for_input ();
input_pending = 0;
@@ -11402,17 +11420,23 @@ init_keyboard (void)
SIGINT. There is special code in interrupt_signal to exit
Emacs on SIGINT when there are no termcap frames on the
controlling terminal. */
- signal (SIGINT, deliver_interrupt_signal);
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_interrupt_signal);
+ sigaction (SIGINT, &action, 0);
#ifndef DOS_NT
/* For systems with SysV TERMIO, C-g is set up for both SIGINT and
SIGQUIT and we can't tell which one it will give us. */
- signal (SIGQUIT, deliver_interrupt_signal);
+ sigaction (SIGQUIT, &action, 0);
#endif /* not DOS_NT */
}
/* Note SIGIO has been undef'd if FIONREAD is missing. */
#ifdef SIGIO
if (!noninteractive)
- signal (SIGIO, deliver_input_available_signal);
+ {
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_input_available_signal);
+ sigaction (SIGIO, &action, 0);
+ }
#endif /* SIGIO */
/* Use interrupt input by default, if it works and noninterrupt input
@@ -11424,7 +11448,7 @@ init_keyboard (void)
interrupt_input = 0;
#endif
- sigfree ();
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
dribble = 0;
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)
interpretation of even the system includes. */
#include <config.h>
-#include <signal.h>
#include <math.h>
#include <setjmp.h>
#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/>. */
#define PROCESS_INLINE EXTERN_INLINE
-#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <setjmp.h>
@@ -1612,8 +1611,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
#if !defined (WINDOWSNT) && defined (FD_CLOEXEC)
int wait_child_setup[2];
#endif
- sigset_t procmask;
- sigset_t blocked;
+ sigset_t blocked, procmask;
struct sigaction sigint_action;
struct sigaction sigquit_action;
struct sigaction sigpipe_action;
@@ -1765,12 +1763,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
int xforkin = forkin;
int xforkout = forkout;
-#if 0 /* This was probably a mistake--it duplicates code later on,
- but fails to handle all the cases. */
- /* Make sure SIGCHLD is not blocked in the child. */
- sigsetmask (SIGEMPTYMASK);
-#endif
-
/* Make the pty be the controlling terminal of the process. */
#ifdef HAVE_PTYS
/* First, disconnect its current controlling terminal. */
@@ -5434,7 +5426,10 @@ static Lisp_Object process_sent_to;
static _Noreturn void
handle_pipe_signal (int sig)
{
- sigunblock (sigmask (SIGPIPE));
+ sigset_t unblocked;
+ sigemptyset (&unblocked);
+ sigaddset (&unblocked, SIGPIPE);
+ pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
_longjmp (send_process_frame, 1);
}
@@ -5534,7 +5529,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
struct Lisp_Process *p = XPROCESS (proc);
ssize_t rv;
struct coding_system *coding;
- void (*volatile old_sigpipe) (int);
+ struct sigaction old_sigpipe_action;
if (p->raw_status_new)
update_status (p);
@@ -5673,7 +5668,9 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
/* Send this batch, using one or more write calls. */
ptrdiff_t written = 0;
int outfd = p->outfd;
- old_sigpipe = signal (SIGPIPE, deliver_pipe_signal);
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_pipe_signal);
+ sigaction (SIGPIPE, &action, &old_sigpipe_action);
#ifdef DATAGRAM_SOCKETS
if (DATAGRAM_CHAN_P (outfd))
{
@@ -5684,7 +5681,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
written = rv;
else if (errno == EMSGSIZE)
{
- signal (SIGPIPE, old_sigpipe);
+ sigaction (SIGPIPE, &old_sigpipe_action, 0);
report_file_error ("sending datagram",
Fcons (proc, Qnil));
}
@@ -5709,7 +5706,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
}
#endif
}
- signal (SIGPIPE, old_sigpipe);
+ sigaction (SIGPIPE, &old_sigpipe_action, 0);
if (rv < 0)
{
@@ -5769,7 +5766,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
}
else
{
- signal (SIGPIPE, old_sigpipe);
+ sigaction (SIGPIPE, &old_sigpipe_action, 0);
proc = process_sent_to;
p = XPROCESS (proc);
p->raw_status_new = 0;
@@ -7389,7 +7386,11 @@ init_process_emacs (void)
#ifndef CANNOT_DUMP
if (! noninteractive || initialized)
#endif
- signal (SIGCHLD, deliver_child_signal);
+ {
+ struct sigaction action;
+ emacs_sigaction_init (&action, deliver_child_signal);
+ sigaction (SIGCHLD, &action, 0);
+ }
#endif
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/>. */
#include "lisp.h"
#include "dispextern.h"
#include "atimer.h"
-#include <signal.h>
#include "syssignal.h"
/* END: Common Includes */
@@ -316,7 +315,12 @@ sound_perror (const char *msg)
turn_on_atimers (1);
#ifdef SIGIO
- sigunblock (sigmask (SIGIO));
+ {
+ sigset_t unblocked;
+ sigemptyset (&unblocked);
+ sigaddset (&unblocked, SIGIO);
+ pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
+ }
#endif
if (saved_errno != 0)
error ("%s: %s", msg, strerror (saved_errno));
@@ -728,6 +732,9 @@ static void
vox_configure (struct sound_device *sd)
{
int val;
+#ifdef SIGIO
+ sigset_t blocked;
+#endif
eassert (sd->fd >= 0);
@@ -736,7 +743,9 @@ vox_configure (struct sound_device *sd)
troubles. */
turn_on_atimers (0);
#ifdef SIGIO
- sigblock (sigmask (SIGIO));
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGIO);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
#endif
val = sd->format;
@@ -770,7 +779,7 @@ vox_configure (struct sound_device *sd)
turn_on_atimers (1);
#ifdef SIGIO
- sigunblock (sigmask (SIGIO));
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
#endif
}
@@ -786,7 +795,10 @@ vox_close (struct sound_device *sd)
be interrupted by a signal. Block the ones we know to cause
troubles. */
#ifdef SIGIO
- sigblock (sigmask (SIGIO));
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGIO);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
#endif
turn_on_atimers (0);
@@ -795,7 +807,7 @@ vox_close (struct sound_device *sd)
turn_on_atimers (1);
#ifdef SIGIO
- sigunblock (sigmask (SIGIO));
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
#endif
/* 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/>. */
#define SYSTIME_INLINE EXTERN_INLINE
#include <execinfo.h>
-#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#ifdef HAVE_PWD_H
@@ -303,27 +302,34 @@ wait_for_termination_1 (pid_t pid, int interruptible)
termination of subprocesses, perhaps involving a kernel bug too,
but no idea what it is. Just as a hunch we signal SIGCHLD to see
if that causes the problem to go away or get worse. */
- sigsetmask (sigmask (SIGCHLD));
+ sigset_t sigchild_mask;
+ sigemptyset (&sigchild_mask);
+ sigaddset (&sigchild_mask, SIGCHLD);
+ pthread_sigmask (SIG_SETMASK, &sigchild_mask, 0);
+
if (0 > kill (pid, 0))
{
- sigsetmask (SIGEMPTYMASK);
+ pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
kill (getpid (), SIGCHLD);
break;
}
if (wait_debugging)
sleep (1);
else
- sigpause (SIGEMPTYMASK);
+ sigsuspend (&empty_mask);
#else /* not BSD_SYSTEM, and not HPUX version >= 6 */
#ifdef WINDOWSNT
wait (0);
break;
#else /* not WINDOWSNT */
- sigblock (sigmask (SIGCHLD));
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGCHLD);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
errno = 0;
if (kill (pid, 0) == -1 && errno == ESRCH)
{
- sigunblock (sigmask (SIGCHLD));
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
break;
}
@@ -457,11 +463,11 @@ child_setup_tty (int out)
#endif /* not MSDOS */
-/* Record a signal code and the handler for it. */
+/* Record a signal code and the action for it. */
struct save_signal
{
int code;
- void (*handler) (int);
+ struct sigaction action;
};
static void save_signal_handlers (struct save_signal *);
@@ -619,8 +625,9 @@ save_signal_handlers (struct save_signal *saved_handlers)
{
while (saved_handlers->code)
{
- saved_handlers->handler
- = (void (*) (int)) signal (saved_handlers->code, SIG_IGN);
+ struct sigaction action;
+ emacs_sigaction_init (&action, SIG_IGN);
+ sigaction (saved_handlers->code, &action, &saved_handlers->action);
saved_handlers++;
}
}
@@ -630,7 +637,7 @@ restore_signal_handlers (struct save_signal *saved_handlers)
{
while (saved_handlers->code)
{
- signal (saved_handlers->code, saved_handlers->handler);
+ sigaction (saved_handlers->code, &saved_handlers->action, 0);
saved_handlers++;
}
}
@@ -687,13 +694,17 @@ reset_sigio (int fd)
void
request_sigio (void)
{
+ sigset_t unblocked;
+
if (noninteractive)
return;
+ sigemptyset (&unblocked);
#ifdef SIGWINCH
- sigunblock (sigmask (SIGWINCH));
+ sigaddset (&unblocked, SIGWINCH);
#endif
- sigunblock (sigmask (SIGIO));
+ sigaddset (&unblocked, SIGIO);
+ pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
interrupts_deferred = 0;
}
@@ -701,6 +712,8 @@ request_sigio (void)
void
unrequest_sigio (void)
{
+ sigset_t blocked;
+
if (noninteractive)
return;
@@ -709,10 +722,12 @@ unrequest_sigio (void)
return;
#endif
+ sigemptyset (&blocked);
#ifdef SIGWINCH
- sigblock (sigmask (SIGWINCH));
+ sigaddset (&blocked, SIGWINCH);
#endif
- sigblock (sigmask (SIGIO));
+ sigaddset (&blocked, SIGIO);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
interrupts_deferred = 1;
}
@@ -1471,20 +1486,16 @@ init_system_name (void)
}
}
-/* POSIX signals support - DJB */
-/* Anyone with POSIX signals should have ANSI C declarations */
-
sigset_t empty_mask;
-#ifndef WINDOWSNT
-
-signal_handler_t
-sys_signal (int signal_number, signal_handler_t action)
+/* Store into *ACTION a signal action suitable for Emacs, with handler
+ HANDLER. */
+void
+emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
{
- struct sigaction new_action, old_action;
- sigemptyset (&new_action.sa_mask);
- new_action.sa_handler = action;
- new_action.sa_flags = 0;
+ sigemptyset (&action->sa_mask);
+ action->sa_handler = handler;
+ action->sa_flags = 0;
#if defined (SA_RESTART)
/* Emacs mostly works better with restartable system services. If this
flag exists, we probably want to turn it on here.
@@ -1501,54 +1512,8 @@ sys_signal (int signal_number, signal_handler_t action)
# if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT)
if (noninteractive)
# endif
- new_action.sa_flags = SA_RESTART;
+ action->sa_flags = SA_RESTART;
#endif
- sigaction (signal_number, &new_action, &old_action);
- return (old_action.sa_handler);
-}
-
-#endif /* WINDOWSNT */
-
-#ifndef __GNUC__
-/* If we're compiling with GCC, we don't need this function, since it
- can be written as a macro. */
-sigset_t
-sys_sigmask (int sig)
-{
- sigset_t mask;
- sigemptyset (&mask);
- sigaddset (&mask, sig);
- return mask;
-}
-#endif
-
-/* I'd like to have these guys return pointers to the mask storage in here,
- but there'd be trouble if the code was saving multiple masks. I'll be
- safe and pass the structure. It normally won't be more than 2 bytes
- anyhow. - DJB */
-
-sigset_t
-sys_sigblock (sigset_t new_mask)
-{
- sigset_t old_mask;
- pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask);
- return (old_mask);
-}
-
-sigset_t
-sys_sigunblock (sigset_t new_mask)
-{
- sigset_t old_mask;
- pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask);
- return (old_mask);
-}
-
-sigset_t
-sys_sigsetmask (sigset_t new_mask)
-{
- sigset_t old_mask;
- pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask);
- return (old_mask);
}
#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.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
+#include <signal.h>
+
extern void init_signals (void);
#ifdef HAVE_PTHREAD
@@ -26,63 +28,16 @@ extern void init_signals (void);
#define FORWARD_SIGNAL_TO_MAIN_THREAD
#endif
-/* Don't #include <signal.h>. That header should always be #included
- before "config.h", because some configuration files (like s/hpux.h)
- indicate that SIGIO doesn't work by #undef-ing SIGIO. If this file
- #includes <signal.h>, then that will re-#define SIGIO and confuse
- things. */
-/* XXX This is not correct anymore, there is a BROKEN_SIGIO macro. */
-
-#define SIGMASKTYPE sigset_t
-
-#define SIGEMPTYMASK (empty_mask)
extern sigset_t empty_mask;
-/* POSIX pretty much destroys any possibility of writing sigmask as a
- macro in standard C. We always define our own version because the
- predefined macro in Glibc 2.1 is only provided for compatibility for old
- programs that use int as signal mask type. */
-#undef sigmask
-#ifdef __GNUC__
-#define sigmask(SIG) \
- ({ \
- sigset_t _mask; \
- sigemptyset (&_mask); \
- sigaddset (&_mask, SIG); \
- _mask; \
- })
-#else /* ! defined (__GNUC__) */
-extern sigset_t sys_sigmask ();
-#define sigmask(SIG) (sys_sigmask (SIG))
-#endif /* ! defined (__GNUC__) */
-
-#undef sigpause
-#define sigpause(MASK) sigsuspend (&(MASK))
-
-#define sigblock(SIG) sys_sigblock (SIG)
-#define sigunblock(SIG) sys_sigunblock (SIG)
-#ifndef sigsetmask
-#define sigsetmask(SIG) sys_sigsetmask (SIG)
-#endif
-#undef signal
-#define signal(SIG,ACT) sys_signal(SIG,ACT)
-
-/* Whether this is what all systems want or not, this is what
- appears to be assumed in the source, for example data.c:arith_error. */
typedef void (*signal_handler_t) (int);
-signal_handler_t sys_signal (int signal_number, signal_handler_t action);
-sigset_t sys_sigblock (sigset_t new_mask);
-sigset_t sys_sigunblock (sigset_t new_mask);
-sigset_t sys_sigsetmask (sigset_t new_mask);
+extern void emacs_sigaction_init (struct sigaction *, signal_handler_t);
+
#if ! (defined TIOCNOTTY || defined USG5 || defined CYGWIN)
_Noreturn void croak (char *);
#endif
-#define sys_sigdel(MASK,SIG) sigdelset (&MASK,SIG)
-
-#define sigfree() sigsetmask (SIGEMPTYMASK)
-
#if defined (SIGIO) && defined (BROKEN_SIGIO)
# undef SIGIO
#endif
@@ -97,12 +52,8 @@ _Noreturn void croak (char *);
#undef SIGPTY
#endif
-
-/* FIXME? Emacs only defines NSIG_MINIMUM on some platforms? */
#if NSIG < NSIG_MINIMUM
-# ifdef NSIG
-# undef NSIG
-# endif
+# undef NSIG
# define NSIG NSIG_MINIMUM
#endif
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/>. */
#include <sys/file.h>
#include <sys/time.h>
#include <unistd.h>
-#include <signal.h>
#include <setjmp.h>
#include "lisp.h"
@@ -2932,7 +2931,10 @@ dissociate_if_controlling_tty (int fd)
no_controlling_tty = 1;
#else
#ifdef TIOCNOTTY /* Try BSD ioctls. */
- sigblock (sigmask (SIGTTOU));
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGTTOU);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
fd = emacs_open (DEV_TTY, O_RDWR, 0);
if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1)
{
@@ -2940,7 +2942,7 @@ dissociate_if_controlling_tty (int fd)
}
if (fd != -1)
emacs_close (fd);
- sigunblock (sigmask (SIGTTOU));
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
#else
/* Unknown system. */
croak ();
@@ -3074,9 +3076,14 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
/* On some systems, tgetent tries to access the controlling
terminal. */
- sigblock (sigmask (SIGTTOU));
- status = tgetent (tty->termcap_term_buffer, terminal_type);
- sigunblock (sigmask (SIGTTOU));
+ {
+ sigset_t blocked;
+ sigemptyset (&blocked);
+ sigaddset (&blocked, SIGTTOU);
+ pthread_sigmask (SIG_BLOCK, &blocked, 0);
+ status = tgetent (tty->termcap_term_buffer, terminal_type);
+ pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
+ }
if (status < 0)
{
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/>. */
#include <X11/ShellP.h>
#include "../lwlib/lwlib.h"
-#include <signal.h>
-#include "syssignal.h"
-
#include "character.h"
#include "font.h"
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/>. */
#include <config.h>
-#if 0 /* Why was this included? And without syssignal.h? */
-/* On 4.3 this loses if it comes after xterm.h. */
-#include <signal.h>
-#endif
-
#include <stdio.h>
#include <setjmp.h>
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/>. */
/* Xt features made by Fred Pierresteguy. */
#include <config.h>
-#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
@@ -29,9 +28,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "lisp.h"
#include "blockinput.h"
-
-/* Need syssignal.h for various externs and definitions that may be required
- by some configurations for calls to signal later in this source file. */
#include "syssignal.h"
/* 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, */
#ifdef USG
/* USG systems forget handlers when they are used;
must reestablish each time */
- signal (signalnum, x_connection_signal);
+ struct sigaction action;
+ emacs_sigaction_init (&action, x_connection_signal);
+ sigaction (signalnum, &action, 0);
#endif /* USG */
}
@@ -7876,10 +7874,15 @@ For details, see etc/PROBLEMS.\n",
}
/* Ordinary stack unwind doesn't deal with these. */
+ {
+ sigset_t unblocked;
+ sigemptyset (&unblocked);
#ifdef SIGIO
- sigunblock (sigmask (SIGIO));
+ sigaddset (&unblocked, SIGIO);
#endif
- sigunblock (sigmask (SIGALRM));
+ sigaddset (&unblocked, SIGALRM);
+ pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
+ }
TOTALLY_UNBLOCK_INPUT;
unbind_to (idx, Qnil);
@@ -10759,6 +10762,8 @@ x_create_terminal (struct x_display_info *dpyinfo)
void
x_initialize (void)
{
+ struct sigaction action;
+
baud_rate = 19200;
x_noop_count = 0;
@@ -10805,7 +10810,8 @@ x_initialize (void)
XSetErrorHandler (x_error_handler);
XSetIOErrorHandler (x_io_error_quitter);
- signal (SIGPIPE, x_connection_signal);
+ emacs_sigaction_init (&action, x_connection_signal);
+ sigaction (SIGPIPE, &action, 0);
}