From 2fb23fe9624c39d0e903b4df8cbffcd1090f6682 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 14 Nov 2017 15:30:03 +0000 Subject: [PATCH 08/13] 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. Signed-off-by: Simon McVittie --- 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 8ab529a4..b2bcc226 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 bebf2073..f103323c 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 2be5b779..b841bf63 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 b500af31..f71e3e03 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 f5287548..425914a1 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 0adb5ad1..6b93997e 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) -- 2.15.0