]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
execute: also hook up ansi-seq-based terminal size determination with exec_context_de...
authorLennart Poettering <lennart@poettering.net>
Thu, 11 Jul 2024 09:29:15 +0000 (11:29 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 19 Jul 2024 09:44:04 +0000 (11:44 +0200)
And while we are at it, merge exec_context_determine_tty_size() +
exec_context_apply_tty_size().

Let's simplify things, and merge the two funcs, since the latter just
does one more call.

At the same time, let's make sure we actually allow passing separate
input/output fds.

src/core/exec-invoke.c
src/core/execute.c
src/core/execute.h

index f8c0a81153810d3dc51774c5f415f86194f3db72..9489fc230968ee68e39d6b6fa5681382a23e8e5b 100644 (file)
@@ -360,7 +360,7 @@ static int setup_input(
                         if (context->tty_reset)
                                 (void) terminal_reset_defensive(STDIN_FILENO, /* switch_to_text= */ true);
 
-                        (void) exec_context_apply_tty_size(context, STDIN_FILENO, /* tty_path= */ NULL);
+                        (void) exec_context_apply_tty_size(context, STDIN_FILENO, STDIN_FILENO, /* tty_path= */ NULL);
                 }
 
                 return STDIN_FILENO;
@@ -389,7 +389,7 @@ static int setup_input(
                 if (tty_fd < 0)
                         return tty_fd;
 
-                r = exec_context_apply_tty_size(context, tty_fd, tty_path);
+                r = exec_context_apply_tty_size(context, tty_fd, tty_fd, tty_path);
                 if (r < 0)
                         return r;
 
@@ -679,7 +679,7 @@ static int setup_confirm_stdio(
         if (r < 0)
                 return r;
 
-        r = exec_context_apply_tty_size(context, fd, vc);
+        r = exec_context_apply_tty_size(context, fd, fd, vc);
         if (r < 0)
                 return r;
 
index 6ed2f5a0f9d6560356afe35391f5b888400acbb4..e821133eea1fdb4a51d86ff44c34a9048dc72e1f 100644 (file)
@@ -99,45 +99,49 @@ const char* exec_context_tty_path(const ExecContext *context) {
         return "/dev/console";
 }
 
-static void exec_context_determine_tty_size(
+int exec_context_apply_tty_size(
                 const ExecContext *context,
-                const char *tty_path,
-                unsigned *ret_rows,
-                unsigned *ret_cols) {
+                int input_fd,
+                int output_fd,
+                const char *tty_path) {
 
         unsigned rows, cols;
+        int r;
 
         assert(context);
-        assert(ret_rows);
-        assert(ret_cols);
+        assert(input_fd >= 0);
+        assert(output_fd >= 0);
+
+        if (!isatty_safe(output_fd))
+                return 0;
 
         if (!tty_path)
                 tty_path = exec_context_tty_path(context);
 
+        /* Preferably use explicitly configured data */
         rows = context->tty_rows;
         cols = context->tty_cols;
 
+        /* Fill in data from kernel command line if anything is unspecified */
         if (tty_path && (rows == UINT_MAX || cols == UINT_MAX))
                 (void) proc_cmdline_tty_size(
                                 tty_path,
                                 rows == UINT_MAX ? &rows : NULL,
                                 cols == UINT_MAX ? &cols : NULL);
 
-        *ret_rows = rows;
-        *ret_cols = cols;
-}
-
-int exec_context_apply_tty_size(
-                const ExecContext *context,
-                int tty_fd,
-                const char *tty_path) {
-
-        unsigned rows, cols;
-
-        exec_context_determine_tty_size(context, tty_path, &rows, &cols);
+        /* If we got nothing so far and we are talking to a physical device, and the TTY reset logic is on,
+         * then let's query dimensions from the ANSI driver. */
+        if (rows == UINT_MAX && cols == UINT_MAX &&
+            context->tty_reset &&
+            terminal_is_pty_fd(output_fd) == 0 &&
+            isatty_safe(input_fd)) {
+                r = terminal_get_size_by_dsr(input_fd, output_fd, &rows, &cols);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to get terminal size by DSR, ignoring: %m");
+        }
 
-        return terminal_set_size_fd(tty_fd, tty_path, rows, cols);
- }
+        return terminal_set_size_fd(output_fd, tty_path, rows, cols);
+}
 
 void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p) {
         _cleanup_close_ int _fd = -EBADF, lock_fd = -EBADF;
@@ -174,7 +178,7 @@ void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p)
         if (context->tty_reset)
                 (void) terminal_reset_defensive(fd, /* switch_to_text= */ true);
 
-        (void) exec_context_apply_tty_size(context, fd, path);
+        (void) exec_context_apply_tty_size(context, fd, fd, path);
 
         if (context->tty_vt_disallocate && path)
                 (void) vt_disallocate(path);
index 0414fbad2290effbfb45e11b2240674e1f9697f3..b801bfe8532e15e1fe92574625a5c2e5f0a5db3c 100644 (file)
@@ -526,7 +526,7 @@ int exec_context_get_clean_directories(ExecContext *c, char **prefix, ExecCleanM
 int exec_context_get_clean_mask(ExecContext *c, ExecCleanMask *ret);
 
 const char* exec_context_tty_path(const ExecContext *context);
-int exec_context_apply_tty_size(const ExecContext *context, int tty_fd, const char *tty_path);
+int exec_context_apply_tty_size(const ExecContext *context, int input_fd, int output_fd, const char *tty_path);
 void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p);
 
 uint64_t exec_context_get_rlimit(const ExecContext *c, const char *name);