From 9959096559df3014d18b1ab98943baca52ea90e6 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Fri, 26 Jul 2013 03:35:46 +0000 Subject: [PATCH] Handle signals better with -reincarnate If we receive SIGTERM or SIGILL we should propagate the signal to the child FS process. As FS normally handles these signals, we need to restore the handler before we refork. FS may also add a handler for SIGCHLD; we need the default action here instead for the parent. --- src/switch.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/switch.c b/src/switch.c index 6afdbcbd38..2a68db473c 100644 --- a/src/switch.c +++ b/src/switch.c @@ -357,11 +357,25 @@ static void daemonize(int *fds) return; } +static pid_t reincarnate_child = 0; +static void reincarnate_handle_sigterm (int sig) { + if (!sig) return; + if (reincarnate_child) kill(reincarnate_child, sig); + return; +} + static void reincarnate_protect(char **argv) { - int i; + int i; struct sigaction sa, sa_dfl, sa4_prev, sa15_prev, sa17_prev; + memset(&sa, 0, sizeof(sa)); memset(&sa_dfl, 0, sizeof(sa_dfl)); + sa.sa_handler = reincarnate_handle_sigterm; + sa_dfl.sa_handler = SIG_DFL; refork: if ((i=fork())) { /* parent */ int s; pid_t r; + reincarnate_child = i; + sigaction(SIGILL, &sa, &sa4_prev); + sigaction(SIGTERM, &sa, &sa15_prev); + sigaction(SIGCHLD, &sa_dfl, &sa17_prev); rewait: r = waitpid(i, &s, 0); if (r == (pid_t)-1) { @@ -375,6 +389,9 @@ static void reincarnate_protect(char **argv) { exit(WEXITSTATUS(s)); } if (WIFEXITED(s) || WIFSIGNALED(s)) { + sigaction(SIGILL, &sa4_prev, NULL); + sigaction(SIGTERM, &sa15_prev, NULL); + sigaction(SIGCHLD, &sa17_prev, NULL); if (argv) { execv(argv[0], argv); return; } else goto refork;