From 9fc3990e0420d528c5d917879f1f8fafa7dba7aa Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 3 Jul 2013 06:31:59 +0000 Subject: [PATCH] Add -reincarnate flag to FS When FS is given the -reincarnate flag, FS will be automatically restarted after any uncontrolled exit. --- src/switch.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/switch.c b/src/switch.c index cdd383f7a2..6afdbcbd38 100644 --- a/src/switch.c +++ b/src/switch.c @@ -357,6 +357,32 @@ static void daemonize(int *fds) return; } +static void reincarnate_protect(char **argv) { + int i; + refork: + if ((i=fork())) { /* parent */ + int s; pid_t r; + rewait: + r = waitpid(i, &s, 0); + if (r == (pid_t)-1) { + if (errno == EINTR) goto rewait; + exit(EXIT_FAILURE); + } + if (r != i) goto rewait; + if (WIFEXITED(s) + && (WEXITSTATUS(s) == EXIT_SUCCESS + || WEXITSTATUS(s) == EXIT_FAILURE)) { + exit(WEXITSTATUS(s)); + } + if (WIFEXITED(s) || WIFSIGNALED(s)) { + if (argv) { + execv(argv[0], argv); return; + } else goto refork; + } + goto rewait; + } +} + #endif static const char usage[] = @@ -369,6 +395,8 @@ static const char usage[] = "\t-monotonic-clock -- use monotonic clock as timer source\n" #else "\t-nf -- no forking\n" + "\t-reincarnate -- restart the switch on an uncontrolled exit\n" + "\t-reincarnate-reexec -- run execv on a restart (helpful for upgrades)\n" "\t-u [user] -- specify user to switch to\n" "\t-g [group] -- specify group to switch to\n" #endif @@ -437,6 +465,7 @@ int main(int argc, char *argv[]) switch_bool_t do_wait = SWITCH_FALSE; char *runas_user = NULL; char *runas_group = NULL; + switch_bool_t reincarnate = SWITCH_FALSE, reincarnate_reexec = SWITCH_FALSE; int fds[2] = { 0, 0 }; #else switch_bool_t win32_service = SWITCH_FALSE; @@ -612,6 +641,14 @@ int main(int argc, char *argv[]) nf = SWITCH_TRUE; } + else if (!strcmp(local_argv[x], "-reincarnate")) { + reincarnate = SWITCH_TRUE; + } + else if (!strcmp(local_argv[x], "-reincarnate-reexec")) { + reincarnate = SWITCH_TRUE; + reincarnate_reexec = SWITCH_TRUE; + } + else if (!strcmp(local_argv[x], "-version")) { fprintf(stdout, "FreeSWITCH version: %s (%s)\n", SWITCH_VERSION_FULL, SWITCH_VERSION_REVISION_HUMAN); exit(EXIT_SUCCESS); @@ -994,6 +1031,10 @@ int main(int argc, char *argv[]) } #endif } +#ifndef WIN32 + if (reincarnate) + reincarnate_protect(reincarnate_reexec ? argv : NULL); +#endif switch (priority) { case 2: