Move kernelcompat.h to include/ust/ and share.h, usterr.h to include/
[ust.git] / ustd / ustd.c
index 2393ea3d45b5befa4c01cc628eeb57279b48cea4..0026c3b12a88816392df29447289d48404656d16 100644 (file)
@@ -33,9 +33,8 @@
 #include <getopt.h>
 
 #include "ustd.h"
-#include "localerr.h"
+#include "usterr.h"
 #include "ustcomm.h"
-#include "share.h"
 
 /* return value: 0 = subbuffer is finished, it won't produce data anymore
  *               1 = got subbuffer successfully
@@ -52,6 +51,8 @@
 
 char *sock_path=NULL;
 char *trace_path=NULL;
+int daemon_mode = 0;
+char *pidfile = NULL;
 
 /* Number of active buffers and the mutex to protect it. */
 int active_buffers = 0;
@@ -473,7 +474,9 @@ void usage(void)
        fprintf(stderr, "Usage:\nustd OPTIONS\n\nOptions:\n"
                        "\t-h\t\tDisplay this usage.\n"
                        "\t-o DIR\t\tSpecify the directory where to output the traces.\n"
-                       "\t-s PATH\t\tSpecify the path to use for the daemon socket.\n");
+                       "\t-s PATH\t\tSpecify the path to use for the daemon socket.\n"
+                       "\t-d\t\tStart as a daemon.\n"
+                       "\t--pidfile FILE\tWrite the PID in this file (when using -d).\n");
 }
 
 int parse_args(int argc, char **argv)
@@ -483,12 +486,13 @@ int parse_args(int argc, char **argv)
        while (1) {
                int option_index = 0;
                static struct option long_options[] = {
+                       {"pidfile", 1, 0, 'p'},
                        {"help", 0, 0, 'h'},
                        {"version", 0, 0, 'V'},
                        {0, 0, 0, 0}
                };
 
-               c = getopt_long(argc, argv, "hs:o:", long_options, &option_index);
+               c = getopt_long(argc, argv, "hs:o:d", long_options, &option_index);
                if (c == -1)
                        break;
 
@@ -509,6 +513,12 @@ int parse_args(int argc, char **argv)
                                return -1;
                        }
                        break;
+               case 'd':
+                       daemon_mode = 1;
+                       break;
+               case 'p':
+                       pidfile = strdup(optarg);
+                       break;
                case 'h':
                        usage();
                        exit(0);
@@ -531,7 +541,7 @@ void sigterm_handler(int sig)
        terminate_req = 1;
 }
 
-int main(int argc, char **argv)
+int start_ustd(int fd)
 {
        struct ustcomm_ustd ustd;
        int result;
@@ -552,11 +562,6 @@ int main(int argc, char **argv)
                return 1;
        }
 
-       result = parse_args(argc, argv);
-       if(result == -1) {
-               exit(1);
-       }
-
        result = ustcomm_init_ustd(&ustd, sock_path);
        if(result == -1) {
                ERR("failed to initialize socket");
@@ -580,6 +585,24 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       /* Notify parent that we are successfully started. */
+       if(fd != -1) {
+               /* write any one character */
+               result = write(fd, "!", 1);
+               if(result == -1) {
+                       PERROR("write");
+                       return -1;
+               }
+               if(result != 1) {
+                       ERR("Problem sending confirmation of daemon start to parent");
+                       return -1;
+               }
+               result = close(fd);
+               if(result == -1) {
+                       PERROR("close");
+               }
+       }
+
        /* app loop */
        for(;;) {
                char *recvbuf;
@@ -629,3 +652,86 @@ int main(int argc, char **argv)
 
        return 0;
 }
+
+int start_ustd_daemon()
+{
+       int result;
+       int fd[2];
+       pid_t child_pid;
+
+       result = pipe(fd);
+
+       result = child_pid = fork();
+       if(result == -1) {
+               PERROR("fork");
+               return -1;
+       }
+       else if(result == 0) {
+               return start_ustd(fd[1]);
+       }
+       else {
+               char buf;
+               FILE *pidfp;
+
+               /* It's important to write the file *before*
+                * the parent ends, because the file may be
+                * read as soon as the parent ends.
+                */
+               if(pidfile) {
+                       pidfp = fopen(pidfile, "w+");
+                       if(!pidfp) {
+                               PERROR("fopen (%s)", pidfile);
+                               WARN("killing child process");
+                               result = kill(child_pid, SIGTERM);
+                               if(result == -1) {
+                                       PERROR("kill");
+                               }
+                               return -1;
+                       }
+
+                       fprintf(pidfp, "%d\n", child_pid);
+                       fclose(pidfp);
+               }
+
+               result = read(fd[0], &buf, 1);
+               if(result == -1) {
+                       PERROR("read");
+                       return -1;
+               }
+               if(result != 1) {
+                       ERR("did not receive valid confirmation that the daemon is started");
+                       return -1;
+               }
+
+               result = close(fd[0]);
+               if(result == -1) {
+                       PERROR("close");
+               }
+
+               DBG("The daemon is now successfully started");
+       }
+
+       /* Wait for confirmation that the server is ready. */
+
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       int result;
+
+       result = parse_args(argc, argv);
+       if(result == -1) {
+               exit(1);
+       }
+
+       if(daemon_mode) {
+               result = start_ustd_daemon();
+       }
+       else {
+               result = start_ustd(-1);
+       }
+
+       return result;
+}
This page took 0.025441 seconds and 4 git commands to generate.