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 :)
This commit is contained in:
Colin Guthrie 2011-03-25 09:12:51 +00:00
parent f49711c99a
commit 34ddc5b9c5

View file

@ -729,6 +729,7 @@ int main(int argc, char *argv[]) {
if ((child = fork()) < 0) { if ((child = fork()) < 0) {
pa_log(_("fork() failed: %s"), pa_cstrerror(errno)); pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
pa_close_pipe(daemon_pipe);
goto finish; goto finish;
} }
@ -793,6 +794,7 @@ int main(int argc, char *argv[]) {
if ((child = fork()) < 0) { if ((child = fork()) < 0) {
pa_log(_("fork() failed: %s"), pa_cstrerror(errno)); pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
pa_close_pipe(daemon_pipe2);
goto finish; goto finish;
} }
@ -1128,10 +1130,15 @@ finish:
pa_signal_done(); pa_signal_done();
#ifdef HAVE_FORK #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_loop_write(daemon_pipe2[1], &retval, sizeof(retval), NULL);
pa_close_pipe(daemon_pipe2); pa_close_pipe(daemon_pipe2);
pa_close_pipe(daemon_pipe);
#endif #endif
if (mainloop) if (mainloop)