]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: Set /dev/console size when we reset it
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 13 Jul 2023 12:50:23 +0000 (14:50 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 14 Jul 2023 07:11:29 +0000 (09:11 +0200)
If a size is configured for /dev/console via the kernel cmdline,
let's make sure we take that into account when resetting /dev/console.

src/basic/terminal-util.c
src/basic/terminal-util.h
src/core/execute.c
src/core/main.c

index 31fed16682bad1721fbc38a364ee816e29f578d3..49a61a4f1b4c5ef04c54a3a1e6a6b71dd572c251 100644 (file)
@@ -589,10 +589,21 @@ int make_console_stdio(void) {
                         return log_error_errno(r, "Failed to make /dev/null stdin/stdout/stderr: %m");
 
         } else {
+                unsigned rows, cols;
+
                 r = reset_terminal_fd(fd, true);
                 if (r < 0)
                         log_warning_errno(r, "Failed to reset terminal, ignoring: %m");
 
+                r = proc_cmdline_tty_size("/dev/console", &rows, &cols);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to get terminal size, ignoring: %m");
+                else {
+                        r = terminal_set_size_fd(fd, NULL, rows, cols);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to set terminal size, ignoring: %m");
+                }
+
                 r = rearrange_stdio(fd, fd, fd); /* This invalidates 'fd' both on success and on failure. */
                 if (r < 0)
                         return log_error_errno(r, "Failed to make terminal stdin/stdout/stderr: %m");
@@ -882,6 +893,54 @@ int terminal_set_size_fd(int fd, const char *ident, unsigned rows, unsigned cols
         return 0;
 }
 
+int proc_cmdline_tty_size(const char *tty, unsigned *ret_rows, unsigned *ret_cols) {
+        _cleanup_free_ char *rowskey = NULL, *rowsvalue = NULL, *colskey = NULL, *colsvalue = NULL;
+        unsigned rows = UINT_MAX, cols = UINT_MAX;
+        int r;
+
+        assert(tty);
+
+        if (!ret_rows && !ret_cols)
+                return 0;
+
+        tty = skip_dev_prefix(tty);
+        if (!in_charset(tty, ALPHANUMERICAL))
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "%s contains non-alphanumeric characters", tty);
+
+        rowskey = strjoin("systemd.tty.rows.", tty);
+        if (!rowskey)
+                return -ENOMEM;
+
+        colskey = strjoin("systemd.tty.columns.", tty);
+        if (!colskey)
+                return -ENOMEM;
+
+        r = proc_cmdline_get_key_many(/* flags = */ 0,
+                                      rowskey, &rowsvalue,
+                                      colskey, &colsvalue);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to read TTY size of %s from kernel cmdline: %m", tty);
+
+        if (rowsvalue) {
+                r = safe_atou(rowsvalue, &rows);
+                if (r < 0)
+                        return log_debug_errno(r, "Failed to parse %s=%s: %m", rowskey, rowsvalue);
+        }
+
+        if (colsvalue) {
+                r = safe_atou(colsvalue, &cols);
+                if (r < 0)
+                        return log_debug_errno(r, "Failed to parse %s=%s: %m", colskey, colsvalue);
+        }
+
+        if (ret_rows)
+                *ret_rows = rows;
+        if (ret_cols)
+                *ret_cols = cols;
+
+        return 0;
+}
+
 /* intended to be used as a SIGWINCH sighandler */
 void columns_lines_cache_reset(int signum) {
         cached_columns = 0;
index 0fa01dbdf88e77fbdda5b8a4b3fafe9e8d01c2cc..7a9b0fde7c0bd250e0f24a55576f7a5dbdf28bef 100644 (file)
@@ -127,6 +127,7 @@ int terminal_vhangup_fd(int fd);
 int terminal_vhangup(const char *name);
 
 int terminal_set_size_fd(int fd, const char *ident, unsigned rows, unsigned cols);
+int proc_cmdline_tty_size(const char *tty, unsigned *ret_rows, unsigned *ret_cols);
 
 int chvt(int vt);
 
index abedd8f50983a3e08b997eeef1d60f7531313387..c2958b4bd2916b87474719b84c1ea67d4e49c7d2 100644 (file)
@@ -208,10 +208,8 @@ static const char *exec_context_tty_path(const ExecContext *context) {
 }
 
 static int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows, unsigned *ret_cols) {
-        _cleanup_free_ char *rowskey = NULL, *rowsvalue = NULL, *colskey = NULL, *colsvalue = NULL;
         unsigned rows, cols;
         const char *tty;
-        int r;
 
         assert(context);
         assert(ret_rows);
@@ -221,45 +219,8 @@ static int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows,
         cols = context->tty_cols;
 
         tty = exec_context_tty_path(context);
-        if (!tty || (rows != UINT_MAX && cols != UINT_MAX)) {
-                *ret_rows = rows;
-                *ret_cols = cols;
-                return 0;
-        }
-
-        tty = skip_dev_prefix(tty);
-        if (!in_charset(tty, ALPHANUMERICAL)) {
-                log_debug("%s contains non-alphanumeric characters, ignoring", tty);
-                *ret_rows = rows;
-                *ret_cols = cols;
-                return 0;
-        }
-
-        rowskey = strjoin("systemd.tty.rows.", tty);
-        if (!rowskey)
-                return -ENOMEM;
-
-        colskey = strjoin("systemd.tty.columns.", tty);
-        if (!colskey)
-                return -ENOMEM;
-
-        r = proc_cmdline_get_key_many(/* flags = */ 0,
-                                      rowskey, &rowsvalue,
-                                      colskey, &colsvalue);
-        if (r < 0)
-                log_debug_errno(r, "Failed to read TTY size of %s from kernel cmdline, ignoring: %m", tty);
-
-        if (rows == UINT_MAX && rowsvalue) {
-                r = safe_atou(rowsvalue, &rows);
-                if (r < 0)
-                        log_debug_errno(r, "Failed to parse %s=%s, ignoring: %m", rowskey, rowsvalue);
-        }
-
-        if (cols == UINT_MAX && colsvalue) {
-                r = safe_atou(colsvalue, &cols);
-                if (r < 0)
-                        log_debug_errno(r, "Failed to parse %s=%s, ignoring: %m", colskey, colsvalue);
-        }
+        if (tty)
+                (void) proc_cmdline_tty_size(tty, rows == UINT_MAX ? &rows : NULL, cols == UINT_MAX ? &cols : NULL);
 
         *ret_rows = rows;
         *ret_cols = cols;
index f9fd9fae7c34eae11032eb8abd1f5805b3724b3f..bbbf77a7792dbfa16e03943679716770b8ee2ad3 100644 (file)
@@ -220,6 +220,7 @@ static int manager_find_user_config_paths(char ***ret_files, char ***ret_dirs) {
 
 static int console_setup(void) {
         _cleanup_close_ int tty_fd = -EBADF;
+        unsigned rows, cols;
         int r;
 
         tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
@@ -232,6 +233,15 @@ static int console_setup(void) {
         if (r < 0)
                 return log_error_errno(r, "Failed to reset /dev/console: %m");
 
+        r = proc_cmdline_tty_size("/dev/console", &rows, &cols);
+        if (r < 0)
+                log_warning_errno(r, "Failed to get terminal 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");
+        }
+
         return 0;
 }