diff options
author | Lennart Poettering <lennart@poettering.net> | 2024-07-11 09:26:07 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2024-07-19 11:41:43 +0200 |
commit | cfac09083b287c713a2bc3724eb71468a350321d (patch) | |
tree | 33bd60ef8d5067f682092e02c9081c3ae49530ba | |
parent | terminal-util: add terminal_is_pty_fd() helper (diff) | |
download | systemd-cfac09083b287c713a2bc3724eb71468a350321d.tar.xz systemd-cfac09083b287c713a2bc3724eb71468a350321d.zip |
terminal-util: add new helper terminal_reset_defensive() that combines reset-by-ioctl and reset-by-sequence reasonably
-rw-r--r-- | src/basic/terminal-util.c | 21 | ||||
-rw-r--r-- | src/basic/terminal-util.h | 1 | ||||
-rw-r--r-- | src/core/exec-invoke.c | 4 | ||||
-rw-r--r-- | src/core/execute.c | 2 | ||||
-rw-r--r-- | src/firstboot/firstboot.c | 2 | ||||
-rw-r--r-- | src/home/homectl.c | 2 | ||||
-rw-r--r-- | src/test/test-terminal-util.c | 8 | ||||
-rw-r--r-- | src/tty-ask-password-agent/tty-ask-password-agent.c | 4 |
8 files changed, 36 insertions, 8 deletions
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 4c4a715ff6..9754b9900b 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -1575,6 +1575,27 @@ int terminal_reset_ansi_seq(int fd) { return k < 0 ? k : r; } +int terminal_reset_defensive(int fd, bool switch_to_text) { + int r = 0; + + assert(fd >= 0); + + /* Resets the terminal comprehensively, but defensively. i.e. both resets the tty via ioctl()s and + * via ANSI sequences, but avoids the latter in case we are talking to a pty. That's a safety measure + * because ptys might be connected to shell pipelines where we cannot expect such ansi sequences to + * work. Given that ptys are generally short-lived (and not recycled) this restriction shouldn't hurt + * much. + * + * The specified fd should be open for *writing*! */ + + RET_GATHER(r, reset_terminal_fd(fd, switch_to_text)); + + if (terminal_is_pty_fd(fd) == 0) + RET_GATHER(r, terminal_reset_ansi_seq(fd)); + + return r; +} + void termios_disable_echo(struct termios *termios) { assert(termios); diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index df28af02d5..c176933dd5 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -98,6 +98,7 @@ bool isatty_safe(int fd); int reset_terminal_fd(int fd, bool switch_to_text); int reset_terminal(const char *name); int terminal_reset_ansi_seq(int fd); +int terminal_reset_defensive(int fd, bool switch_to_text); int terminal_set_cursor_position(int fd, unsigned row, unsigned column); diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 94c908afd7..f8c0a81153 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -358,7 +358,7 @@ static int setup_input( (void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE); if (context->tty_reset) - (void) reset_terminal_fd(STDIN_FILENO, /* switch_to_text= */ true); + (void) terminal_reset_defensive(STDIN_FILENO, /* switch_to_text= */ true); (void) exec_context_apply_tty_size(context, STDIN_FILENO, /* tty_path= */ NULL); } @@ -675,7 +675,7 @@ static int setup_confirm_stdio( if (r < 0) return r; - r = reset_terminal_fd(fd, /* switch_to_text= */ true); + r = terminal_reset_defensive(fd, /* switch_to_text= */ true); if (r < 0) return r; diff --git a/src/core/execute.c b/src/core/execute.c index 18396db113..7590943179 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -172,7 +172,7 @@ 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, /* switch_to_text= */ true); + (void) terminal_reset_defensive(fd, /* switch_to_text= */ true); (void) exec_context_apply_tty_size(context, fd, path); diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index 92b0289859..615142cc1e 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -133,7 +133,7 @@ static void print_welcome(int rfd) { pn = os_release_pretty_name(pretty_name, os_name); ac = isempty(ansi_color) ? "0" : ansi_color; - (void) reset_terminal_fd(STDIN_FILENO, /* switch_to_text= */ false); + (void) terminal_reset_defensive(STDIN_FILENO, /* switch_to_text= */ false); if (colors_enabled()) printf("\nWelcome to your new installation of \x1B[%sm%s\x1B[0m!\n", ac, pn); diff --git a/src/home/homectl.c b/src/home/homectl.c index 65431db8ee..c64354141c 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -2438,7 +2438,7 @@ static int create_interactively(void) { (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); - (void) reset_terminal_fd(STDIN_FILENO, /* switch_to_text= */ false); + (void) terminal_reset_defensive(STDIN_FILENO, /* switch_to_text= */ false); for (;;) { username = mfree(username); diff --git a/src/test/test-terminal-util.c b/src/test/test-terminal-util.c index 2f09ae9f71..fdd590107e 100644 --- a/src/test/test-terminal-util.c +++ b/src/test/test-terminal-util.c @@ -282,4 +282,12 @@ TEST(get_color_mode) { reset_terminal_feature_caches(); } +TEST(terminal_reset_defensive) { + int r; + + r = terminal_reset_defensive(STDIN_FILENO, /* switch_to_text= */ false); + if (r < 0) + log_notice_errno(r, "Failed to reset terminal: %m"); +} + DEFINE_TEST_MAIN(LOG_INFO); diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c index 84ce5e1940..b411c9c309 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -150,9 +150,7 @@ static int agent_ask_password_tty( if (tty_fd < 0) return log_error_errno(tty_fd, "Failed to acquire %s: %m", con); - r = reset_terminal_fd(tty_fd, true); - if (r < 0) - log_warning_errno(r, "Failed to reset terminal, ignoring: %m"); + (void) terminal_reset_defensive(tty_fd, /* switch_to_text= */ true); log_info("Starting password query on %s.", con); } |