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");
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;
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);
}
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);
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;
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);
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;
}