From 13b640544dae99cfa851f3bbe9338ca58844aea8 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 14 Nov 2017 15:30:03 +0000 Subject: 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 Signed-off-by: Simon McVittie Bug: https://bugs.freedesktop.org/show_bug.cgi?id=103601 --- dbus/dbus-spawn.c | 11 ++++++++++- dbus/dbus-sysdeps-unix.c | 10 ++++++++++ dbus/dbus-sysdeps-util-unix.c | 7 +++++++ test/test-service.c | 10 +++++++++- tools/dbus-launch.c | 14 +++++++++++++- 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 #include #include +#include #include #ifdef HAVE_ERRNO_H #include @@ -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 +#include #include #include #include @@ -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 #include "test-utils.h" +#include #ifdef HAVE_UNISTD_H #include #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) -- cgit v1.2.3