mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
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
This commit is contained in:
parent
93c8fe6577
commit
70007175d2
6 changed files with 130 additions and 20 deletions
9
doc/todo
9
doc/todo
|
|
@ -1,6 +1,8 @@
|
||||||
*** $Id$ ***
|
*** $Id$ ***
|
||||||
|
|
||||||
*** 0.4 ***
|
- add FAQ
|
||||||
|
|
||||||
|
*** 0.5 ***
|
||||||
- make mcalign merge chunks
|
- make mcalign merge chunks
|
||||||
- use ref counting in more objects (i.e. sink, source, sink_input, source_output)
|
- use ref counting in more objects (i.e. sink, source, sink_input, source_output)
|
||||||
- unix socket directories include user name
|
- unix socket directories include user name
|
||||||
|
|
@ -12,11 +14,6 @@
|
||||||
- add sample directory
|
- add sample directory
|
||||||
- config file for command line arguments
|
- 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 ***
|
** later ***
|
||||||
- xmlrpc/http
|
- xmlrpc/http
|
||||||
- dbus
|
- dbus
|
||||||
|
|
|
||||||
|
|
@ -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_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_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_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[] = {
|
static const struct command commands[] = {
|
||||||
{ "exit", pa_cli_command_exit, "Terminate the daemon", 1 },
|
{ "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_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_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},
|
{ "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 }
|
{ NULL, NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -596,6 +598,98 @@ static int pa_cli_command_autoload_list(struct pa_core *c, struct pa_tokenizer *
|
||||||
return 0;
|
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) {
|
int pa_cli_command_execute_line(struct pa_core *c, const char *s, struct pa_strbuf *buf, int *fail, int *verbose) {
|
||||||
const char *cs;
|
const char *cs;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,7 @@ int main(int argc, char *argv[]) {
|
||||||
pa_context_set_state_callback(context, context_state_callback, NULL);
|
pa_context_set_state_callback(context, context_state_callback, NULL);
|
||||||
|
|
||||||
/* Connect the context */
|
/* Connect the context */
|
||||||
pa_context_connect_spawn(context, NULL);
|
pa_context_connect_spawn(context, NULL, NULL, NULL);
|
||||||
|
|
||||||
/* Run the main loop */
|
/* Run the main loop */
|
||||||
if (pa_mainloop_run(m, &ret) < 0) {
|
if (pa_mainloop_run(m, &ret) < 0) {
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,15 @@ load module-oss device="/dev/dsp" sink_name=output source_name=input record=0
|
||||||
|
|
||||||
# Load audio drivers automatically on access
|
# Load audio drivers automatically on access
|
||||||
|
|
||||||
#autoload_sink_add output 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/adsp" 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_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_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_sink_add output module-alsa-sink sink_name=output
|
||||||
#autoload_source_add input module-alsa-source source_name=input
|
#autoload_source_add input module-alsa-source source_name=input
|
||||||
|
|
||||||
# Load several protocols
|
# Load several protocols
|
||||||
#load module-esound-protocol-tcp
|
load module-esound-protocol-tcp
|
||||||
#load module-simple-protocol-tcp
|
#load module-simple-protocol-tcp
|
||||||
load module-native-protocol-unix
|
load module-native-protocol-unix
|
||||||
#load module-cli-protocol-unix
|
#load module-cli-protocol-unix
|
||||||
|
|
@ -46,8 +46,8 @@ load module-native-protocol-unix
|
||||||
load module-cli
|
load module-cli
|
||||||
|
|
||||||
# Make some devices default
|
# Make some devices default
|
||||||
#isink_default output
|
sink_default output
|
||||||
#source_default input
|
source_default input
|
||||||
|
|
||||||
.nofail
|
.nofail
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ load module-cli
|
||||||
scache_load /usr/share/sounds/KDE_Notify.wav x11-bell
|
scache_load /usr/share/sounds/KDE_Notify.wav x11-bell
|
||||||
|
|
||||||
# Load X11 bell module
|
# 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-source
|
||||||
#load module-pipe-sink
|
#load module-pipe-sink
|
||||||
|
|
|
||||||
|
|
@ -571,9 +571,9 @@ static int is_running(void) {
|
||||||
return 1;
|
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;
|
pid_t pid;
|
||||||
int status;
|
int status, r;
|
||||||
int fds[2] = { -1, -1} ;
|
int fds[2] = { -1, -1} ;
|
||||||
struct pa_iochannel *io;
|
struct pa_iochannel *io;
|
||||||
|
|
||||||
|
|
@ -586,9 +586,16 @@ int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prefork)
|
||||||
|
prefork();
|
||||||
|
|
||||||
if ((pid = fork()) < 0) {
|
if ((pid = fork()) < 0) {
|
||||||
pa_log(__FILE__": fork() failed: %s\n", strerror(errno));
|
pa_log(__FILE__": fork() failed: %s\n", strerror(errno));
|
||||||
pa_context_fail(c, PA_ERROR_INTERNAL);
|
pa_context_fail(c, PA_ERROR_INTERNAL);
|
||||||
|
|
||||||
|
if (postfork)
|
||||||
|
postfork();
|
||||||
|
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (!pid) {
|
} else if (!pid) {
|
||||||
char t[64];
|
char t[64];
|
||||||
|
|
@ -610,7 +617,13 @@ int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parent */
|
/* 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_log(__FILE__": waitpid() failed: %s\n", strerror(errno));
|
||||||
pa_context_fail(c, PA_ERROR_INTERNAL);
|
pa_context_fail(c, PA_ERROR_INTERNAL);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
|
|
@ -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
|
/** 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
|
* 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
|
* 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
|
* file descriptors or to do any other cleanups. (It is not safe to
|
||||||
* SIGCHLD is handled when calling this function. The function will
|
* close all file descriptors unconditionally, since a UNIX socket is
|
||||||
* waitpid() on the daemon's PID. \since 0.4 */
|
* passed to the new process.) if prefork is not NULL it is run just
|
||||||
int pa_context_connect_spawn(struct pa_context *c, void (*atfork)(void));
|
* 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 */
|
/** Terminate the context connection immediately */
|
||||||
void pa_context_disconnect(struct pa_context *c);
|
void pa_context_disconnect(struct pa_context *c);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue