]> code.delx.au - pulseaudio/commitdiff
add new switch --start to the PA binary which allows starting PA if it is not running...
authorLennart Poettering <lennart@poettering.net>
Wed, 11 Jun 2008 17:38:50 +0000 (17:38 +0000)
committerLennart Poettering <lennart@poettering.net>
Wed, 11 Jun 2008 17:38:50 +0000 (17:38 +0000)
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2513 fefdeb5f-60dc-0310-8127-8f9354f1896f

man/pulseaudio.1.xml.in
src/daemon/cmdline.c
src/daemon/daemon-conf.h
src/daemon/main.c
src/pulsecore/pid.c

index 1f53a60b69d8db74e3a59d1efece00c52d8e519c..5988c12db9a99c4b3895c6d5c381ae9e90e5df5b 100644 (file)
@@ -33,6 +33,7 @@ USA.
     <cmd>pulseaudio <opt>--dump-modules</opt></cmd>
     <cmd>pulseaudio <opt>--dump-resample-methods</opt></cmd>
     <cmd>pulseaudio <opt>--cleanup-shm</opt></cmd>
+    <cmd>pulseaudio <opt>--start</opt></cmd>
     <cmd>pulseaudio <opt>--kill</opt></cmd>
     <cmd>pulseaudio <opt>--check</opt></cmd>
   </synopsis>
@@ -90,6 +91,16 @@ USA.
       (e.g. Linux).</p></optdesc>
     </option>
 
+    <option>
+      <p><opt>--start</opt></p>
+
+      <optdesc><p>Start PulseAudio if it is not running yet. This is
+      different from starting PulseAudio without <opt>--start</opt>
+      which would fail if PA is already running. PulseAudio is
+      guaranteed to be fully initialized when this call
+      returns. Implies <opt>--daemon</p>.</optdesc>
+    </option>
+
     <option>
       <p><opt>-k | --kill</opt></p>
 
index 97c75f3711bcc936e418271a72fe4d88e0a006db..03b1ac7819cedab3554435c07c6a786534a40cfa 100644 (file)
@@ -66,7 +66,8 @@ enum {
     ARG_DISABLE_SHM,
     ARG_DUMP_RESAMPLE_METHODS,
     ARG_SYSTEM,
-    ARG_CLEANUP_SHM
+    ARG_CLEANUP_SHM,
+    ARG_START
 };
 
 /* Tabel for getopt_long() */
@@ -91,6 +92,7 @@ static const struct option long_options[] = {
     {"dl-search-path",              1, 0, ARG_DL_SEARCH_PATH},
     {"resample-method",             1, 0, ARG_RESAMPLE_METHOD},
     {"kill",                        0, 0, ARG_KILL},
+    {"start",                       0, 0, ARG_START},
     {"use-pid-file",                2, 0, ARG_USE_PID_FILE},
     {"check",                       0, 0, ARG_CHECK},
     {"system",                      2, 0, ARG_SYSTEM},
@@ -119,6 +121,7 @@ void pa_cmdline_help(const char *argv0) {
            "      --dump-modules                    Dump list of available modules\n"
            "      --dump-resample-methods           Dump available resample methods\n"
            "      --cleanup-shm                     Cleanup stale shared memory segments\n"
+           "      --start                           Start the daemon if it is not running\n"
            "  -k  --kill                            Kill a running daemon\n"
            "      --check                           Check for a running daemon\n\n"
 
@@ -207,6 +210,11 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
                 conf->cmd = PA_CMD_KILL;
                 break;
 
+            case ARG_START:
+                conf->cmd = PA_CMD_START;
+                conf->daemonize = TRUE;
+                break;
+
             case ARG_CHECK:
                 conf->cmd = PA_CMD_CHECK;
                 break;
index 03a756619db0cd5161ee74261a75dd9efdfad5f2..373924acfd821c08afeaefb51ed269cc63ed7e49 100644 (file)
@@ -37,6 +37,7 @@
 /* The actual command to execute */
 typedef enum pa_daemon_conf_cmd {
     PA_CMD_DAEMON,  /* the default */
+    PA_CMD_START,
     PA_CMD_HELP,
     PA_CMD_VERSION,
     PA_CMD_DUMP_CONF,
index 6e5997cf67827d6bf189e63f1d1ab8e0525723ea..d4c16fef79c75e459e856827d29dc1de5b678ae9 100644 (file)
@@ -96,6 +96,8 @@
 #include "ltdl-bind-now.h"
 #include "polkit.h"
 
+#define AUTOSPAWN_LOCK "autospawn.lock"
+
 #ifdef HAVE_LIBWRAP
 /* Only one instance of these variables */
 int allow_severity = LOG_INFO;
@@ -344,6 +346,8 @@ int main(int argc, char *argv[]) {
     pa_time_event *win32_timer;
     struct timeval win32_tv;
 #endif
+    char *lf = NULL;
+    int autospawn_lock_fd = -1;
 
 #if defined(__linux__) && defined(__OPTIMIZE__)
     /*
@@ -486,13 +490,13 @@ int main(int argc, char *argv[]) {
     if (conf->high_priority && !pa_can_high_priority())
         pa_log_warn("High-priority scheduling enabled in configuration but not allowed by policy.");
 
-    if (conf->high_priority && conf->cmd == PA_CMD_DAEMON)
+    if (conf->high_priority && (conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START))
         pa_raise_priority(conf->nice_level);
 
     if (suid_root) {
         pa_bool_t drop;
 
-        drop = conf->cmd != PA_CMD_DAEMON || !conf->realtime_scheduling;
+        drop = (conf->cmd != PA_CMD_DAEMON && conf->cmd != PA_CMD_START) || !conf->realtime_scheduling;
 
 #ifdef RLIMIT_RTPRIO
         if (!drop) {
@@ -608,7 +612,7 @@ int main(int argc, char *argv[]) {
             goto finish;
 
         default:
-            pa_assert(conf->cmd == PA_CMD_DAEMON);
+            pa_assert(conf->cmd == PA_CMD_DAEMON || conf->cmd == PA_CMD_START);
     }
 
     if (real_root && !conf->system_instance)
@@ -618,6 +622,15 @@ int main(int argc, char *argv[]) {
         goto finish;
     }
 
+    if (conf->cmd == PA_CMD_START) {
+        /* If we shall start PA only when it is not running yet, we
+         * first take the autospawn lock to make things
+         * synchronous. */
+
+        lf = pa_runtime_path(AUTOSPAWN_LOCK);
+        autospawn_lock_fd = pa_lock_lockfile(lf);
+    }
+
     if (conf->daemonize) {
         pid_t child;
         int tty_fd;
@@ -661,6 +674,14 @@ int main(int argc, char *argv[]) {
             goto finish;
         }
 
+        if (autospawn_lock_fd >= 0) {
+            /* The lock file is unlocked from the parent, so we need
+             * to close it in the child */
+
+            pa_close(autospawn_lock_fd);
+            autospawn_lock_fd = -1;
+        }
+
         pa_assert_se(pa_close(daemon_pipe[0]) == 0);
         daemon_pipe[0] = -1;
 #endif
@@ -728,7 +749,20 @@ int main(int argc, char *argv[]) {
     pa_log_info("Running in system mode: %s", pa_yes_no(pa_in_system_mode()));
 
     if (conf->use_pid_file) {
-        if (pa_pid_file_create("pulseaudio") < 0) {
+        int z;
+
+        if ((z = pa_pid_file_create("pulseaudio")) != 0) {
+
+            if (conf->cmd == PA_CMD_START && z > 0) {
+                /* If we are already running and with are run in
+                 * --start mode, then let's return this as success. */
+
+                pa_log_info("z=%i rock!", z);
+
+                retval = 0;
+                goto finish;
+            }
+
             pa_log("pa_pid_file_create() failed.");
             goto finish;
         }
@@ -826,11 +860,12 @@ int main(int argc, char *argv[]) {
         goto finish;
     }
 
-
 #ifdef HAVE_FORK
-    if (conf->daemonize) {
+    if (daemon_pipe[1] >= 0) {
         int ok = 0;
         pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
+        pa_close(daemon_pipe[1]);
+        daemon_pipe[1] = -1;
     }
 #endif
 
@@ -844,6 +879,12 @@ int main(int argc, char *argv[]) {
 
 finish:
 
+    if (autospawn_lock_fd >= 0)
+        pa_unlock_lockfile(lf, autospawn_lock_fd);
+
+    if (lf)
+        pa_xfree(lf);
+
 #ifdef OS_IS_WIN32
     if (win32_timer)
         pa_mainloop_get_api(mainloop)->time_free(win32_timer);
@@ -860,6 +901,9 @@ finish:
     pa_signal_done();
 
 #ifdef HAVE_FORK
+    if (daemon_pipe[1] >= 0)
+        pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
+
     pa_close_pipe(daemon_pipe);
 #endif
 
index 9e93234f6c77fede231cf88b52d0eb3d507f5ec3..dd2e699d0d829cbf4d57b279d0f87cf645f4627a 100644 (file)
@@ -220,6 +220,7 @@ int pa_pid_file_create(const char *procname) {
 
             if (ours) {
                 pa_log("Daemon already running.");
+                ret = 1;
                 goto fail;
             }
         }