mirror of
https://github.com/systemd/systemd.git
synced 2024-10-26 08:55:40 +03:00
Merge pull request #34891 from poettering/run0-pty
run0: add --pty and --pipe switches to force allocation of a pty or pipe
This commit is contained in:
commit
9d8f5e22f8
15
man/run0.xml
15
man/run0.xml
@ -192,6 +192,21 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--pty</option></term>
|
||||
<term><option>--pipe</option></term>
|
||||
|
||||
<listitem><para>Request allocation of a pseudo TTY for the <command>run0</command> session (in case
|
||||
of <option>--pty</option>), or request passing the caller's STDIO file descriptors directly through
|
||||
(in case of <option>--pipe</option>). If neither switch is specified, or if both switches are
|
||||
specified, the mode will be picked automatically: if standard input, standard output and standard
|
||||
error output are all connected to a TTY then a pseudo TTY is allocated, otherwise the relevant file
|
||||
descriptors are passed through directly.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v257"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--machine=</option></term>
|
||||
|
||||
|
@ -290,7 +290,7 @@ static int handle_arg_console(const char *arg) {
|
||||
else if (streq(arg, "passive"))
|
||||
arg_console_mode = CONSOLE_PASSIVE;
|
||||
else if (streq(arg, "pipe")) {
|
||||
if (isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO))
|
||||
if (isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO))
|
||||
log_full(arg_quiet ? LOG_DEBUG : LOG_NOTICE,
|
||||
"Console mode 'pipe' selected, but standard input/output are connected to an interactive TTY. "
|
||||
"Most likely you want to use 'interactive' console mode for proper interactivity and shell job control. "
|
||||
@ -298,7 +298,7 @@ static int handle_arg_console(const char *arg) {
|
||||
|
||||
arg_console_mode = CONSOLE_PIPE;
|
||||
} else if (streq(arg, "autopipe")) {
|
||||
if (isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO))
|
||||
if (isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO))
|
||||
arg_console_mode = CONSOLE_INTERACTIVE;
|
||||
else
|
||||
arg_console_mode = CONSOLE_PIPE;
|
||||
@ -5981,7 +5981,7 @@ static int run(int argc, char *argv[]) {
|
||||
umask(0022);
|
||||
|
||||
if (arg_console_mode < 0)
|
||||
arg_console_mode = isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO) ?
|
||||
arg_console_mode = isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO) ?
|
||||
CONSOLE_INTERACTIVE : CONSOLE_READ_ONLY;
|
||||
|
||||
if (arg_console_mode == CONSOLE_PIPE) /* if we pass STDERR on to the container, don't add our own logs into it too */
|
||||
|
@ -171,6 +171,10 @@ static int help_sudo_mode(void) {
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
/* NB: Let's not go overboard with short options: we try to keep a modicum of compatibility with
|
||||
* sudo's short switches, hence please do not introduce new short switches unless they have a roughly
|
||||
* equivalent purpose on sudo. Use long options for everything private to run0. */
|
||||
|
||||
printf("%s [OPTIONS...] COMMAND [ARGUMENTS...]\n"
|
||||
"\n%sElevate privileges interactively.%s\n\n"
|
||||
" -h --help Show this help\n"
|
||||
@ -188,6 +192,8 @@ static int help_sudo_mode(void) {
|
||||
" -D --chdir=PATH Set working directory\n"
|
||||
" --setenv=NAME[=VALUE] Set environment variable\n"
|
||||
" --background=COLOR Set ANSI color for background\n"
|
||||
" --pty Request allocation of a pseudo TTY for stdio\n"
|
||||
" --pipe Request direct pipe for stdio\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
@ -674,7 +680,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
/* If we both --pty and --pipe are specified we'll automatically pick --pty if we are connected fully
|
||||
* to a TTY and pick direct fd passing otherwise. This way, we automatically adapt to usage in a shell
|
||||
* pipeline, but we are neatly interactive with tty-level isolation otherwise. */
|
||||
arg_stdio = isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) ?
|
||||
arg_stdio = isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO) && isatty_safe(STDERR_FILENO) ?
|
||||
ARG_STDIO_PTY :
|
||||
ARG_STDIO_DIRECT;
|
||||
|
||||
@ -770,6 +776,8 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
|
||||
ARG_NICE,
|
||||
ARG_SETENV,
|
||||
ARG_BACKGROUND,
|
||||
ARG_PTY,
|
||||
ARG_PIPE,
|
||||
};
|
||||
|
||||
/* If invoked as "run0" binary, let's expose a more sudo-like interface. We add various extensions
|
||||
@ -791,6 +799,8 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
|
||||
{ "chdir", required_argument, NULL, 'D' },
|
||||
{ "setenv", required_argument, NULL, ARG_SETENV },
|
||||
{ "background", required_argument, NULL, ARG_BACKGROUND },
|
||||
{ "pty", no_argument, NULL, ARG_PTY },
|
||||
{ "pipe", no_argument, NULL, ARG_PIPE },
|
||||
{},
|
||||
};
|
||||
|
||||
@ -883,6 +893,20 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
|
||||
|
||||
break;
|
||||
|
||||
case ARG_PTY:
|
||||
if (IN_SET(arg_stdio, ARG_STDIO_DIRECT, ARG_STDIO_AUTO)) /* if --pipe is already used, upgrade to auto mode */
|
||||
arg_stdio = ARG_STDIO_AUTO;
|
||||
else
|
||||
arg_stdio = ARG_STDIO_PTY;
|
||||
break;
|
||||
|
||||
case ARG_PIPE:
|
||||
if (IN_SET(arg_stdio, ARG_STDIO_PTY, ARG_STDIO_AUTO)) /* If --pty is already used, upgrade to auto mode */
|
||||
arg_stdio = ARG_STDIO_AUTO;
|
||||
else
|
||||
arg_stdio = ARG_STDIO_DIRECT;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -913,7 +937,9 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
|
||||
arg_wait = true;
|
||||
arg_aggressive_gc = true;
|
||||
|
||||
arg_stdio = isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) ? ARG_STDIO_PTY : ARG_STDIO_DIRECT;
|
||||
if (IN_SET(arg_stdio, ARG_STDIO_NONE, ARG_STDIO_AUTO))
|
||||
arg_stdio = isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO) && isatty_safe(STDERR_FILENO) ? ARG_STDIO_PTY : ARG_STDIO_DIRECT;
|
||||
|
||||
arg_expand_environment = false;
|
||||
arg_send_sighup = true;
|
||||
|
||||
@ -1181,7 +1207,7 @@ static int transient_service_set_properties(sd_bus_message *m, const char *pty_p
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
send_term = isatty_safe(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO);
|
||||
send_term = isatty_safe(STDIN_FILENO) || isatty_safe(STDOUT_FILENO) || isatty_safe(STDERR_FILENO);
|
||||
}
|
||||
|
||||
if (send_term) {
|
||||
|
@ -261,4 +261,14 @@ if [[ -e /usr/lib/pam.d/systemd-run0 ]] || [[ -e /etc/pam.d/systemd-run0 ]]; the
|
||||
assert_eq "$(run0 -D / pwd)" "/"
|
||||
assert_eq "$(run0 --user=testuser pwd)" "/home/testuser"
|
||||
assert_eq "$(run0 -D / --user=testuser pwd)" "/"
|
||||
|
||||
# Verify that all combinations of --pty/--pipe come to the sam results
|
||||
assert_eq "$(run0 echo -n foo)" "foo"
|
||||
assert_eq "$(run0 --pty echo -n foo)" "foo"
|
||||
assert_eq "$(run0 --pipe echo -n foo)" "foo"
|
||||
assert_eq "$(run0 --pipe --pty echo -n foo)" "foo"
|
||||
|
||||
# Validate when we invoke run0 without a tty, that depending on --pty it either allocates a tty or not
|
||||
assert_neq "$(run0 --pty tty < /dev/null)" "not a tty"
|
||||
assert_eq "$(run0 --pipe tty < /dev/null)" "not a tty"
|
||||
fi
|
||||
|
@ -39,6 +39,15 @@ assert_eq() {(
|
||||
fi
|
||||
)}
|
||||
|
||||
assert_neq() {(
|
||||
set +ex
|
||||
|
||||
if [[ "${1?}" = "${2?}" ]]; then
|
||||
echo "FAIL: not expected: '$2' actual: '$1'" >&2
|
||||
exit 1
|
||||
fi
|
||||
)}
|
||||
|
||||
assert_le() {(
|
||||
set +ex
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user