]> code.delx.au - pulseaudio/commitdiff
implemented new CLI command: dump
authorLennart Poettering <lennart@poettering.net>
Tue, 7 Sep 2004 17:06:54 +0000 (17:06 +0000)
committerLennart Poettering <lennart@poettering.net>
Tue, 7 Sep 2004 17:06:54 +0000 (17:06 +0000)
add prefork() and postfork() arguments to pa_context_connect_spawn()

git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@184 fefdeb5f-60dc-0310-8127-8f9354f1896f

doc/todo
polyp/cli-command.c
polyp/pacat.c
polyp/polypaudio.pa
polyp/polyplib-context.c
polyp/polyplib-context.h

index f8a5ce8660c892dbf230c596a1f5884c9585658b..4232a4d42f28f1d5ba5d52b7d48154c063174fdf 100644 (file)
--- a/doc/todo
+++ b/doc/todo
@@ -1,6 +1,8 @@
 *** $Id$ ***
 
-*** 0.4 ***
+- add FAQ
+
+*** 0.5 ***
 - make mcalign merge chunks
 - use ref counting in more objects (i.e. sink, source, sink_input, source_output)
 - unix socket directories include user name
 - add sample directory
 - config file for command line arguments
 
-- add FAQ
-- pa_context_connect_spawn(): change function to fork+exec+waitpid-like function
-- on delete event in paman
-- add feature to dump config file
-
 ** later ***
 - xmlrpc/http
 - dbus
index 4c4f566b15038631cd229f2ee570c283c659f2c7..52926199e1e2a9866b0a1f81918622620e26e72c 100644 (file)
@@ -82,6 +82,7 @@ static int pa_cli_command_play_file(struct pa_core *c, struct pa_tokenizer *t, s
 static int pa_cli_command_autoload_list(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose);
 static int pa_cli_command_autoload_add(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose);
 static int pa_cli_command_autoload_remove(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose);
+static int pa_cli_command_dump(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose);
 
 static const struct command commands[] = {
     { "exit",                    pa_cli_command_exit,               "Terminate the daemon",         1 },
@@ -115,6 +116,7 @@ static const struct command commands[] = {
     { "autoload_source_add",     pa_cli_command_autoload_add,       "Add autoload entry for a source (args: source, name, arguments)", 4},
     { "autoload_sink_remove",    pa_cli_command_autoload_remove,    "Remove autoload entry for a sink (args: sink)", 2},
     { "autoload_source_remove",  pa_cli_command_autoload_remove,    "Remove autoload entry for a source (args: source)", 2},
+    { "dump",                    pa_cli_command_dump,               "Dump daemon configuration", 1},
     { NULL, NULL, NULL, 0 }
 };
 
@@ -596,6 +598,98 @@ static int pa_cli_command_autoload_list(struct pa_core *c, struct pa_tokenizer *
     return 0;
 }
 
+static int pa_cli_command_dump(struct pa_core *c, struct pa_tokenizer *t, struct pa_strbuf *buf, int *fail, int *verbose) {
+    struct pa_module *m;
+    struct pa_sink *s;
+    int nl;
+    const char *p;
+    uint32_t index;
+    char txt[256];
+    time_t now;
+    void *i;
+    struct pa_autoload_entry *a;
+    
+    assert(c && t);
+
+    time(&now);
+
+    pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime_r(&now, txt));
+
+    
+    for (m = pa_idxset_first(c->modules, &index); m; m = pa_idxset_next(c->modules, &index)) {
+        if (m->auto_unload)
+            continue;
+
+        pa_strbuf_printf(buf, "load %s", m->name);
+
+        if (m->argument)
+            pa_strbuf_printf(buf, " %s", m->argument);
+
+        pa_strbuf_puts(buf, "\n");
+    }
+
+    nl = 0;
+
+    for (s = pa_idxset_first(c->sinks, &index); s; s = pa_idxset_next(c->sinks, &index)) {
+        if (s->volume == PA_VOLUME_NORM)
+            continue;
+        
+        if (s->owner && s->owner->auto_unload)
+            continue;
+
+        if (!nl) {
+            pa_strbuf_puts(buf, "\n");
+            nl = 1;
+        }
+        
+        pa_strbuf_printf(buf, "sink_volume %s 0x%03x\n", s->name, s->volume);
+    }
+
+
+    if (c->autoload_hashmap) {
+        nl = 0;
+        
+        i = NULL;
+        while ((a = pa_hashmap_iterate(c->autoload_hashmap, &i))) {
+            
+            if (!nl) {
+                pa_strbuf_puts(buf, "\n");
+                nl = 1;
+            }
+            
+            pa_strbuf_printf(buf, "autoload_%s_add %s %s", a->type == PA_NAMEREG_SINK ? "sink" : "source", a->name, a->module);
+            
+            if (a->argument)
+                pa_strbuf_printf(buf, " %s", a->argument);
+            
+            pa_strbuf_puts(buf, "\n");
+        }
+    }
+
+    nl = 0;
+    
+    if ((p = pa_namereg_get_default_sink_name(c))) {
+        if (!nl) {
+            pa_strbuf_puts(buf, "\n");
+            nl = 1;
+        }
+        pa_strbuf_printf(buf, "sink_default %s\n", p);
+    }
+
+    if ((p = pa_namereg_get_default_source_name(c))) {
+        if (!nl) {
+            pa_strbuf_puts(buf, "\n");
+            nl = 1;
+        }
+        pa_strbuf_printf(buf, "source_default %s\n", p);
+    }
+
+    pa_strbuf_puts(buf, "\n### EOF\n");
+
+    return 0;
+}
+
+
 int pa_cli_command_execute_line(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail, int *verbose) {
     const char *cs;
     
index 40301be88b7a6392fb7cffc3b748bd539391a4d8..0ad5fa52580a7102b3efd134de8ab71ed8230f30 100644 (file)
@@ -357,7 +357,7 @@ int main(int argc, char *argv[]) {
     pa_context_set_state_callback(context, context_state_callback, NULL);
 
     /* Connect the context */
-    pa_context_connect_spawn(context, NULL);
+    pa_context_connect_spawn(context, NULL, NULL, NULL);
 
     /* Run the main loop */
     if (pa_mainloop_run(m, &ret) < 0) {
index 40012fd6604e0933737b837af3db8484d0391224..15434627ccbe8f5307ed67b4d18a3008e1358032 100755 (executable)
@@ -28,15 +28,15 @@ load module-oss device="/dev/dsp" sink_name=output source_name=input record=0
 
 # Load audio drivers automatically on access
 
-#autoload_sink_add output module-oss device="/dev/adsp" sink_name=output source_name=input
-#autoload_source_add input module-oss device="/dev/adsp" sink_name=output source_name=input
+#autoload_sink_add output module-oss device="/dev/dsp" sink_name=output source_name=input
+#autoload_source_add input module-oss device="/dev/dsp" sink_name=output source_name=input
 #autoload_sink_add output module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
 #autoload_source_add input module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
 #autoload_sink_add output module-alsa-sink sink_name=output
 #autoload_source_add input module-alsa-source source_name=input
 
 # Load several protocols
-#load module-esound-protocol-tcp
+load module-esound-protocol-tcp
 #load module-simple-protocol-tcp
 load module-native-protocol-unix
 #load module-cli-protocol-unix
@@ -46,8 +46,8 @@ load module-native-protocol-unix
 load module-cli
 
 # Make some devices default
-#isink_default output
-#source_default input
+sink_default output
+source_default input
 
 .nofail
 
@@ -55,7 +55,7 @@ load module-cli
 scache_load /usr/share/sounds/KDE_Notify.wav x11-bell
 
 # Load X11 bell module
-#load module-x11-bell sample=x11-bell sink=output
+load module-x11-bell sample=x11-bell sink=output
 
 #load module-pipe-source
 #load module-pipe-sink
index a810bd9840355cc9fee102ee41d0250b6728a481..caaa1dbb9b28261395f64beadac38062483d5e60 100644 (file)
@@ -571,9 +571,9 @@ static int is_running(void) {
     return 1;
 }
 
-int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void)) {
+int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void), void (*prefork)(void), void (*postfork)(void)) {
     pid_t pid;
-    int status;
+    int status, r;
     int fds[2] = { -1, -1} ;
     struct pa_iochannel *io;
     
@@ -586,9 +586,16 @@ int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void)) {
         goto fail;
     }
 
+    if (prefork)
+        prefork();
+
     if ((pid = fork()) < 0) {
         pa_log(__FILE__": fork() failed: %s\n", strerror(errno));
         pa_context_fail(c, PA_ERROR_INTERNAL);
+
+        if (postfork)
+            postfork();
+        
         goto fail;
     } else if (!pid) {
         char t[64];
@@ -610,7 +617,13 @@ int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void)) {
     } 
 
     /* Parent */
-    if (waitpid(pid, &status, 0) < 0) {
+
+    r = waitpid(pid, &status, 0);
+
+    if (postfork)
+        postfork();
+        
+    if (r < 0) {
         pa_log(__FILE__": waitpid() failed: %s\n", strerror(errno));
         pa_context_fail(c, PA_ERROR_INTERNAL);
         goto fail;
index 65befbb398ec85fad1a1a10206412fc1b9943c0a..4b199751b3eb5f029a8ca0c99c93d03f607288e1 100644 (file)
@@ -82,10 +82,16 @@ int pa_context_connect(struct pa_context *c, const char *server);
 /** Connect the context to a server. If the default server is local
  * but not accessible, spawn a new daemon. If atfork is not NULL it is
  * run after the fork() in the child process. It may be used to close
- * file descriptors or to do any other cleanups. Make sure that
- * SIGCHLD is handled when calling this function. The function will
- * waitpid() on the daemon's PID. \since 0.4 */
-int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void));
+ * file descriptors or to do any other cleanups. (It is not safe to
+ * close all file descriptors unconditionally, since a UNIX socket is
+ * passed to the new process.) if prefork is not NULL it is run just
+ * before forking in the parent process. Use this to block SIGCHLD
+ * handling if required. If postfork is not NULL it is run just after
+ * forking in the parent process. Use this to unblock SIGCHLD if
+ * required.  The function will waitpid() on the daemon's PID, but
+ * will not block or ignore SIGCHLD signals, since this cannot be done
+ * in a thread compatible way. \since 0.4 */
+int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void), void (*prefork)(void), void (*postfork)(void));
 
 /** Terminate the context connection immediately */
 void pa_context_disconnect(struct pa_context *c);