From bce2937acead6988b0f0b84b2b339f1fd8d54122 Mon Sep 17 00:00:00 2001 From: Pierre-Marc Fournier Date: Tue, 13 Oct 2009 17:55:01 -0400 Subject: [PATCH] ustd: add daemon mode --- ustd/ustd.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++----- usttrace | 5 ++- 2 files changed, 93 insertions(+), 9 deletions(-) diff --git a/ustd/ustd.c b/ustd/ustd.c index 2393ea3..0019776 100644 --- a/ustd/ustd.c +++ b/ustd/ustd.c @@ -52,6 +52,7 @@ char *sock_path=NULL; char *trace_path=NULL; +int daemon_mode = 0; /* 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,9 @@ int parse_args(int argc, char **argv) return -1; } break; + case 'd': + daemon_mode = 1; + break; case 'h': usage(); exit(0); @@ -531,7 +538,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 +559,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 +582,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 +649,64 @@ int main(int argc, char **argv) return 0; } + +int start_ustd_daemon() +{ + int result; + int fd[2]; + + result = pipe(fd); + + result = fork(); + if(result == -1) { + PERROR("fork"); + return -1; + } + else if(result == 0) { + return start_ustd(fd[1]); + } + else { + char buf; + + 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; +} diff --git a/usttrace b/usttrace index e8ab13c..cb94640 100755 --- a/usttrace +++ b/usttrace @@ -79,7 +79,10 @@ fi # Wait for the daemon to settle # If we don't, the process may try to connect to its socket before # it's ready. -# FIXME: is there a way to make sure this works every time? +# FIXME: is there a way to make sure this works every time? Yes, +# we could have a mode where ustd daemonizes itself. Therefore +# by the time the control returns to the console, it's ready. + sleep 0.5 # Establish the environment for the command -- 2.34.1