Fix lib/dhparams.c build failure fallout from earlier build system changes.
[sliver-openvswitch.git] / lib / fatal-signal.c
index d299cdf..ac9e2a5 100644 (file)
@@ -52,6 +52,7 @@ static sigset_t fatal_signal_set;
 struct hook {
     void (*func)(void *aux);
     void *aux;
+    bool run_at_exit;
 };
 #define MAX_HOOKS 32
 static struct hook hooks[MAX_HOOKS];
@@ -63,17 +64,24 @@ static int block_level = 0;
 /* Signal mask saved by outermost signal blocker. */
 static sigset_t saved_signal_mask;
 
+/* Disabled by fatal_signal_fork()? */
+static bool disabled;
+
 static void call_sigprocmask(int how, sigset_t* new_set, sigset_t* old_set);
+static void atexit_handler(void);
+static void call_hooks(int sig_nr);
 
-/* Registers 'hook' to be called when a process termination signal is
- * raised. */
+/* Registers 'hook' to be called when a process termination signal is raised.
+ * If 'run_at_exit' is true, 'hook' is also called during normal process
+ * termination, e.g. when exit() is called or when main() returns. */
 void
-fatal_signal_add_hook(void (*func)(void *aux), void *aux)
+fatal_signal_add_hook(void (*func)(void *aux), void *aux, bool run_at_exit)
 {
     fatal_signal_block();
     assert(n_hooks < MAX_HOOKS);
     hooks[n_hooks].func = func;
     hooks[n_hooks].aux = aux;
+    hooks[n_hooks].run_at_exit = run_at_exit;
     n_hooks++;
     fatal_signal_unblock();
 }
@@ -100,13 +108,14 @@ fatal_signal_block()
 
             sigaddset(&fatal_signal_set, sig_nr);
             if (sigaction(sig_nr, NULL, &old_sa)) {
-                fatal(errno, "sigaction");
+                ofp_fatal(errno, "sigaction");
             }
             if (old_sa.sa_handler == SIG_DFL
                 && signal(sig_nr, fatal_signal_handler) == SIG_ERR) {
-                fatal(errno, "signal");
+                ofp_fatal(errno, "signal");
             }
         }
+        atexit(atexit_handler);
     }
 
     if (++block_level == 1) {
@@ -138,6 +147,25 @@ fatal_signal_unblock()
  * handler in the case where the signal has its default handling.)  */
 void
 fatal_signal_handler(int sig_nr)
+{
+    call_hooks(sig_nr);
+
+    /* 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);
+}
+
+static void
+atexit_handler(void)
+{
+    if (!disabled) {
+        call_hooks(0);
+    }
+}
+
+static void
+call_hooks(int sig_nr)
 {
     volatile sig_atomic_t recurse = 0;
     if (!recurse) {
@@ -145,21 +173,17 @@ fatal_signal_handler(int sig_nr)
 
         recurse = 1;
 
-        /* Call all the hooks. */
         for (i = 0; i < n_hooks; i++) {
-            hooks[i].func(hooks[i].aux);
+            struct hook *h = &hooks[i];
+            if (sig_nr || h->run_at_exit) {
+                h->func(h->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;
-static bool disabled;
 
 static void unlink_files(void *aux);
 static void do_unlink_files(void);
@@ -172,8 +196,7 @@ fatal_signal_add_file_to_unlink(const char *file)
     static bool added_hook = false;
     if (!added_hook) {
         added_hook = true;
-        fatal_signal_add_hook(unlink_files, NULL);
-        atexit(do_unlink_files);
+        fatal_signal_add_hook(unlink_files, NULL, true);
     }
 
     fatal_signal_block();
@@ -212,12 +235,10 @@ unlink_files(void *aux UNUSED)
 static void
 do_unlink_files(void)
 {
-    if (!disabled) {
-        size_t i;
+    size_t i;
 
-        for (i = 0; i < n_files; i++) {
-            unlink(files[i]);
-        }
+    for (i = 0; i < n_files; i++) {
+        unlink(files[i]);
     }
 }
 \f