changeset 10230:54813304edd2

Use sigaction module rather than signal(). * modules/c-stack (Depends-on): Add sigaction. * modules/fatal-signal (Depends-on): Likewise. * modules/nanosleep (Depends-on): Likewise. * modules/sigprocmask (Files): Add sig-handler.h. * modules/sigaction (Files): Likewise. * lib/sig-handler.h (get_handler): New file, suggested by Paul Eggert. * lib/c-stack.c (SIGACTION_WORKS): Simplify conditions. (c_stack_action) [!SIGACTION_WORKS]: Use sigaction, not signal. * lib/fatal-signal.c (uninstall_handlers, install_handlers) (init_fatal_signals): Likewise. * lib/nanosleep.c (rpl_nanosleep): Likewise. (siginterrupt): Delete fallback. * lib/sigprocmask.c (handler_t): Delete. (old_handlers): Use sa_handler_t instead. * m4/nanosleep.m4 (gl_PREREQ_NANOSLEEP): Drop check for siginterrupt. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Sat, 21 Jun 2008 07:08:49 -0600
parents 29502a2dd08a
children 32f7d74b65e8
files ChangeLog lib/c-stack.c lib/fatal-signal.c lib/nanosleep.c lib/sig-handler.h lib/sigprocmask.c m4/nanosleep.m4 modules/c-stack modules/fatal-signal modules/nanosleep modules/sigaction modules/sigprocmask
diffstat 12 files changed, 112 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Jun 21 14:32:55 2008 -0600
+++ b/ChangeLog	Sat Jun 21 07:08:49 2008 -0600
@@ -1,5 +1,24 @@
 2008-06-21  Eric Blake  <ebb9@byu.net>
 
+	Use sigaction module rather than signal().
+	* modules/c-stack (Depends-on): Add sigaction.
+	* modules/fatal-signal (Depends-on): Likewise.
+	* modules/nanosleep (Depends-on): Likewise.
+	* modules/sigprocmask (Files): Add sig-handler.h.
+	* modules/sigaction (Files): Likewise.
+	* lib/sig-handler.h (get_handler): New file, suggested by Paul
+	Eggert.
+	* lib/c-stack.c (SIGACTION_WORKS): Simplify conditions.
+	(c_stack_action) [!SIGACTION_WORKS]: Use sigaction, not signal.
+	* lib/fatal-signal.c (uninstall_handlers, install_handlers)
+	(init_fatal_signals): Likewise.
+	* lib/nanosleep.c (rpl_nanosleep): Likewise.
+	(siginterrupt): Delete fallback.
+	* lib/sigprocmask.c (handler_t, old_handlers): Use sa_handler_t
+	instead.
+	* m4/nanosleep.m4 (gl_PREREQ_NANOSLEEP): Drop check for
+	siginterrupt.
+
 	New module sigaction, for mingw.
 	* modules/sigaction: New module...
 	* modules/sigaction-tests: ...and its test.
--- a/lib/c-stack.c	Sat Jun 21 14:32:55 2008 -0600
+++ b/lib/c-stack.c	Sat Jun 21 07:08:49 2008 -0600
@@ -71,8 +71,7 @@
 #include "c-stack.h"
 #include "exitfail.h"
 
-#if (HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined SA_NODEFER \
-     && defined SA_ONSTACK && defined SA_RESETHAND && defined SA_SIGINFO)
+#if defined SA_ONSTACK && defined SA_SIGINFO
 # define SIGACTION_WORKS 1
 #else
 # define SIGACTION_WORKS 0
@@ -168,7 +167,7 @@
       char const *faulting_address = info->si_addr;
       size_t s = faulting_address - stack_base;
       size_t page_size = sysconf (_SC_PAGESIZE);
-      if (find_stack_direction (0) < 0)
+      if (find_stack_direction (NULL) < 0)
 	s += page_size;
       if (s < stack_size + page_size)
 	signo = 0;
@@ -213,10 +212,11 @@
 {
   int r;
   stack_t st;
+  struct sigaction act;
   st.ss_flags = 0;
   st.ss_sp = alternate_signal_stack.buffer;
   st.ss_size = sizeof alternate_signal_stack.buffer;
-  r = sigaltstack (&st, 0);
+  r = sigaltstack (&st, NULL);
   if (r != 0)
     return r;
 
@@ -224,23 +224,20 @@
   program_error_message = _("program error");
   stack_overflow_message = _("stack overflow");
 
-  {
-# if SIGACTION_WORKS
-    struct sigaction act;
-    sigemptyset (&act.sa_mask);
+  sigemptyset (&act.sa_mask);
 
-    /* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but
-       this is not true on Solaris 8 at least.  It doesn't hurt to use
-       SA_NODEFER here, so leave it in.  */
-    act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
+# if SIGACTION_WORKS
+  /* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but
+     this is not true on Solaris 8 at least.  It doesn't hurt to use
+     SA_NODEFER here, so leave it in.  */
+  act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
+  act.sa_sigaction = segv_handler;
+# else
+  act.sa_flags = SA_NODEFER | SA_RESETHAND;
+  act.sa_handler = die;
+# endif
 
-    act.sa_sigaction = segv_handler;
-
-    return sigaction (SIGSEGV, &act, 0);
-# else
-    return signal (SIGSEGV, die) == SIG_ERR ? -1 : 0;
-# endif
-  }
+  return sigaction (SIGSEGV, &act, NULL);
 }
 
 #else /* ! (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK) */
--- a/lib/fatal-signal.c	Sat Jun 21 14:32:55 2008 -0600
+++ b/lib/fatal-signal.c	Sat Jun 21 07:08:49 2008 -0600
@@ -26,11 +26,11 @@
 #include <signal.h>
 #include <unistd.h>
 
+#include "sig-handler.h"
 #include "xalloc.h"
 
 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
 
-
 /* ========================================================================= */
 
 
@@ -88,7 +88,6 @@
   static bool fatal_signals_initialized = false;
   if (!fatal_signals_initialized)
     {
-#if HAVE_SIGACTION
       size_t i;
 
       for (i = 0; i < num_fatal_signals; i++)
@@ -96,14 +95,9 @@
 	  struct sigaction action;
 
 	  if (sigaction (fatal_signals[i], NULL, &action) >= 0
-	      /* POSIX says that SIG_IGN can only occur when action.sa_flags
-		 does not contain SA_SIGINFO.  But in Linux 2.4, for example,
-		 SA_SIGINFO can actually be set and is ignored when sa_handler
-		 is SIG_IGN.  So don't bother testing for SA_SIGINFO.  */
-	      && action.sa_handler == SIG_IGN)
+	      && get_handler (&action) == SIG_IGN)
 	    fatal_signals[i] = -1;
 	}
-#endif
 
       fatal_signals_initialized = true;
     }
@@ -136,10 +130,14 @@
 uninstall_handlers ()
 {
   size_t i;
+  struct sigaction action;
 
+  action.sa_handler = SIG_DFL;
+  action.sa_flags = 0;
+  sigemptyset (&action.sa_mask);
   for (i = 0; i < num_fatal_signals; i++)
     if (fatal_signals[i] >= 0)
-      signal (fatal_signals[i], SIG_DFL);
+      sigaction (fatal_signals[i], &action, NULL);
 }
 
 
@@ -162,9 +160,9 @@
     }
 
   /* Now execute the signal's default action.
-     If signal() blocks the signal being delivered for the duration of the
-     signal handler's execution, the re-raised signal is delivered when this
-     handler returns; otherwise it is delivered already during raise().  */
+     If any cleanup action blocks the signal that triggered the cleanup, the
+     re-raised signal is delivered when this handler returns; otherwise it
+     is delivered already during raise().  */
   uninstall_handlers ();
   raise (sig);
 }
@@ -175,10 +173,16 @@
 install_handlers ()
 {
   size_t i;
+  struct sigaction action;
 
+  action.sa_handler = &fatal_signal_handler;
+  /* One-shot handling - if we fault while handling a fault, the
+     cleanup actions are intentionally cut short.  */
+  action.sa_flags = SA_NODEFER | SA_RESETHAND;
+  sigemptyset (&action.sa_mask);
   for (i = 0; i < num_fatal_signals; i++)
     if (fatal_signals[i] >= 0)
-      signal (fatal_signals[i], &fatal_signal_handler);
+      sigaction (fatal_signals[i], &action, NULL);
 }
 
 
--- a/lib/nanosleep.c	Sat Jun 21 14:32:55 2008 -0600
+++ b/lib/nanosleep.c	Sat Jun 21 07:08:49 2008 -0600
@@ -22,6 +22,7 @@
 
 #include <time.h>
 
+#include "sig-handler.h"
 #include "timespec.h"
 
 #include <stdbool.h>
@@ -102,10 +103,6 @@
 #  define SIGCONT SIGTERM
 # endif
 
-# if ! HAVE_SIGINTERRUPT
-#  define siginterrupt(sig, flag) /* empty */
-# endif
-
 static sig_atomic_t volatile suspended;
 
 /* Handle SIGCONT. */
@@ -150,22 +147,14 @@
   /* set up sig handler */
   if (! initialized)
     {
-# ifdef SA_NOCLDSTOP
       struct sigaction oldact, newact;
       newact.sa_handler = sighandler;
       sigemptyset (&newact.sa_mask);
       newact.sa_flags = 0;
 
       sigaction (SIGCONT, NULL, &oldact);
-      if (oldact.sa_handler != SIG_IGN)
+      if (get_handler (&oldact) != SIG_IGN)
 	sigaction (SIGCONT, &newact, NULL);
-# else
-      if (signal (SIGCONT, SIG_IGN) != SIG_IGN)
-	{
-	  signal (SIGCONT, sighandler);
-	  siginterrupt (SIGCONT, 1);
-	}
-# endif
       initialized = true;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/sig-handler.h	Sat Jun 21 07:08:49 2008 -0600
@@ -0,0 +1,44 @@
+/* Convenience declarations when working with <signal.h>.
+
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_SIG_HANDLER_H
+#define _GL_SIG_HANDLER_H
+
+#include <signal.h>
+
+/* Convenience type when working with signal handlers.  */
+typedef void (*sa_handler_t) (int);
+
+/* Return the handler of a signal, as a sa_handler_t value regardless
+   of its true type.  The resulting function can be compared to
+   special values like SIG_IGN but it is not portable to call it.  */
+static inline sa_handler_t
+get_handler (struct sigaction const *a)
+{
+#ifdef SA_SIGINFO
+  /* POSIX says that special values like SIG_IGN can only occur when
+     action.sa_flags does not contain SA_SIGINFO.  But in Linux 2.4,
+     for example, sa_sigaction and sa_handler are aliases and a signal
+     is ignored if sa_sigaction (after casting) equals SIG_IGN.  So
+     use (and cast) sa_sigaction in that case.  */
+  if (a->sa_flags & SA_SIGINFO)
+    return (sa_handler_t) a->sa_sigaction;
+#endif
+  return a->sa_handler;
+}
+
+#endif /* _GL_SIG_HANDLER_H */
--- a/lib/sigprocmask.c	Sat Jun 21 14:32:55 2008 -0600
+++ b/lib/sigprocmask.c	Sat Jun 21 07:08:49 2008 -0600
@@ -24,6 +24,8 @@
 #include <stdint.h>
 #include <stdlib.h>
 
+#include "sig-handler.h"
+
 /* We assume that a platform without POSIX signal blocking functions
    also does not have the POSIX sigaction() function, only the
    signal() function.  We also assume signal() has SysV semantics,
@@ -43,9 +45,6 @@
 # define SIGSTOP (-1)
 #endif
 
-/* A signal handler.  */
-typedef void (*handler_t) (int signal);
-
 int
 sigismember (const sigset_t *set, int sig)
 {
@@ -134,7 +133,7 @@
 
 /* The previous signal handlers.
    Only the array elements corresponding to blocked signals are relevant.  */
-static volatile handler_t old_handlers[NSIG];
+static volatile sa_handler_t old_handlers[NSIG];
 
 int
 sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
@@ -208,8 +207,8 @@
 
 /* Install the handler FUNC for signal SIG, and return the previous
    handler.  */
-handler_t
-rpl_signal (int sig, handler_t handler)
+sa_handler_t
+rpl_signal (int sig, sa_handler_t handler)
 {
   /* We must provide a wrapper, so that a user can query what handler
      they installed even if that signal is currently blocked.  */
@@ -227,7 +226,7 @@
 	     stale information if it calls signal(B).  Oh well -
 	     signal handlers really shouldn't try to manipulate the
 	     installed handlers of unrelated signals.  */
-	  handler_t result = old_handlers[sig];
+	  sa_handler_t result = old_handlers[sig];
 	  old_handlers[sig] = handler;
 	  return result;
 	}
--- a/m4/nanosleep.m4	Sat Jun 21 14:32:55 2008 -0600
+++ b/m4/nanosleep.m4	Sat Jun 21 07:08:49 2008 -0600
@@ -1,12 +1,12 @@
-#serial 23
+#serial 24
 
 dnl From Jim Meyering.
 dnl Check for the nanosleep function.
 dnl If not found, use the supplied replacement.
 dnl
 
-# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 Free
-# Software Foundation, Inc.
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -111,6 +111,5 @@
 # Prerequisites of lib/nanosleep.c.
 AC_DEFUN([gl_PREREQ_NANOSLEEP],
 [
-  AC_CHECK_FUNCS_ONCE(siginterrupt)
   AC_CHECK_HEADERS_ONCE(sys/select.h)
 ])
--- a/modules/c-stack	Sat Jun 21 14:32:55 2008 -0600
+++ b/modules/c-stack	Sat Jun 21 07:08:49 2008 -0600
@@ -11,6 +11,7 @@
 exitfail
 unistd
 raise
+sigaction
 
 configure.ac:
 gl_C_STACK
--- a/modules/fatal-signal	Sat Jun 21 14:32:55 2008 -0600
+++ b/modules/fatal-signal	Sat Jun 21 07:08:49 2008 -0600
@@ -11,6 +11,7 @@
 xalloc
 stdbool
 unistd
+sigaction
 sigprocmask
 raise
 
--- a/modules/nanosleep	Sat Jun 21 14:32:55 2008 -0600
+++ b/modules/nanosleep	Sat Jun 21 07:08:49 2008 -0600
@@ -9,6 +9,7 @@
 clock-time
 extensions
 gettime
+sigaction
 stdbool
 sys_select
 sys_time
--- a/modules/sigaction	Sat Jun 21 14:32:55 2008 -0600
+++ b/modules/sigaction	Sat Jun 21 07:08:49 2008 -0600
@@ -3,6 +3,7 @@
 
 Files:
 lib/sigaction.c
+lib/sig-handler.h
 m4/sigaction.m4
 
 Depends-on:
--- a/modules/sigprocmask	Sat Jun 21 14:32:55 2008 -0600
+++ b/modules/sigprocmask	Sat Jun 21 07:08:49 2008 -0600
@@ -3,6 +3,7 @@
 
 Files:
 lib/sigprocmask.c
+lib/sig-handler.h
 m4/signalblocking.m4
 
 Depends-on: