diff options
author | Simon McVittie <smcv@collabora.com> | 2017-11-14 15:30:03 +0000 |
---|---|---|
committer | Simon McVittie <smcv@collabora.com> | 2017-11-15 12:12:18 +0000 |
commit | 13b640544dae99cfa851f3bbe9338ca58844aea8 (patch) | |
tree | bf08965b2182f5082b1179cbd26672b282c1cf5b | |
parent | 3d2300efc3584d9b5aabe2b9c2130b0eedd381bc (diff) |
Unix: Flush stdout and stderr streams before forking
stdout and stderr are close-on-exec and buffered, so we can't rely on
their buffers being empty. If we continue to execute application code
after forking (as opposed to immediately exec()ing), then the child
process might later flush the libc stdio buffers, resulting in
output that is printed by the parent also being printed by the child.
In particular, test-bus.log sometimes grows extremely large for
this reason, because this test repeatedly attempts to carry out
legacy activation.
Reviewed-by: Philip Withnall <withnall@endlessm.com>
Signed-off-by: Simon McVittie <smcv@collabora.com>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=103601
-rw-r--r-- | dbus/dbus-spawn.c | 11 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-unix.c | 10 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-util-unix.c | 7 | ||||
-rw-r--r-- | test/test-service.c | 10 | ||||
-rw-r--r-- | tools/dbus-launch.c | 14 | ||||
-rw-r--r-- | tools/dbus-run-session.c | 8 |
6 files changed, 57 insertions, 3 deletions
diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c index 8ab529a49..b2bcc2260 100644 --- a/dbus/dbus-spawn.c +++ b/dbus/dbus-spawn.c @@ -34,6 +34,7 @@ #include <fcntl.h> #include <signal.h> #include <sys/wait.h> +#include <stdio.h> #include <stdlib.h> #ifdef HAVE_ERRNO_H #include <errno.h> @@ -1362,6 +1363,11 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, } #endif + /* Make sure our output buffers aren't redundantly printed by both the + * parent and the child */ + fflush (stdout); + fflush (stderr); + pid = fork (); if (pid < 0) @@ -1385,7 +1391,10 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, /* Close the parent's end of the pipes. */ close_and_invalidate (&child_err_report_pipe[READ_END]); close_and_invalidate (&babysitter_pipe[0].fd); - + + fflush (stdout); + fflush (stderr); + /* Create the child that will exec () */ grandchild_pid = fork (); diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index bebf2073b..f103323c5 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -1040,6 +1040,11 @@ _dbus_connect_exec (const char *path, _dbus_fd_set_close_on_exec (fds[1]); } + /* Make sure our output buffers aren't redundantly printed by both the + * parent and the child */ + fflush (stdout); + fflush (stderr); + pid = fork (); if (pid < 0) { @@ -3623,6 +3628,11 @@ _read_subprocess_line_argv (const char *progpath, goto out; } + /* Make sure our output buffers aren't redundantly printed by both the + * parent and the child */ + fflush (stdout); + fflush (stderr); + pid = fork (); if (pid < 0) { diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index 2be5b7792..b841bf63f 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -35,6 +35,7 @@ #include "dbus-test.h" #include <sys/types.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> @@ -99,6 +100,12 @@ _dbus_become_daemon (const DBusString *pidfile, } _dbus_verbose ("forking...\n"); + + /* Make sure our output buffers aren't redundantly printed by both the + * parent and the child */ + fflush (stdout); + fflush (stderr); + switch ((child_pid = fork ())) { case -1: diff --git a/test/test-service.c b/test/test-service.c index b500af314..f71e3e039 100644 --- a/test/test-service.c +++ b/test/test-service.c @@ -1,6 +1,7 @@ #include <config.h> #include "test-utils.h" +#include <stdio.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -424,7 +425,14 @@ main (int argc, #ifndef DBUS_WIN if (do_fork) { - pid_t pid = fork (); + pid_t pid; + + /* Make sure our output buffers aren't redundantly printed by both the + * parent and the child */ + fflush (stdout); + fflush (stderr); + + pid = fork (); if (pid != 0) exit (0); sleep (1); diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c index f52875482..425914a19 100644 --- a/tools/dbus-launch.c +++ b/tools/dbus-launch.c @@ -656,6 +656,11 @@ babysit (int exit_with_session, exit (1); } + /* Make sure our output buffers aren't redundantly printed by both the + * parent and the child */ + fflush (stdout); + fflush (stderr); + ret = fork (); if (ret < 0) @@ -1125,6 +1130,11 @@ main (int argc, char **argv) exit (1); } + /* Make sure our output buffers aren't redundantly printed by both the + * parent and the child */ + fflush (stdout); + fflush (stderr); + ret = fork (); if (ret < 0) { @@ -1150,7 +1160,9 @@ main (int argc, char **argv) verbose ("=== Babysitter's intermediate parent created\n"); /* Fork once more to create babysitter */ - + + fflush (stdout); + fflush (stderr); ret = fork (); if (ret < 0) { diff --git a/tools/dbus-run-session.c b/tools/dbus-run-session.c index 0adb5ad1d..6b93997ef 100644 --- a/tools/dbus-run-session.c +++ b/tools/dbus-run-session.c @@ -354,6 +354,11 @@ main (int argc, char **argv) return 127; } + /* Make sure our output buffers aren't redundantly printed by both the + * parent and the child */ + fflush (stdout); + fflush (stderr); + bus_pid = fork (); if (bus_pid < 0) @@ -401,6 +406,9 @@ main (int argc, char **argv) !dbus_setenv ("DBUS_STARTER_BUS_TYPE", NULL)) oom (); + fflush (stdout); + fflush (stderr); + app_pid = fork (); if (app_pid < 0) |