Merge pull request #28401 from keszybz/set-console-size

Set console size when we reset it
This commit is contained in:
Luca Boccassi 2023-07-14 23:02:41 +01:00 committed by GitHub
commit 2c941b4e07
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 42 deletions

View file

@ -33,3 +33,4 @@ KernelCommandLineExtra=systemd.crash_shell
apparmor=0
selinux=0
enforcing=0
systemd.early_core_pattern=/core

View 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 {
r = reset_terminal_fd(fd, true);
unsigned rows, cols;
r = reset_terminal_fd(fd, /* switch_to_text= */ 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;

View 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);

View 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;

View 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;
}