diff options
-rw-r--r-- | lib/signals.c | 21 | ||||
-rw-r--r-- | lib/signals.h | 3 | ||||
-rw-r--r-- | vswitchd/ovs-vswitchd.c | 1 |
3 files changed, 21 insertions, 4 deletions
diff --git a/lib/signals.c b/lib/signals.c index 37f063732..7650cb9b0 100644 --- a/lib/signals.c +++ b/lib/signals.c @@ -20,6 +20,7 @@ #include <errno.h> #include <limits.h> #include <signal.h> +#include <stdlib.h> #include <unistd.h> #include "poll-loop.h" #include "socket-util.h" @@ -40,6 +41,7 @@ VLOG_DEFINE_THIS_MODULE(signals); #endif struct signal { + struct sigaction saved_sa; int signr; }; @@ -78,20 +80,31 @@ signal_register(int signr) signal_init(); + s = xmalloc(sizeof *s); + s->signr = signr; + /* Set up signal handler. */ assert(signr >= 1 && signr < N_SIGNALS); memset(&sa, 0, sizeof sa); sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; - xsigaction(signr, &sa, NULL); + xsigaction(signr, &sa, &s->saved_sa); - /* Return structure. */ - s = xmalloc(sizeof *s); - s->signr = signr; return s; } +/* Unregisters the handler for 's', restores the signal handler that was in + * effect before signal_register() was called, and frees 's'. */ +void +signal_unregister(struct signal *s) +{ + if (s) { + xsigaction(s->signr, &s->saved_sa, NULL); + free(s); + } +} + /* Returns true if signal 's' has been received since the last call to this * function with argument 's'. */ bool diff --git a/lib/signals.h b/lib/signals.h index 12fb31139..e09b04a0a 100644 --- a/lib/signals.h +++ b/lib/signals.h @@ -21,7 +21,10 @@ #include <stdbool.h> void signal_init(void); + struct signal *signal_register(int signr); +void signal_unregister(struct signal *); + bool signal_poll(struct signal *); void signal_wait(struct signal *); diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c index d591e951e..a71eecccc 100644 --- a/vswitchd/ovs-vswitchd.c +++ b/vswitchd/ovs-vswitchd.c @@ -102,6 +102,7 @@ main(int argc, char *argv[]) } bridge_exit(); unixctl_server_destroy(unixctl); + signal_unregister(sighup); return 0; } |