Merge pull request #29929 from poettering/tty-reset-fixes

pid1: various fixes around TTY resets
This commit is contained in:
Yu Watanabe 2023-11-11 12:44:31 +09:00 committed by GitHub
commit 49549a458c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 39 deletions

View file

@ -392,12 +392,12 @@ static int setup_input(
/* Try to make this the controlling tty, if it is a tty, and reset it */
if (isatty(STDIN_FILENO)) {
unsigned rows = context->tty_rows, cols = context->tty_cols;
(void) exec_context_tty_size(context, &rows, &cols);
(void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE);
(void) reset_terminal_fd(STDIN_FILENO, true);
(void) terminal_set_size_fd(STDIN_FILENO, NULL, rows, cols);
if (context->tty_reset)
(void) reset_terminal_fd(STDIN_FILENO, /* switch_to_text= */ true);
(void) exec_context_apply_tty_size(context, STDIN_FILENO, /* tty_path= */ NULL);
}
return STDIN_FILENO;
@ -413,26 +413,29 @@ static int setup_input(
case EXEC_INPUT_TTY:
case EXEC_INPUT_TTY_FORCE:
case EXEC_INPUT_TTY_FAIL: {
unsigned rows, cols;
int fd;
_cleanup_close_ int tty_fd = -EBADF;
const char *tty_path;
fd = acquire_terminal(exec_context_tty_path(context),
i == EXEC_INPUT_TTY_FAIL ? ACQUIRE_TERMINAL_TRY :
i == EXEC_INPUT_TTY_FORCE ? ACQUIRE_TERMINAL_FORCE :
ACQUIRE_TERMINAL_WAIT,
USEC_INFINITY);
if (fd < 0)
return fd;
tty_path = ASSERT_PTR(exec_context_tty_path(context));
r = exec_context_tty_size(context, &rows, &cols);
tty_fd = acquire_terminal(tty_path,
i == EXEC_INPUT_TTY_FAIL ? ACQUIRE_TERMINAL_TRY :
i == EXEC_INPUT_TTY_FORCE ? ACQUIRE_TERMINAL_FORCE :
ACQUIRE_TERMINAL_WAIT,
USEC_INFINITY);
if (tty_fd < 0)
return tty_fd;
r = exec_context_apply_tty_size(context, tty_fd, tty_path);
if (r < 0)
return r;
r = terminal_set_size_fd(fd, exec_context_tty_path(context), rows, cols);
r = move_fd(tty_fd, STDIN_FILENO, /* cloexec= */ false);
if (r < 0)
return r;
return move_fd(fd, STDIN_FILENO, false);
TAKE_FD(tty_fd);
return r;
}
case EXEC_INPUT_SOCKET:
@ -692,7 +695,6 @@ static int setup_confirm_stdio(
int *ret_saved_stdout) {
_cleanup_close_ int fd = -EBADF, saved_stdin = -EBADF, saved_stdout = -EBADF;
unsigned rows, cols;
int r;
assert(ret_saved_stdin);
@ -714,15 +716,11 @@ static int setup_confirm_stdio(
if (r < 0)
return r;
r = reset_terminal_fd(fd, true);
r = reset_terminal_fd(fd, /* switch_to_text= */ true);
if (r < 0)
return r;
r = exec_context_tty_size(context, &rows, &cols);
if (r < 0)
return r;
r = terminal_set_size_fd(fd, vc, rows, cols);
r = exec_context_apply_tty_size(context, fd, vc);
if (r < 0)
return r;

View file

@ -99,27 +99,46 @@ const char *exec_context_tty_path(const ExecContext *context) {
return "/dev/console";
}
int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows, unsigned *ret_cols) {
static void exec_context_determine_tty_size(
const ExecContext *context,
const char *tty_path,
unsigned *ret_rows,
unsigned *ret_cols) {
unsigned rows, cols;
const char *tty;
assert(context);
assert(ret_rows);
assert(ret_cols);
if (!tty_path)
tty_path = exec_context_tty_path(context);
rows = context->tty_rows;
cols = context->tty_cols;
tty = exec_context_tty_path(context);
if (tty)
(void) proc_cmdline_tty_size(tty, rows == UINT_MAX ? &rows : NULL, cols == UINT_MAX ? &cols : NULL);
if (tty_path && (rows == UINT_MAX || cols == UINT_MAX))
(void) proc_cmdline_tty_size(
tty_path,
rows == UINT_MAX ? &rows : NULL,
cols == UINT_MAX ? &cols : NULL);
*ret_rows = rows;
*ret_cols = cols;
return 0;
}
int exec_context_apply_tty_size(
const ExecContext *context,
int tty_fd,
const char *tty_path) {
unsigned rows, cols;
exec_context_determine_tty_size(context, tty_path, &rows, &cols);
return terminal_set_size_fd(tty_fd, tty_path, rows, cols);
}
void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p) {
_cleanup_close_ int _fd = -EBADF, lock_fd = -EBADF;
int fd;
@ -150,14 +169,9 @@ void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p)
(void) terminal_vhangup_fd(fd);
if (context->tty_reset)
(void) reset_terminal_fd(fd, true);
(void) reset_terminal_fd(fd, /* switch_to_text= */ true);
if (p && p->stdin_fd >= 0) {
unsigned rows = context->tty_rows, cols = context->tty_cols;
(void) exec_context_tty_size(context, &rows, &cols);
(void) terminal_set_size_fd(p->stdin_fd, path, rows, cols);
}
(void) exec_context_apply_tty_size(context, fd, path);
if (context->tty_vt_disallocate && path)
(void) vt_disallocate(path);

View file

@ -224,7 +224,11 @@ struct ExecContext {
ExecInput std_input;
ExecOutput std_output;
ExecOutput std_error;
/* At least one of stdin/stdout/stderr was initialized from an fd passed in. This boolean survives
* the fds being closed. This only makes sense for transient units. */
bool stdio_as_fds;
char *stdio_fdname[3];
char *stdio_file[3];
@ -513,7 +517,7 @@ int exec_context_get_clean_directories(ExecContext *c, char **prefix, ExecCleanM
int exec_context_get_clean_mask(ExecContext *c, ExecCleanMask *ret);
const char *exec_context_tty_path(const ExecContext *context);
int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows, unsigned *ret_cols);
int exec_context_apply_tty_size(const ExecContext *context, int tty_fd, const char *tty_path);
void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p);
uint64_t exec_context_get_rlimit(const ExecContext *c, const char *name);