diff lib/fatal-signal.c @ 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 8c0d36d59e97
children 478a8cd21855
line wrap: on
line diff
--- a/lib/fatal-signal.c
+++ b/lib/fatal-signal.c
@@ -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);
 }