✓ TTYReset=
✓ TTYVHangup=
✓ TTYVTDisallocate=
+✓ TTYRows=
+✓ TTYColumns=
✓ SyslogIdentifier=
✓ SyslogFacility=
✓ SyslogLevel=
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b TTYVTDisallocate = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly q TTYRows = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly q TTYColumns = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SyslogPriority = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s SyslogIdentifier = '...';
<!--property TTYVTDisallocate is not documented!-->
+ <!--property TTYRows is not documented!-->
+
+ <!--property TTYColumns is not documented!-->
+
<!--property SyslogPriority is not documented!-->
<!--property SyslogIdentifier is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="TTYVTDisallocate"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="TTYRows"/>
+
+ <variablelist class="dbus-property" generated="True" extra-ref="TTYColumns"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="SyslogPriority"/>
<variablelist class="dbus-property" generated="True" extra-ref="SyslogIdentifier"/>
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b TTYVTDisallocate = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly q TTYRows = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly q TTYColumns = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SyslogPriority = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s SyslogIdentifier = '...';
<!--property TTYVTDisallocate is not documented!-->
+ <!--property TTYRows is not documented!-->
+
+ <!--property TTYColumns is not documented!-->
+
<!--property SyslogPriority is not documented!-->
<!--property SyslogIdentifier is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="TTYVTDisallocate"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="TTYRows"/>
+
+ <variablelist class="dbus-property" generated="True" extra-ref="TTYColumns"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="SyslogPriority"/>
<variablelist class="dbus-property" generated="True" extra-ref="SyslogIdentifier"/>
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b TTYVTDisallocate = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly q TTYRows = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly q TTYColumns = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SyslogPriority = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s SyslogIdentifier = '...';
<!--property TTYVTDisallocate is not documented!-->
+ <!--property TTYRows is not documented!-->
+
+ <!--property TTYColumns is not documented!-->
+
<!--property SyslogPriority is not documented!-->
<!--property SyslogIdentifier is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="TTYVTDisallocate"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="TTYRows"/>
+
+ <variablelist class="dbus-property" generated="True" extra-ref="TTYColumns"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="SyslogPriority"/>
<variablelist class="dbus-property" generated="True" extra-ref="SyslogIdentifier"/>
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b TTYVTDisallocate = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly q TTYRows = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly q TTYColumns = ...;
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SyslogPriority = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s SyslogIdentifier = '...';
<!--property TTYVTDisallocate is not documented!-->
+ <!--property TTYRows is not documented!-->
+
+ <!--property TTYColumns is not documented!-->
+
<!--property SyslogPriority is not documented!-->
<!--property SyslogIdentifier is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="TTYVTDisallocate"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="TTYRows"/>
+
+ <variablelist class="dbus-property" generated="True" extra-ref="TTYColumns"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="SyslogPriority"/>
<variablelist class="dbus-property" generated="True" extra-ref="SyslogIdentifier"/>
<varname>TTYPath=</varname> before and after execution. Defaults to <literal>no</literal>.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>TTYRows=</varname></term>
+ <term><varname>TTYColumns=</varname></term>
+
+ <listitem><para>Configure the size of the TTY specified with <varname>TTYPath=</varname>. If unset or
+ set to the empty string, the kernel default is used.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>TTYVTDisallocate=</varname></term>
return cached_lines;
}
+int terminal_set_size_fd(int fd, const char *ident, unsigned rows, unsigned cols) {
+ struct winsize ws;
+
+ if (rows == UINT_MAX && cols == UINT_MAX)
+ return 0;
+
+ if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
+ return log_debug_errno(errno,
+ "TIOCGWINSZ ioctl for getting %s size failed, not setting terminal size: %m",
+ ident ?: "TTY");
+
+ if (rows == UINT_MAX)
+ rows = ws.ws_row;
+ else if (rows > USHRT_MAX)
+ rows = USHRT_MAX;
+
+ if (cols == UINT_MAX)
+ cols = ws.ws_col;
+ else if (cols > USHRT_MAX)
+ cols = USHRT_MAX;
+
+ if (rows == ws.ws_row && cols == ws.ws_col)
+ return 0;
+
+ ws.ws_row = rows;
+ ws.ws_col = cols;
+
+ if (ioctl(fd, TIOCSWINSZ, &ws) < 0)
+ return log_debug_errno(errno, "TIOCSWINSZ ioctl for setting %s size failed: %m", ident ?: "TTY");
+
+ return 0;
+}
+
/* intended to be used as a SIGWINCH sighandler */
void columns_lines_cache_reset(int signum) {
cached_columns = 0;
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 chvt(int vt);
int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl);
SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("TTYRows", "q", bus_property_get_unsigned, offsetof(ExecContext, tty_rows), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("TTYColumns", "q", bus_property_get_unsigned, offsetof(ExecContext, tty_cols), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
if (streq(name, "TTYVTDisallocate"))
return bus_set_transient_bool(u, name, &c->tty_vt_disallocate, message, flags, error);
+ if (streq(name, "TTYRows"))
+ return bus_set_transient_unsigned(u, name, &c->tty_rows, message, flags, error);
+
+ if (streq(name, "TTYColumns"))
+ return bus_set_transient_unsigned(u, name, &c->tty_cols, message, flags, error);
+
if (streq(name, "PrivateTmp"))
return bus_set_transient_bool(u, name, &c->private_tmp, message, flags, error);
(void) reset_terminal(path);
}
+ if (p && p->stdin_fd >= 0)
+ (void) terminal_set_size_fd(p->stdin_fd, path, context->tty_rows, context->tty_cols);
+
if (context->tty_vt_disallocate && path)
(void) vt_disallocate(path);
}
const int named_iofds[static 3]) {
ExecInput i;
+ int r;
assert(context);
assert(params);
if (isatty(STDIN_FILENO)) {
(void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE);
(void) reset_terminal_fd(STDIN_FILENO, true);
+ (void) terminal_set_size_fd(STDIN_FILENO, NULL, context->tty_rows, context->tty_cols);
}
return STDIN_FILENO;
if (fd < 0)
return fd;
+ r = terminal_set_size_fd(fd, exec_context_tty_path(context), context->tty_rows, context->tty_cols);
+ if (r < 0)
+ return r;
+
return move_fd(fd, STDIN_FILENO, false);
}
}
static int setup_confirm_stdio(
+ const ExecContext *context,
const char *vc,
int *ret_saved_stdin,
int *ret_saved_stdout) {
if (r < 0)
return r;
+ r = terminal_set_size_fd(fd, vc, context->tty_rows, context->tty_cols);
+ if (r < 0)
+ return r;
+
r = rearrange_stdio(fd, fd, STDERR_FILENO); /* Invalidates 'fd' also on failure */
TAKE_FD(fd);
if (r < 0)
CONFIRM_EXECUTE = 1,
};
-static int ask_for_confirmation(const char *vc, Unit *u, const char *cmdline) {
+static int ask_for_confirmation(const ExecContext *context, const char *vc, Unit *u, const char *cmdline) {
int saved_stdout = -1, saved_stdin = -1, r;
_cleanup_free_ char *e = NULL;
char c;
/* For any internal errors, assume a positive response. */
- r = setup_confirm_stdio(vc, &saved_stdin, &saved_stdout);
+ r = setup_confirm_stdio(context, vc, &saved_stdin, &saved_stdout);
if (r < 0) {
write_confirm_error(r, vc, u);
return CONFIRM_EXECUTE;
return log_oom();
}
- r = ask_for_confirmation(vc, unit, cmdline);
+ r = ask_for_confirmation(context, vc, unit, cmdline);
if (r != CONFIRM_EXECUTE) {
if (r == CONFIRM_PRETEND_SUCCESS) {
*exit_status = EXIT_SUCCESS;
#if HAVE_SECCOMP
c->syscall_errno = SECCOMP_ERROR_NUMBER_KILL;
#endif
+ c->tty_rows = UINT_MAX;
+ c->tty_cols = UINT_MAX;
numa_policy_reset(&c->numa_policy);
}
"%sTTYPath: %s\n"
"%sTTYReset: %s\n"
"%sTTYVHangup: %s\n"
- "%sTTYVTDisallocate: %s\n",
+ "%sTTYVTDisallocate: %s\n"
+ "%sTTYRows: %u\n"
+ "%sTTYColumns: %u\n",
prefix, c->tty_path,
prefix, yes_no(c->tty_reset),
prefix, yes_no(c->tty_vhangup),
- prefix, yes_no(c->tty_vt_disallocate));
+ prefix, yes_no(c->tty_vt_disallocate),
+ prefix, c->tty_rows,
+ prefix, c->tty_cols);
if (IN_SET(c->std_output,
EXEC_OUTPUT_KMSG,
bool tty_vhangup;
bool tty_vt_disallocate;
+ unsigned tty_rows;
+ unsigned tty_cols;
+
bool ignore_sigpipe;
ExecKeyringMode keyring_mode;
{{type}}.TTYReset, config_parse_bool, 0, offsetof({{type}}, exec_context.tty_reset)
{{type}}.TTYVHangup, config_parse_bool, 0, offsetof({{type}}, exec_context.tty_vhangup)
{{type}}.TTYVTDisallocate, config_parse_bool, 0, offsetof({{type}}, exec_context.tty_vt_disallocate)
+{{type}}.TTYRows, config_parse_tty_size, 0, offsetof({{type}}, exec_context.tty_rows)
+{{type}}.TTYColumns, config_parse_tty_size, 0, offsetof({{type}}, exec_context.tty_cols)
{{type}}.SyslogIdentifier, config_parse_unit_string_printf, 0, offsetof({{type}}, exec_context.syslog_identifier)
{{type}}.SyslogFacility, config_parse_log_facility, 0, offsetof({{type}}, exec_context.syslog_priority)
{{type}}.SyslogLevel, config_parse_log_level, 0, offsetof({{type}}, exec_context.syslog_priority)
return 0;
}
+
+int config_parse_tty_size(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ unsigned *sz = data;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ if (isempty(rvalue)) {
+ *sz = UINT_MAX;
+ return 0;
+ }
+
+ return config_parse_unsigned(unit, filename, line, section, section_line, lvalue, ltype, rvalue, data, userdata);
+}
CONFIG_PARSER_PROTOTYPE(config_parse_cgroup_socket_bind);
CONFIG_PARSER_PROTOTYPE(config_parse_restrict_network_interfaces);
CONFIG_PARSER_PROTOTYPE(config_parse_watchdog_sec);
+CONFIG_PARSER_PROTOTYPE(config_parse_tty_size);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
if (streq(field, "LogRateLimitIntervalSec"))
return bus_append_parse_sec_rename(m, field, eq);
- if (streq(field, "LogRateLimitBurst"))
+ if (STR_IN_SET(field, "LogRateLimitBurst",
+ "TTYRows",
+ "TTYColumns"))
return bus_append_safe_atou(m, field, eq);
if (streq(field, "MountFlags"))
TTYReset=
TTYVHangup=
TTYVTDisallocate=
+TTYRows=
+TTYColumns=
TemporaryFileSystem=
TimerSlackNSec=
TrustedCertificateFile=
TTYReset=
TTYVHangup=
TTYVTDisallocate=
+TTYRows=
+TTYColumns=
TasksAccounting=
TasksMax=
TemporaryFileSystem=
TTYReset=
TTYVHangup=
TTYVTDisallocate=
+TTYRows=
+TTYColumns=
TasksAccounting=
TasksMax=
TemporaryFileSystem=
TTYReset=
TTYVHangup=
TTYVTDisallocate=
+TTYRows=
+TTYColumns=
TasksAccounting=
TasksMax=
TemporaryFileSystem=
TTYReset=
TTYVHangup=
TTYVTDisallocate=
+TTYRows=
+TTYColumns=
TasksAccounting=
TasksMax=
TemporaryFileSystem=