diff options
author | Lennart Poettering <lennart@poettering.net> | 2009-07-28 01:35:19 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2009-07-28 01:35:19 +0200 |
commit | 09e57c2ee9c731805e97f07771a18dfc4c917318 (patch) | |
tree | ef48805839f8bede8accef8c1eed47ef6a9e3372 /src/pulse/context.c | |
parent | 835a2ae83a6cca344608ce9504f8d69da9d112fc (diff) | |
parent | 8343360da1d8d93e8e3818ab91e7f764a1c8c99e (diff) |
Merge branch 'master' into master-tx
Diffstat (limited to 'src/pulse/context.c')
-rw-r--r-- | src/pulse/context.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/pulse/context.c b/src/pulse/context.c index 4ded5565..7c3717fa 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -668,11 +668,24 @@ static pa_strlist *prepend_per_user(pa_strlist *l) { static int context_autospawn(pa_context *c) { pid_t pid; int status, r; - - pa_log_debug("Trying to autospawn..."); + struct sigaction sa; pa_context_ref(c); + if (sigaction(SIGCHLD, NULL, &sa) < 0) { + pa_log_debug("sigaction() failed: %s", pa_cstrerror(errno)); + pa_context_fail(c, PA_ERR_INTERNAL); + goto fail; + } + + if ((sa.sa_flags & SA_NOCLDWAIT) || sa.sa_handler == SIG_IGN) { + pa_log_debug("Process disabled waitpid(), cannot autospawn."); + pa_context_fail(c, PA_ERR_CONNECTIONREFUSED); + goto fail; + } + + pa_log_debug("Trying to autospawn..."); + if (c->spawn_api.prefork) c->spawn_api.prefork(); @@ -688,9 +701,8 @@ static int context_autospawn(pa_context *c) { /* Child */ const char *state = NULL; -#define MAX_ARGS 64 - const char * argv[MAX_ARGS+1]; - int n; + const char * argv[32]; + unsigned n = 0; if (c->spawn_api.atfork) c->spawn_api.atfork(); @@ -699,12 +711,10 @@ static int context_autospawn(pa_context *c) { /* Setup argv */ - n = 0; - argv[n++] = c->conf->daemon_binary; argv[n++] = "--start"; - while (n < MAX_ARGS) { + while (n < PA_ELEMENTSOF(argv)-1) { char *a; if (!(a = pa_split_spaces(c->conf->extra_arguments, &state))) @@ -714,10 +724,10 @@ static int context_autospawn(pa_context *c) { } argv[n++] = NULL; + pa_assert(n <= PA_ELEMENTSOF(argv)); execv(argv[0], (char * const *) argv); _exit(1); -#undef MAX_ARGS } /* Parent */ @@ -730,9 +740,16 @@ static int context_autospawn(pa_context *c) { } while (r < 0 && errno == EINTR); if (r < 0) { - pa_log(_("waitpid(): %s"), pa_cstrerror(errno)); - pa_context_fail(c, PA_ERR_INTERNAL); - goto fail; + + if (errno != ESRCH) { + pa_log(_("waitpid(): %s"), pa_cstrerror(errno)); + pa_context_fail(c, PA_ERR_INTERNAL); + goto fail; + } + + /* hmm, something already reaped our child, so we assume + * startup worked, even if we cannot know */ + } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { pa_context_fail(c, PA_ERR_CONNECTIONREFUSED); goto fail; |