]> code.delx.au - pulseaudio/commitdiff
daemon: Fix some more error paths in the double forking.
authorColin Guthrie <cguthrie@mandriva.org>
Fri, 25 Mar 2011 09:12:51 +0000 (09:12 +0000)
committerColin Guthrie <cguthrie@mandriva.org>
Fri, 25 Mar 2011 21:35:40 +0000 (21:35 +0000)
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

index b77a8b610f94c70f4fb6b3bd46557103837f98cb..f939313c27ff6f1cae8159292f2f1103fd4831a8 100644 (file)
@@ -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)