mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
terminal-util: add new helper terminal_reset_defensive() that combines reset-by-ioctl and reset-by-sequence reasonably
This commit is contained in:
parent
ce3a1593bc
commit
cfac09083b
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user