return true;
}
+static int maybe_inherit_stdout_from_stdin(const ExecContext *context, ExecInput i) {
+ int r;
+
+ assert(context);
+
+ if (context->std_output != EXEC_OUTPUT_INHERIT)
+ return 0;
+
+ /* If input got downgraded, inherit the original value */
+ if (i == EXEC_INPUT_NULL && exec_input_is_terminal(context->std_input))
+ return open_terminal_as(exec_context_tty_path(context), O_WRONLY, STDOUT_FILENO);
+
+ if (!exec_input_is_inheritable(i))
+ goto fallback;
+
+ r = fd_is_writable(STDIN_FILENO);
+ if (r <= 0) {
+ if (r < 0)
+ log_warning_errno(r, "Failed to check if inherited stdin is writable for stdout, using fallback: %m");
+ else
+ log_warning("Inherited stdin is not writable for stdout, using fallback: %m");
+ goto fallback;
+ }
+
+ return RET_NERRNO(dup2(STDIN_FILENO, STDOUT_FILENO));
+
+fallback:
+ /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
+ if (getppid() != 1)
+ return STDOUT_FILENO;
+
+ /* We need to open /dev/null here anew, to get the right access mode. */
+ return open_null_as(O_WRONLY, STDOUT_FILENO);
+}
+
static int setup_output(
const ExecContext *context,
const ExecParameters *params,
}
i = fixup_input(context, params->flags & EXEC_APPLY_TTY_STDIN);
- o = context->std_output;
if (fileno == STDERR_FILENO) {
- ExecOutput e = context->std_error;
-
/* This expects the input and output are already set up */
/* Don't change the stderr file descriptor if we inherit all
* the way and are not on a tty */
- if (e == EXEC_OUTPUT_INHERIT &&
- o == EXEC_OUTPUT_INHERIT &&
- i == EXEC_INPUT_NULL &&
- !exec_input_is_terminal(context->std_input) &&
+ if (context->std_error == EXEC_OUTPUT_INHERIT &&
+ context->std_output == EXEC_OUTPUT_INHERIT &&
+ i == EXEC_INPUT_NULL && !exec_input_is_terminal(context->std_input) &&
getppid() != 1)
return fileno;
return RET_NERRNO(dup2(STDOUT_FILENO, fileno));
}
- o = e;
-
- } else if (o == EXEC_OUTPUT_INHERIT) {
- /* If input got downgraded, inherit the original value */
- if (i == EXEC_INPUT_NULL && exec_input_is_terminal(context->std_input))
- return open_terminal_as(exec_context_tty_path(context), O_WRONLY, fileno);
+ o = context->std_error;
- /* If the input is connected to anything that's not a /dev/null or a data fd, inherit that... */
- if (!IN_SET(i, EXEC_INPUT_NULL, EXEC_INPUT_DATA)) {
- r = fd_is_writable(STDIN_FILENO);
- if (r <= 0) {
- if (r < 0)
- log_warning_errno(r, "Failed to check if inherited stdin is writable for %s, falling back to /dev/null.",
- fileno == STDOUT_FILENO ? "stdout" : "stderr");
- else
- log_warning("Inherited stdin is not writable for %s, falling back to /dev/null.",
- fileno == STDOUT_FILENO ? "stdout" : "stderr");
- return open_null_as(O_WRONLY, fileno);
- }
- return RET_NERRNO(dup2(STDIN_FILENO, fileno));
- }
+ } else {
+ assert(fileno == STDOUT_FILENO);
- /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
- if (getppid() != 1)
- return fileno;
+ r = maybe_inherit_stdout_from_stdin(context, i);
+ if (r != 0)
+ return r;
- /* We need to open /dev/null here anew, to get the right access mode. */
- return open_null_as(O_WRONLY, fileno);
+ o = context->std_output;
}
switch (o) {