]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
process-util: add new safe_fork() flag for connecting stdout to stderr
authorLennart Poettering <lennart@poettering.net>
Mon, 6 May 2019 20:38:43 +0000 (22:38 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 4 Dec 2019 09:59:42 +0000 (10:59 +0100)
This adds a new safe_fork() flag. If set the child process' fd 1 becomes
fd 2 of the caller. This is useful for invoking tools (such as various
mkfs/fsck implementations) that output status messages to stdout, but
which we invoke and don't want to pollute stdout with their output.

src/basic/process-util.c
src/basic/process-util.h

index 9b6c4c31f713da377515ddf797900fe887b462ab..f996614bb688ebbf674dbffbea165a1271e81278 100644 (file)
@@ -1337,6 +1337,13 @@ int safe_fork_full(
                         log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
                         _exit(EXIT_FAILURE);
                 }
+
+        } else if (flags & FORK_STDOUT_TO_STDERR) {
+
+                if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
+                        log_full_errno(prio, r, "Failed to connect stdout to stderr: %m");
+                        _exit(EXIT_FAILURE);
+                }
         }
 
         if (flags & FORK_RLIMIT_NOFILE_SAFE) {
index 5f4e174f04cb180ee1a8094cbd36e441ed04bd83..8f5addd4b995e67eab83852a78ae5762143eca36 100644 (file)
@@ -147,16 +147,17 @@ void reset_cached_pid(void);
 int must_be_root(void);
 
 typedef enum ForkFlags {
-        FORK_RESET_SIGNALS      = 1 << 0, /* Reset all signal handlers and signal mask */
-        FORK_CLOSE_ALL_FDS      = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
-        FORK_DEATHSIG           = 1 << 2, /* Set PR_DEATHSIG in the child */
-        FORK_NULL_STDIO         = 1 << 3, /* Connect 0,1,2 to /dev/null */
-        FORK_REOPEN_LOG         = 1 << 4, /* Reopen log connection */
-        FORK_LOG                = 1 << 5, /* Log above LOG_DEBUG log level about failures */
-        FORK_WAIT               = 1 << 6, /* Wait until child exited */
-        FORK_NEW_MOUNTNS        = 1 << 7, /* Run child in its own mount namespace */
-        FORK_MOUNTNS_SLAVE      = 1 << 8, /* Make child's mount namespace MS_SLAVE */
-        FORK_RLIMIT_NOFILE_SAFE = 1 << 9, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
+        FORK_RESET_SIGNALS      = 1 <<  0, /* Reset all signal handlers and signal mask */
+        FORK_CLOSE_ALL_FDS      = 1 <<  1, /* Close all open file descriptors in the child, except for 0,1,2 */
+        FORK_DEATHSIG           = 1 <<  2, /* Set PR_DEATHSIG in the child */
+        FORK_NULL_STDIO         = 1 <<  3, /* Connect 0,1,2 to /dev/null */
+        FORK_REOPEN_LOG         = 1 <<  4, /* Reopen log connection */
+        FORK_LOG                = 1 <<  5, /* Log above LOG_DEBUG log level about failures */
+        FORK_WAIT               = 1 <<  6, /* Wait until child exited */
+        FORK_NEW_MOUNTNS        = 1 <<  7, /* Run child in its own mount namespace */
+        FORK_MOUNTNS_SLAVE      = 1 <<  8, /* Make child's mount namespace MS_SLAVE */
+        FORK_RLIMIT_NOFILE_SAFE = 1 <<  9, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
+        FORK_STDOUT_TO_STDERR   = 1 << 10, /* Make stdout a copy of stderr */
 } ForkFlags;
 
 int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);