From: Lennart Poettering Date: Fri, 19 Sep 2025 12:50:53 +0000 (+0200) Subject: ptyfwd: reset tty when exiting X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3d97db8f3c3e86b70d09444965ebfddd051df39c;p=thirdparty%2Fsystemd.git ptyfwd: reset tty when exiting Let's do a "soft" reset of the TTY when a ptyfwd session ends. This is a good idea, in order to reset changes to the scrolling window that code inside the session might have made. A "soft" reset will undo this. While we are at it, make sure to output the ansi sequences for this *after* terminating any half-written line, as that is still somewhat contents of the session, even if it's augmented. --- diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 2106d0db8c7..2175523e201 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -955,7 +955,7 @@ finish: return r; } -static int terminal_reset_ansi_seq(int fd) { +int terminal_reset_ansi_seq(int fd) { int r, k; assert(fd >= 0); diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index 28694693533..6428d9a1472 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -34,6 +34,8 @@ bool isatty_safe(int fd); +int terminal_reset_ansi_seq(int fd); + typedef enum TerminalResetFlags { TERMINAL_RESET_SWITCH_TO_TEXT = 1 << 0, TERMINAL_RESET_AVOID_ANSI_SEQ = 1 << 1, diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c index 46151ee21b9..6d2b07d2b4d 100644 --- a/src/shared/ptyfwd.c +++ b/src/shared/ptyfwd.c @@ -133,13 +133,6 @@ static void pty_forward_disconnect(PTYForward *f) { /* STDIN/STDOUT should not be non-blocking normally, so let's reset it */ (void) fd_nonblock(f->output_fd, false); - if (colors_enabled()) { - (void) loop_write(f->output_fd, ANSI_NORMAL ANSI_ERASE_TO_END_OF_SCREEN, SIZE_MAX); - - if (f->title) - (void) loop_write(f->output_fd, ANSI_WINDOW_TITLE_POP, SIZE_MAX); - } - if (f->last_char_set && f->last_char != '\n') { const char *s; @@ -153,6 +146,13 @@ static void pty_forward_disconnect(PTYForward *f) { f->last_char = '\n'; } + if (colors_enabled()) { + if (f->title) + (void) loop_write(f->output_fd, ANSI_WINDOW_TITLE_POP, SIZE_MAX); + + terminal_reset_ansi_seq(f->output_fd); + } + if (f->close_output_fd) f->output_fd = safe_close(f->output_fd); }