From: Travis Cross Date: Fri, 26 Jul 2013 03:35:46 +0000 (+0000) Subject: Handle signals better with -reincarnate X-Git-Tag: v1.4.1~19^2~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9959096559df3014d18b1ab98943baca52ea90e6;p=thirdparty%2Ffreeswitch.git 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. --- 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;