New functions ds_truncate(), ds_last().
[sliver-openvswitch.git] / lib / fatal-signal.c
index 33bc594..d299cdf 100644 (file)
@@ -43,7 +43,7 @@
 #include "util.h"
 
 /* Signals to catch. */
-static const int fatal_signals[] = { SIGTERM, SIGINT, SIGHUP };
+static const int fatal_signals[] = { SIGTERM, SIGINT, SIGHUP, SIGALRM };
 
 /* Signals to catch as a sigset_t. */
 static sigset_t fatal_signal_set;
@@ -64,7 +64,6 @@ static int block_level = 0;
 static sigset_t saved_signal_mask;
 
 static void call_sigprocmask(int how, sigset_t* new_set, sigset_t* old_set);
-static void signal_handler(int sig_nr);
 
 /* Registers 'hook' to be called when a process termination signal is
  * raised. */
@@ -97,9 +96,15 @@ fatal_signal_block()
         sigemptyset(&fatal_signal_set);
         for (i = 0; i < ARRAY_SIZE(fatal_signals); i++) {
             int sig_nr = fatal_signals[i];
+            struct sigaction old_sa;
+
             sigaddset(&fatal_signal_set, sig_nr);
-            if (signal(sig_nr, signal_handler) == SIG_IGN) {
-                signal(sig_nr, SIG_IGN);
+            if (sigaction(sig_nr, NULL, &old_sa)) {
+                fatal(errno, "sigaction");
+            }
+            if (old_sa.sa_handler == SIG_DFL
+                && signal(sig_nr, fatal_signal_handler) == SIG_ERR) {
+                fatal(errno, "signal");
             }
         }
     }
@@ -121,6 +126,36 @@ fatal_signal_unblock()
         call_sigprocmask(SIG_SETMASK, &saved_signal_mask, NULL);
     }
 }
+
+/* Handles fatal signal number 'sig_nr'.
+ *
+ * Ordinarily this is the actual signal handler.  When other code needs to
+ * handle one of our signals, however, it can register for that signal and, if
+ * and when necessary, call this function to do fatal signal processing for it
+ * and terminate the process.  Currently only timeval.c does this, for SIGALRM.
+ * (It is not important whether the other code sets up its signal handler
+ * before or after this file, because this file will only set up a signal
+ * handler in the case where the signal has its default handling.)  */
+void
+fatal_signal_handler(int sig_nr)
+{
+    volatile sig_atomic_t recurse = 0;
+    if (!recurse) {
+        size_t i;
+
+        recurse = 1;
+
+        /* Call all the hooks. */
+        for (i = 0; i < n_hooks; i++) {
+            hooks[i].func(hooks[i].aux);
+        }
+    }
+
+    /* Re-raise the signal with the default handling so that the program
+     * termination status reflects that we were killed by this signal */
+    signal(sig_nr, SIG_DFL);
+    raise(sig_nr);
+}
 \f
 static char **files;
 static size_t n_files, max_files;
@@ -213,24 +248,3 @@ call_sigprocmask(int how, sigset_t* new_set, sigset_t* old_set)
         fprintf(stderr, "sigprocmask: %s\n", strerror(errno));
     }
 }
-
-static void
-signal_handler(int sig_nr)
-{
-    volatile sig_atomic_t recurse = 0;
-    if (!recurse) {
-        size_t i;
-
-        recurse = 1;
-
-        /* Call all the hooks. */
-        for (i = 0; i < n_hooks; i++) {
-            hooks[i].func(hooks[i].aux);
-        }
-    }
-
-    /* Re-raise the signal with the default handling so that the program
-     * termination status reflects that we were killed by this signal */
-    signal(sig_nr, SIG_DFL);
-    raise(sig_nr);
-}