From: Lennart Poettering Date: Mon, 6 May 2019 20:38:43 +0000 (+0200) Subject: process-util: add new safe_fork() flag for connecting stdout to stderr X-Git-Tag: v245-rc1~314^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8987afc4d12cce4f8b89c6d963aec8f44bf3cc45;p=thirdparty%2Fsystemd.git process-util: add new safe_fork() flag for connecting stdout to stderr 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. --- diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 9b6c4c31f71..f996614bb68 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -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) { diff --git a/src/basic/process-util.h b/src/basic/process-util.h index 5f4e174f04c..8f5addd4b99 100644 --- a/src/basic/process-util.h +++ b/src/basic/process-util.h @@ -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);