]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Add -reincarnate flag to FS
authorTravis Cross <tc@traviscross.com>
Wed, 3 Jul 2013 06:31:59 +0000 (06:31 +0000)
committerTravis Cross <tc@traviscross.com>
Fri, 26 Jul 2013 17:30:01 +0000 (17:30 +0000)
When FS is given the -reincarnate flag, FS will be automatically
restarted after any uncontrolled exit.

src/switch.c

index cdd383f7a2f2cb307cacfe5d657a81bc0a77db79..6afdbcbd382446588e42acd0aca6bad1f81babae 100644 (file)
@@ -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: