Skip to content

Commit 29f5a5a

Browse files
committed
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.
1 parent 85fe60b commit 29f5a5a

File tree

4 files changed

+72
-41
lines changed

4 files changed

+72
-41
lines changed

src/basic/terminal-util.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,10 +589,21 @@ int make_console_stdio(void) {
589589
return log_error_errno(r, "Failed to make /dev/null stdin/stdout/stderr: %m");
590590

591591
} else {
592+
unsigned rows, cols;
593+
592594
r = reset_terminal_fd(fd, true);
593595
if (r < 0)
594596
log_warning_errno(r, "Failed to reset terminal, ignoring: %m");
595597

598+
r = proc_cmdline_tty_size("/dev/console", &rows, &cols);
599+
if (r < 0)
600+
log_warning_errno(r, "Failed to get terminal size, ignoring: %m");
601+
else {
602+
r = terminal_set_size_fd(fd, NULL, rows, cols);
603+
if (r < 0)
604+
log_warning_errno(r, "Failed to set terminal size, ignoring: %m");
605+
}
606+
596607
r = rearrange_stdio(fd, fd, fd); /* This invalidates 'fd' both on success and on failure. */
597608
if (r < 0)
598609
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
882893
return 0;
883894
}
884895

896+
int proc_cmdline_tty_size(const char *tty, unsigned *ret_rows, unsigned *ret_cols) {
897+
_cleanup_free_ char *rowskey = NULL, *rowsvalue = NULL, *colskey = NULL, *colsvalue = NULL;
898+
unsigned rows = UINT_MAX, cols = UINT_MAX;
899+
int r;
900+
901+
assert(tty);
902+
903+
if (!ret_rows && !ret_cols)
904+
return 0;
905+
906+
tty = skip_dev_prefix(tty);
907+
if (!in_charset(tty, ALPHANUMERICAL))
908+
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "%s contains non-alphanumeric characters", tty);
909+
910+
rowskey = strjoin("systemd.tty.rows.", tty);
911+
if (!rowskey)
912+
return -ENOMEM;
913+
914+
colskey = strjoin("systemd.tty.columns.", tty);
915+
if (!colskey)
916+
return -ENOMEM;
917+
918+
r = proc_cmdline_get_key_many(/* flags = */ 0,
919+
rowskey, &rowsvalue,
920+
colskey, &colsvalue);
921+
if (r < 0)
922+
return log_debug_errno(r, "Failed to read TTY size of %s from kernel cmdline: %m", tty);
923+
924+
if (rowsvalue) {
925+
r = safe_atou(rowsvalue, &rows);
926+
if (r < 0)
927+
return log_debug_errno(r, "Failed to parse %s=%s: %m", rowskey, rowsvalue);
928+
}
929+
930+
if (colsvalue) {
931+
r = safe_atou(colsvalue, &cols);
932+
if (r < 0)
933+
return log_debug_errno(r, "Failed to parse %s=%s: %m", colskey, colsvalue);
934+
}
935+
936+
if (ret_rows)
937+
*ret_rows = rows;
938+
if (ret_cols)
939+
*ret_cols = cols;
940+
941+
return 0;
942+
}
943+
885944
/* intended to be used as a SIGWINCH sighandler */
886945
void columns_lines_cache_reset(int signum) {
887946
cached_columns = 0;

src/basic/terminal-util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ int terminal_vhangup_fd(int fd);
127127
int terminal_vhangup(const char *name);
128128

129129
int terminal_set_size_fd(int fd, const char *ident, unsigned rows, unsigned cols);
130+
int proc_cmdline_tty_size(const char *tty, unsigned *ret_rows, unsigned *ret_cols);
130131

131132
int chvt(int vt);
132133

src/core/execute.c

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,8 @@ static const char *exec_context_tty_path(const ExecContext *context) {
208208
}
209209

210210
static int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows, unsigned *ret_cols) {
211-
_cleanup_free_ char *rowskey = NULL, *rowsvalue = NULL, *colskey = NULL, *colsvalue = NULL;
212211
unsigned rows, cols;
213212
const char *tty;
214-
int r;
215213

216214
assert(context);
217215
assert(ret_rows);
@@ -221,45 +219,8 @@ static int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows,
221219
cols = context->tty_cols;
222220

223221
tty = exec_context_tty_path(context);
224-
if (!tty || (rows != UINT_MAX && cols != UINT_MAX)) {
225-
*ret_rows = rows;
226-
*ret_cols = cols;
227-
return 0;
228-
}
229-
230-
tty = skip_dev_prefix(tty);
231-
if (!in_charset(tty, ALPHANUMERICAL)) {
232-
log_debug("%s contains non-alphanumeric characters, ignoring", tty);
233-
*ret_rows = rows;
234-
*ret_cols = cols;
235-
return 0;
236-
}
237-
238-
rowskey = strjoin("systemd.tty.rows.", tty);
239-
if (!rowskey)
240-
return -ENOMEM;
241-
242-
colskey = strjoin("systemd.tty.columns.", tty);
243-
if (!colskey)
244-
return -ENOMEM;
245-
246-
r = proc_cmdline_get_key_many(/* flags = */ 0,
247-
rowskey, &rowsvalue,
248-
colskey, &colsvalue);
249-
if (r < 0)
250-
log_debug_errno(r, "Failed to read TTY size of %s from kernel cmdline, ignoring: %m", tty);
251-
252-
if (rows == UINT_MAX && rowsvalue) {
253-
r = safe_atou(rowsvalue, &rows);
254-
if (r < 0)
255-
log_debug_errno(r, "Failed to parse %s=%s, ignoring: %m", rowskey, rowsvalue);
256-
}
257-
258-
if (cols == UINT_MAX && colsvalue) {
259-
r = safe_atou(colsvalue, &cols);
260-
if (r < 0)
261-
log_debug_errno(r, "Failed to parse %s=%s, ignoring: %m", colskey, colsvalue);
262-
}
222+
if (tty)
223+
(void) proc_cmdline_tty_size(tty, rows == UINT_MAX ? &rows : NULL, cols == UINT_MAX ? &cols : NULL);
263224

264225
*ret_rows = rows;
265226
*ret_cols = cols;

src/core/main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ static int manager_find_user_config_paths(char ***ret_files, char ***ret_dirs) {
220220

221221
static int console_setup(void) {
222222
_cleanup_close_ int tty_fd = -EBADF;
223+
unsigned rows, cols;
223224
int r;
224225

225226
tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
@@ -232,6 +233,15 @@ static int console_setup(void) {
232233
if (r < 0)
233234
return log_error_errno(r, "Failed to reset /dev/console: %m");
234235

236+
r = proc_cmdline_tty_size("/dev/console", &rows, &cols);
237+
if (r < 0)
238+
log_warning_errno(r, "Failed to get terminal size, ignoring: %m");
239+
else {
240+
r = terminal_set_size_fd(tty_fd, NULL, rows, cols);
241+
if (r < 0)
242+
log_warning_errno(r, "Failed to set terminal size, ignoring: %m");
243+
}
244+
235245
return 0;
236246
}
237247

0 commit comments

Comments
 (0)