core: inherit TERM from PID 1 for all services started on /dev/console
This way, invoking nspawn from a shell in the best case inherits the TERM setting all the way down into the login shell spawned in the container. Fixes: #3697
This commit is contained in:
parent
43992e57e0
commit
6af760f3b2
|
@ -785,7 +785,7 @@ bool tty_is_vc_resolve(const char *tty) {
|
|||
}
|
||||
|
||||
const char *default_term_for_tty(const char *tty) {
|
||||
return tty && tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt220";
|
||||
return tty && tty_is_vc_resolve(tty) ? "linux" : "vt220";
|
||||
}
|
||||
|
||||
int fd_columns(int fd) {
|
||||
|
|
|
@ -219,12 +219,36 @@ static void exec_context_tty_reset(const ExecContext *context, const ExecParamet
|
|||
(void) vt_disallocate(path);
|
||||
}
|
||||
|
||||
static bool is_terminal_input(ExecInput i) {
|
||||
return IN_SET(i,
|
||||
EXEC_INPUT_TTY,
|
||||
EXEC_INPUT_TTY_FORCE,
|
||||
EXEC_INPUT_TTY_FAIL);
|
||||
}
|
||||
|
||||
static bool is_terminal_output(ExecOutput o) {
|
||||
return
|
||||
o == EXEC_OUTPUT_TTY ||
|
||||
o == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
|
||||
o == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
|
||||
o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE;
|
||||
return IN_SET(o,
|
||||
EXEC_OUTPUT_TTY,
|
||||
EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
|
||||
EXEC_OUTPUT_KMSG_AND_CONSOLE,
|
||||
EXEC_OUTPUT_JOURNAL_AND_CONSOLE);
|
||||
}
|
||||
|
||||
static bool exec_context_needs_term(const ExecContext *c) {
|
||||
assert(c);
|
||||
|
||||
/* Return true if the execution context suggests we should set $TERM to something useful. */
|
||||
|
||||
if (is_terminal_input(c->std_input))
|
||||
return true;
|
||||
|
||||
if (is_terminal_output(c->std_output))
|
||||
return true;
|
||||
|
||||
if (is_terminal_output(c->std_error))
|
||||
return true;
|
||||
|
||||
return !!c->tty_path;
|
||||
}
|
||||
|
||||
static int open_null_as(int flags, int nfd) {
|
||||
|
@ -363,13 +387,6 @@ static int open_terminal_as(const char *path, mode_t mode, int nfd) {
|
|||
return r;
|
||||
}
|
||||
|
||||
static bool is_terminal_input(ExecInput i) {
|
||||
return
|
||||
i == EXEC_INPUT_TTY ||
|
||||
i == EXEC_INPUT_TTY_FORCE ||
|
||||
i == EXEC_INPUT_TTY_FAIL;
|
||||
}
|
||||
|
||||
static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
|
||||
|
||||
if (is_terminal_input(std_input) && !apply_tty_stdin)
|
||||
|
@ -1444,12 +1461,21 @@ static int build_environment(
|
|||
our_env[n_env++] = x;
|
||||
}
|
||||
|
||||
if (is_terminal_input(c->std_input) ||
|
||||
c->std_output == EXEC_OUTPUT_TTY ||
|
||||
c->std_error == EXEC_OUTPUT_TTY ||
|
||||
c->tty_path) {
|
||||
if (exec_context_needs_term(c)) {
|
||||
const char *tty_path, *term = NULL;
|
||||
|
||||
x = strdup(default_term_for_tty(exec_context_tty_path(c)));
|
||||
tty_path = exec_context_tty_path(c);
|
||||
|
||||
/* If we are forked off PID 1 and we are supposed to operate on /dev/console, then let's try to inherit
|
||||
* the $TERM set for PID 1. This is useful for containers so that the $TERM the container manager
|
||||
* passes to PID 1 ends up all the way in the console login shown. */
|
||||
|
||||
if (path_equal(tty_path, "/dev/console") && getppid() == 1)
|
||||
term = getenv("TERM");
|
||||
if (!term)
|
||||
term = default_term_for_tty(tty_path);
|
||||
|
||||
x = strappend("TERM=", term);
|
||||
if (!x)
|
||||
return -ENOMEM;
|
||||
our_env[n_env++] = x;
|
||||
|
|
|
@ -1318,7 +1318,7 @@ static int fixup_environment(void) {
|
|||
return r;
|
||||
|
||||
if (r == 0) {
|
||||
term = strdup(default_term_for_tty("/dev/console") + 5);
|
||||
term = strdup(default_term_for_tty("/dev/console"));
|
||||
if (!term)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue