implement daemonizing
authorLennart Poettering <lennart@poettering.net>
Thu, 15 Jul 2004 19:00:42 +0000 (19:00 +0000)
committerLennart Poettering <lennart@poettering.net>
Thu, 15 Jul 2004 19:00:42 +0000 (19:00 +0000)
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@69 fefdeb5f-60dc-0310-8127-8f9354f1896f

src/main.c
src/todo

index d2ae61c909e7bf7df3d382615bc14557c741d407..9e2e006648f0c7521225eefb5b0d4eba65225fd0 100644 (file)
@@ -1,3 +1,6 @@
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <signal.h>
@@ -12,6 +15,8 @@
 #include "mainloop-signal.h"
 #include "cmdline.h"
 #include "cli-command.h"
+#include "util.h"
+#include "sioman.h"
 
 static struct pa_mainloop *mainloop;
 
@@ -27,22 +32,70 @@ static void aux_signal_callback(void *id, int sig, void *userdata) {
     pa_module_load(c, sig == SIGUSR1 ? "module-cli" : "module-cli-protocol-unix", NULL);
 }
 
+static void close_pipe(int p[2]) {
+    if (p[0] != -1)
+        close(p[0]);
+    if (p[1] != -1)
+        close(p[1]);
+    p[0] = p[1] = -1;
+}
+
 int main(int argc, char *argv[]) {
     struct pa_core *c;
     struct pa_cmdline *cmdline = NULL;
     struct pa_strbuf *buf = NULL;
     char *s;
-    int r, retval = 0;
+    int r, retval = 1;
+    int daemon_pipe[2] = { -1, -1 };
 
     if (!(cmdline = pa_cmdline_parse(argc, argv))) {
         fprintf(stderr, __FILE__": failed to parse command line.\n");
-        return 1;
+        goto finish;
     }
 
     if (cmdline->help) {
         pa_cmdline_help(argv[0]);
-        pa_cmdline_free(cmdline);
-        return 0;
+        retval = 0;
+        goto finish;
+    }
+
+    if (cmdline->daemonize) {
+        pid_t child;
+
+        if (pa_stdio_acquire() < 0) {
+            fprintf(stderr, __FILE__": failed to acquire stdio.\n");
+            goto finish;
+        }
+
+        if (pipe(daemon_pipe) < 0) {
+            fprintf(stderr, __FILE__": failed to create pipe.\n");
+            goto finish;
+        }
+        
+        if ((child = fork()) < 0) {
+            fprintf(stderr, __FILE__": fork() failed: %s\n", strerror(errno));
+            goto finish;
+        }
+
+        if (child != 0) {
+            /* Father */
+
+            close(daemon_pipe[1]);
+            daemon_pipe[1] = -1;
+
+            if (pa_loop_read(daemon_pipe[0], &retval, sizeof(retval)) != sizeof(retval)) {
+                fprintf(stderr, __FILE__": read() failed: %s\n", strerror(errno));
+                retval = 1;
+            }
+
+            goto finish;
+        }
+
+        close(daemon_pipe[0]);
+        daemon_pipe[0] = -1;
+        
+        setsid();
+        setpgrp();
     }
     
     r = lt_dlinit();
@@ -59,18 +112,6 @@ int main(int argc, char *argv[]) {
     c = pa_core_new(pa_mainloop_get_api(mainloop));
     assert(c);
     
-/*    pa_module_load(c, "module-oss-mmap", "device=/dev/dsp playback=1 record=1");
-    pa_module_load(c, "module-oss-mmap", "/dev/dsp1");
-    pa_module_load(c, "module-pipe-sink", NULL);
-    pa_module_load(c, "module-simple-protocol-tcp", NULL);
-    pa_module_load(c, "module-simple-protocol-unix", NULL);
-    pa_module_load(c, "module-cli-protocol-tcp", NULL);
-    pa_module_load(c, "module-cli-protocol-unix", NULL);
-    pa_module_load(c, "module-native-protocol-tcp", NULL);
-    pa_module_load(c, "module-native-protocol-unix", NULL);
-    pa_module_load(c, "module-esound-protocol-tcp", NULL);
-    pa_module_load(c, "module-cli", NULL);*/
-
     pa_signal_register(SIGUSR1, aux_signal_callback, c);
     pa_signal_register(SIGUSR2, aux_signal_callback, c);
 
@@ -82,26 +123,35 @@ int main(int argc, char *argv[]) {
     
     if (r < 0 && cmdline->fail) {
         fprintf(stderr, __FILE__": failed to initialize daemon.\n");
-        retval = 1;
+        if (cmdline->daemonize)
+            pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
     } else if (!c->modules || pa_idxset_ncontents(c->modules) == 0) {
         fprintf(stderr, __FILE__": daemon startup without any loaded modules, refusing to work.\n");
-        retval = 1;
+        if (cmdline->daemonize)
+            pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
     } else {
+        retval = 0;
+        if (cmdline->daemonize)
+            pa_loop_write(daemon_pipe[1], &retval, sizeof(retval));
         fprintf(stderr, __FILE__": mainloop entry.\n");
         if (pa_mainloop_run(mainloop, &retval) < 0)
             retval = 1;
         fprintf(stderr, __FILE__": mainloop exit.\n");
     }
-
         
     pa_core_free(c);
 
     pa_signal_done();
     pa_mainloop_free(mainloop);
     
-    pa_cmdline_free(cmdline);
-
     lt_dlexit();
+
+finish:
+
+    if (cmdline)
+        pa_cmdline_free(cmdline);
+
+    close_pipe(daemon_pipe);
     
     return retval;
 }
index 5e90dfdae7a8704a1566f1a03d243d958eb9ebe5..963b57fda66f857da89520c7337b93b788bd906f 100644 (file)
--- a/src/todo
+++ b/src/todo
@@ -25,7 +25,6 @@
 - doxygen
 - make mcalign merge chunks
 - modinfo
-- daemonizing
 
 drivers:
 - libao