]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
terminal-util: add helper that adjust terminal width/height from data acquired via...
authorLennart Poettering <lennart@poettering.net>
Wed, 10 Jul 2024 14:33:10 +0000 (16:33 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 19 Jul 2024 09:41:43 +0000 (11:41 +0200)
src/basic/terminal-util.c
src/basic/terminal-util.h
src/test/test-terminal-util.c

index 1cfde3e3ad664fc73789eaac7e08fe3fdb4ec28e..e707adf6944bdf65ada31b214ca9338bda621086 100644 (file)
@@ -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;
+}
index e2c21f7fb72565e60820522dfd4561f97c19c5e8..1c47366eab46877698cc93a6ce8675409aec75b2 100644 (file)
@@ -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);
index 3d15d45558e5577976e4acace97e166d6ab6ce93..9a89f55c80e5777317858b8118367a908dba199a 100644 (file)
@@ -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();