Signal-handler cleanup.
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 7 Sep 2012 01:27:44 +0000 (18:27 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 7 Sep 2012 01:27:44 +0000 (18:27 -0700)
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

23 files changed:
ChangeLog
configure.ac
src/ChangeLog
src/alloc.c
src/atimer.c
src/callproc.c
src/conf_post.h
src/data.c
src/dispnew.c
src/emacs.c
src/emacsgtkfixed.c
src/floatfns.c
src/gtkutil.c
src/keyboard.c
src/nsfns.m
src/process.c
src/sound.c
src/sysdep.c
src/syssignal.h
src/term.c
src/widget.c
src/xmenu.c
src/xterm.c

index 55223ab..112532e 100644 (file)
--- 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).
index 16e579c..dd5e322 100644 (file)
@@ -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
 
 
index 479fb38..3bfa9e9 100644 (file)
@@ -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
 
 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
index 1a9718b..bf7c156 100644 (file)
@@ -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>
index 060dead..3473192 100644 (file)
@@ -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);
 }
index 2e9a895..a92959a 100644 (file)
@@ -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;
index cef5586..1bf40af 100644 (file)
@@ -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
index 6151d81..5fbf43e 100644 (file)
@@ -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);
 }
index e02b330..85b3254 100644 (file)
@@ -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. */
index fc92b30..ff50f40 100644 (file)
@@ -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 */
     }
 
index 1a62b59..9404826 100644 (file)
@@ -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"
index f59cf58..e956dc2 100644 (file)
@@ -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"
index 3bce5be..884574e 100644 (file)
@@ -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)
index 128f928..d26cf35 100644 (file)
@@ -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)
index e8b5d22..f73086e 100644 (file)
@@ -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>
index 9ab8d27..0cc9bc3 100644 (file)
@@ -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);
index d20fa5e..5729d70 100644 (file)
@@ -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.  */
index 42b8baf..0f16d1a 100644 (file)
@@ -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 */
 
 \f
-/* 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)
   }
 }
 \f
-/* 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
index 504aff4..58290ee 100644 (file)
@@ -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
 
index 8cc5dfd..0eaf76a 100644 (file)
@@ -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)
     {
index 9eaf6d1..0100acc 100644 (file)
@@ -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"
 
index 6f92da1..605db13 100644 (file)
@@ -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>
 
index 047b556..f0f6702 100644 (file)
@@ -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);
 }