From: Daan De Meyer Date: Thu, 13 Jul 2023 12:50:23 +0000 (+0200) Subject: tree-wide: Set /dev/console size when we reset it X-Git-Tag: v254-rc2~4^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=29f5a5aef013133cfa0a60f842b434a397234d4b;p=thirdparty%2Fsystemd.git tree-wide: Set /dev/console size when we reset it 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. --- diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 31fed16682b..49a61a4f1b4 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -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; diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index 0fa01dbdf88..7a9b0fde7c0 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -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); diff --git a/src/core/execute.c b/src/core/execute.c index abedd8f5098..c2958b4bd29 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -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; diff --git a/src/core/main.c b/src/core/main.c index f9fd9fae7c3..bbbf77a7792 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -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; }