]> git.sesse.net Git - cubemap/blobdiff - main.cpp
Even more missing unistd.h includes.
[cubemap] / main.cpp
index 64ee29f55fb55b924eb0632935876b5a3cc56ef1..2771f3904048fc86fde47097ed0d50b463f89576 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
+#include <unistd.h>
 #include <assert.h>
 #include <getopt.h>
 #include <arpa/inet.h>
@@ -10,6 +11,8 @@
 #include <sys/ioctl.h>
 #include <sys/poll.h>
 #include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 #include <signal.h>
 #include <errno.h>
 #include <ctype.h>
@@ -241,19 +244,58 @@ void create_streams(const Config &config,
                }
        }
 }
+       
+bool dry_run_config(const std::string &argv0, const std::string &config_filename)
+{
+       char *argv0_copy = strdup(argv0.c_str());
+       char *config_filename_copy = strdup(config_filename.c_str());
+
+       pid_t pid = fork();
+       switch (pid) {
+       case -1:
+               perror("fork()");
+               free(argv0_copy);
+               free(config_filename_copy);
+               return false;
+       case 0:
+               // Child.
+               execlp(argv0_copy, argv0_copy, "--test-config", config_filename_copy, NULL);
+               perror(argv0_copy);
+               _exit(1);
+       default:
+               // Parent.
+               break;
+       }
+               
+       free(argv0_copy);
+       free(config_filename_copy);
+
+       int status;
+       pid_t err;
+       do {
+               err = waitpid(pid, &status, 0);
+       } while (err == -1 && errno == EINTR);
+
+       if (err == -1) {
+               perror("waitpid()");
+               return false;
+       }       
+
+       return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
+}
 
 int main(int argc, char **argv)
 {
-       fprintf(stderr, "\nCubemap " SERVER_VERSION " starting.\n");
-
        // Parse options.
        int state_fd = -1;
+       bool test_config = false;
        for ( ;; ) {
                static const option long_options[] = {
                        { "state", required_argument, 0, 's' },
+                       { "test-config", no_argument, 0, 't' },
                };
                int option_index = 0;
-               int c = getopt_long (argc, argv, "s:", long_options, &option_index);
+               int c = getopt_long (argc, argv, "s:t", long_options, &option_index);
      
                if (c == -1) {
                        break;
@@ -262,6 +304,9 @@ int main(int argc, char **argv)
                case 's':
                        state_fd = atoi(optarg);
                        break;
+               case 't':
+                       test_config = true;
+                       break;
                default:
                        assert(false);
                }
@@ -272,16 +317,20 @@ int main(int argc, char **argv)
                config_filename = argv[optind++];
        }
 
-       struct timeval serialize_start;
-
        Config config;
        if (!parse_config(config_filename, &config)) {
                exit(1);
        }
+       if (test_config) {
+               exit(0);
+       }
 
+start:
+       fprintf(stderr, "\nCubemap " SERVER_VERSION " starting.\n");
        servers = new ServerPool(config.num_servers);
 
        CubemapStateProto loaded_state;
+       struct timeval serialize_start;
        set<string> deserialized_stream_ids;
        map<string, Input *> deserialized_inputs;
        map<int, Acceptor *> deserialized_acceptors;
@@ -305,13 +354,6 @@ int main(int argc, char **argv)
                                create_input(loaded_state.inputs(i))));
                } 
 
-               // Convert the acceptor from older serialized formats.
-               if (loaded_state.has_server_sock() && loaded_state.has_port()) {
-                       AcceptorProto *acceptor = loaded_state.add_acceptors();
-                       acceptor->set_server_sock(loaded_state.server_sock());
-                       acceptor->set_port(loaded_state.port());
-               }
-
                // Deserialize the acceptors.
                for (int i = 0; i < loaded_state.acceptors_size(); ++i) {
                        deserialized_acceptors.insert(make_pair(
@@ -384,6 +426,12 @@ int main(int argc, char **argv)
        state_fd = make_tempfile(collect_state(
                serialize_start, acceptors, inputs, servers));
        delete servers;
+
+       if (!dry_run_config(argv[0], config_filename)) {
+               fprintf(stderr, "ERROR: %s --test-config failed. Restarting old version instead of new.\n", argv[0]);
+               hupped = false;
+               goto start;
+       }
         
        char buf[16];
        sprintf(buf, "%d", state_fd);