summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-09-07 17:06:54 +0000
committerLennart Poettering <lennart@poettering.net>2004-09-07 17:06:54 +0000
commit70007175d28cf4c7323e772683bbe084e62df024 (patch)
treec0a8c35a1d35689d21cad90c03c77de01df7b15d
parent93c8fe6577b59176ed6a54a1ae98f8749f122dc8 (diff)
implemented new CLI command: dump
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
-rw-r--r--doc/todo9
-rw-r--r--polyp/cli-command.c94
-rw-r--r--polyp/pacat.c2
-rwxr-xr-xpolyp/polypaudio.pa12
-rw-r--r--polyp/polyplib-context.c19
-rw-r--r--polyp/polyplib-context.h14
6 files changed, 130 insertions, 20 deletions
diff --git a/doc/todo b/doc/todo
index f8a5ce866..4232a4d42 100644
--- 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
@@ -12,11 +14,6 @@
- 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
diff --git a/polyp/cli-command.c b/polyp/cli-command.c
index 4c4f566b1..52926199e 100644
--- a/polyp/cli-command.c
+++ b/polyp/cli-command.c
@@ -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;
diff --git a/polyp/pacat.c b/polyp/pacat.c
index 40301be88..0ad5fa525 100644
--- a/polyp/pacat.c
+++ b/polyp/pacat.c
@@ -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) {
diff --git a/polyp/polypaudio.pa b/polyp/polypaudio.pa
index 40012fd66..15434627c 100755
--- a/polyp/polypaudio.pa
+++ b/polyp/polypaudio.pa
@@ -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
diff --git a/polyp/polyplib-context.c b/polyp/polyplib-context.c
index a810bd984..caaa1dbb9 100644
--- a/polyp/polyplib-context.c
+++ b/polyp/polyplib-context.c
@@ -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;
diff --git a/polyp/polyplib-context.h b/polyp/polyplib-context.h
index 65befbb39..4b199751b 100644
--- a/polyp/polyplib-context.h
+++ b/polyp/polyplib-context.h
@@ -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);