From: Lennart Poettering Date: Wed, 10 Jul 2024 14:33:10 +0000 (+0200) Subject: terminal-util: add helper that adjust terminal width/height from data acquired via... X-Git-Tag: v257-rc1~873^2~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63c631d7e26324d96c4f7f5161c0e48b8f7b4a9d;p=thirdparty%2Fsystemd.git terminal-util: add helper that adjust terminal width/height from data acquired via ANSI sequences --- diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 1cfde3e3ad6..e707adf6944 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -2072,3 +2072,36 @@ finish: RET_GATHER(r, RET_NERRNO(tcsetattr(input_fd, TCSADRAIN, &old_termios))); return r; } + +int terminal_fix_size(int input_fd, int output_fd) { + unsigned rows, columns; + int r; + + /* Tries to update the current terminal dimensions to the ones reported via ANSI sequences */ + + r = terminal_verify_same(input_fd, output_fd); + if (r < 0) + return r; + + struct winsize ws = {}; + if (ioctl(output_fd, TIOCGWINSZ, &ws) < 0) + return log_debug_errno(errno, "Failed to query terminal dimensions, ignoring: %m"); + + r = terminal_get_size_by_dsr(input_fd, output_fd, &rows, &columns); + if (r < 0) + return log_debug_errno(r, "Failed to acquire terminal dimensions via ANSI sequences, not adjusting terminal dimensions: %m"); + + if (ws.ws_row == rows && ws.ws_col == columns) { + log_debug("Terminal dimensions reported via ANSI sequences match currently set terminal dimensions, not changing."); + return 0; + } + + ws.ws_col = columns; + ws.ws_row = rows; + + if (ioctl(output_fd, TIOCSWINSZ, &ws) < 0) + return log_debug_errno(errno, "Failed to update terminal dimensions, ignoring: %m"); + + log_debug("Fixed terminal dimensions to %ux%u based on ANSI sequence information.", columns, rows); + return 1; +} diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index e2c21f7fb72..1c47366eab4 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -296,3 +296,5 @@ void termios_disable_echo(struct termios *termios); int get_default_background_color(double *ret_red, double *ret_green, double *ret_blue); int terminal_get_size_by_dsr(int input_fd, int output_fd, unsigned *ret_rows, unsigned *ret_columns); + +int terminal_fix_size(int input_fd, int output_fd); diff --git a/src/test/test-terminal-util.c b/src/test/test-terminal-util.c index 3d15d45558e..9a89f55c80e 100644 --- a/src/test/test-terminal-util.c +++ b/src/test/test-terminal-util.c @@ -197,6 +197,18 @@ TEST(terminal_get_size_by_dsr) { } } +TEST(terminal_fix_size) { + int r; + + r = terminal_fix_size(STDIN_FILENO, STDOUT_FILENO); + if (r < 0) + log_warning_errno(r, "Failed to fix terminal size: %m"); + else if (r == 0) + log_notice("Not fixing terminal size, nothing to do."); + else + log_notice("Fixed terminal size."); +} + static void test_get_color_mode_with_env(const char *key, const char *val, ColorMode expected) { ASSERT_OK(setenv(key, val, true)); reset_terminal_feature_caches();