Add ability to run fatal signal hooks upon normal termination too.

This is convenient since in many cases we want these hooks to run in
both cases.
This commit is contained in:
Ben Pfaff committed 2008-08-28 14:24:39 -07:00
1 parent 7129a314b2
commit 3cc1ae6a32
5 files changed
+37 -16

No files matched your search

+3 -1
View File
@@ -34,8 +34,10 @@
#ifndef FATAL_SIGNAL_H
#define FATAL_SIGNAL_H 1
#include <stdbool.h>
/* Basic interface. */
void fatal_signal_add_hook(void (*)(void *aux), void *aux);
void fatal_signal_add_hook(void (*)(void *aux), void *aux, bool run_at_exit);
void fatal_signal_block(void);
void fatal_signal_unblock(void);
void fatal_signal_fork(void);
+31 -12
View 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];
@@ -64,16 +65,20 @@ 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 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();
}
@@ -107,6 +112,7 @@ fatal_signal_block()
fatal(errno, "signal");
}
}
atexit(atexit_handler);
}
if (++block_level == 1) {
@@ -138,6 +144,23 @@ 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)
{
call_hooks(0);
}
static void
call_hooks(int sig_nr)
{
volatile sig_atomic_t recurse = 0;
if (!recurse) {
@@ -145,16 +168,13 @@ 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);
}
static char **files;
@@ -172,8 +192,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();
+1 -1
View File
@@ -770,7 +770,7 @@ init_netdev(void)
static bool inited;
if (!inited) {
inited = true;
fatal_signal_add_hook(restore_all_flags, NULL);
fatal_signal_add_hook(restore_all_flags, NULL, true);
af_inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
if (af_inet_sock < 0) {
fatal(errno, "socket(AF_INET)");
+1 -1
View File
@@ -84,7 +84,7 @@ main(int argc, char *argv[])
fatal(error, "dhclient_create failed");
}
dhclient_init(cli, request_ip.s_addr);
fatal_signal_add_hook(release, cli);
fatal_signal_add_hook(release, cli, true);
for (;;) {
fatal_signal_block();
+1 -1
View File
@@ -117,7 +117,7 @@ main(int argc, char *argv[])
struct iface *iface = &ifaces[i];
dhclient_init(iface->dhcp, 0);
}
fatal_signal_add_hook(release_ifaces, NULL);
fatal_signal_add_hook(release_ifaces, NULL, true);
retval = regcomp(&accept_controller_regex, accept_controller_re,
REG_NOSUB | REG_EXTENDED);