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[] =
"\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
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;
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);
}
#endif
}
+#ifndef WIN32
+ if (reincarnate)
+ reincarnate_protect(reincarnate_reexec ? argv : NULL);
+#endif
switch (priority) {
case 2: