mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
core: Limit terminal reset using ANSI sequences to /dev/console
Doing this in reset_terminal_fd() is a bit too invasive, see https://github.com/systemd/systemd/pull/32406#issuecomment-2070923583. Let's only do this for /dev/console so that we work around weird firmwares disabling line-wrapping, but avoid messing too much with other things. While we're at it, let's handle more than just line wrapping, and do a more general reset of stuff to get the terminal into a sane state.
This commit is contained in:
parent
1b47cfab7f
commit
00bc83a275
@ -306,29 +306,9 @@ int reset_terminal_fd(int fd, bool switch_to_text) {
|
||||
termios.c_cc[VMIN] = 1;
|
||||
|
||||
r = RET_NERRNO(tcsetattr(fd, TCSANOW, &termios));
|
||||
if (r < 0) {
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to set terminal parameters: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!terminal_is_dumb()) {
|
||||
r = fd_nonblock(fd, true);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to set terminal to non-blocking mode: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Enable line wrapping. */
|
||||
(void) loop_write_full(fd, "\033[?7h", SIZE_MAX, 50 * USEC_PER_MSEC);
|
||||
|
||||
if (r > 0) {
|
||||
r = fd_nonblock(fd, false);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to set terminal back to blocking mode: %m");
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
finish:
|
||||
/* Just in case, flush all crap out */
|
||||
(void) tcflush(fd, TCIOFLUSH);
|
||||
@ -1565,6 +1545,37 @@ int set_terminal_cursor_position(int fd, unsigned int row, unsigned int column)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int terminal_reset_ansi_seq(int fd) {
|
||||
int r, k;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
if (getenv_terminal_is_dumb())
|
||||
return 0;
|
||||
|
||||
r = fd_nonblock(fd, true);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to set terminal to non-blocking mode: %m");
|
||||
|
||||
k = loop_write_full(fd,
|
||||
"\033c" /* reset to initial state */
|
||||
"\033[!p" /* soft terminal reset */
|
||||
"\033]104\007" /* reset colors */
|
||||
"\033[?7h", /* enable line-wrapping */
|
||||
SIZE_MAX,
|
||||
50 * USEC_PER_MSEC);
|
||||
if (k < 0)
|
||||
log_debug_errno(k, "Failed to write to terminal: %m");
|
||||
|
||||
if (r > 0) {
|
||||
r = fd_nonblock(fd, false);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to set terminal back to blocking mode: %m");
|
||||
}
|
||||
|
||||
return k < 0 ? k : 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 set_terminal_cursor_position(int fd, unsigned int row, unsigned int column);
|
||||
int terminal_reset_ansi_seq(int fd);
|
||||
|
||||
int open_terminal(const char *name, int mode);
|
||||
|
||||
|
@ -208,13 +208,17 @@ static int console_setup(void) {
|
||||
|
||||
r = proc_cmdline_tty_size("/dev/console", &rows, &cols);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to get terminal size, ignoring: %m");
|
||||
log_warning_errno(r, "Failed to get /dev/console size, ignoring: %m");
|
||||
else {
|
||||
r = terminal_set_size_fd(tty_fd, NULL, rows, cols);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to set terminal size, ignoring: %m");
|
||||
log_warning_errno(r, "Failed to set /dev/console size, ignoring: %m");
|
||||
}
|
||||
|
||||
r = terminal_reset_ansi_seq(tty_fd);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to reset /dev/console using ANSI sequences, ignoring: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user