From 34ddc5b9c533ed83d53238fff0777663f9c50336 Mon Sep 17 00:00:00 2001 From: Colin Guthrie Date: Fri, 25 Mar 2011 09:12:51 +0000 Subject: [PATCH] daemon: Fix some more error paths in the double forking. As spotted by Tanu Kaskinen: The first process: daemon_pipe is not closed if the first fork() call fails. Even if it doesn't fail, the first process never closes daemon_pipe[0]. The second process: daemon_pipe[1] is not closed if anything fails between the first and the second fork() call. Also, if the second fork fails, then the finish section writes to daemon_pipe2[1], even though only the third process should do that. Also, if anything fails between the first and the second fork, then the second process never writes anything to daemon_pipe[1]. I don't know what happens in the first process in this case - does it get an error or does pa_loop_read() get stuck. The third process: No problems :) --- src/daemon/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index b77a8b6..f939313 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -729,6 +729,7 @@ int main(int argc, char *argv[]) { if ((child = fork()) < 0) { pa_log(_("fork() failed: %s"), pa_cstrerror(errno)); + pa_close_pipe(daemon_pipe); goto finish; } @@ -793,6 +794,7 @@ int main(int argc, char *argv[]) { if ((child = fork()) < 0) { pa_log(_("fork() failed: %s"), pa_cstrerror(errno)); + pa_close_pipe(daemon_pipe2); goto finish; } @@ -1128,10 +1130,15 @@ finish: pa_signal_done(); #ifdef HAVE_FORK - if (daemon_pipe2[1] >= 0) + /* If we have daemon_pipe[1] still open, this means we've failed after + * the first fork, but before the second. Therefore just write to it. */ + if (daemon_pipe[1] >= 0) + pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL); + else if (daemon_pipe2[1] >= 0) pa_loop_write(daemon_pipe2[1], &retval, sizeof(retval), NULL); pa_close_pipe(daemon_pipe2); + pa_close_pipe(daemon_pipe); #endif if (mainloop) -- 2.7.4