Commit 2fe28299 authored by Paul Eggert's avatar Paul Eggert

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
parent 845ce106
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).
......
......@@ -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
......
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
......
......@@ -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>
......
......@@ -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);
}
......@@ -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;
......
......@@ -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
......
......@@ -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);
}
......@@ -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. */
......
......@@ -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 */
}
......
......@@ -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"
......
......@@ -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"
......
......@@ -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)
......
......@@ -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 ();