summaryrefslogtreecommitdiff
path: root/src/execute.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2011-05-18 01:07:31 +0200
committerLennart Poettering <lennart@poettering.net>2011-05-18 01:07:36 +0200
commit6ea832a20700f5282c08c70f38422c6ab290a0b5 (patch)
treebcd9a7705c87f3828adf70938ec59cdcfe368e72 /src/execute.c
parent9131f660eedb29d18a29e6efff49c485e683c56c (diff)
exec: hangup/reset/deallocate VTs in gettys
Explicitly disconnect all clients from a VT when a getty starts/finishes (requires TIOCVHANGUP, available in 2.6.29). Explicitly deallocate getty VTs in order to flush scrollback buffer. Explicitly reset terminals to a defined state before spawning getty.
Diffstat (limited to 'src/execute.c')
-rw-r--r--src/execute.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/execute.c b/src/execute.c
index 745dcfcdb8..a62f9dbbc6 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -140,6 +140,19 @@ static const char *tty_path(const ExecContext *context) {
return "/dev/console";
}
+void exec_context_tty_reset(const ExecContext *context) {
+ assert(context);
+
+ if (context->tty_vhangup)
+ terminal_vhangup(tty_path(context));
+
+ if (context->tty_reset)
+ reset_terminal(tty_path(context));
+
+ if (context->tty_vt_disallocate && context->tty_path)
+ vt_disallocate(context->tty_path);
+}
+
static int open_null_as(int flags, int nfd) {
int fd, r;
@@ -1089,6 +1102,8 @@ int exec_spawn(ExecCommand *command,
}
}
+ exec_context_tty_reset(context);
+
/* We skip the confirmation step if we shall not apply the TTY */
if (confirm_spawn &&
(!is_terminal_input(context->std_input) || apply_tty_stdin)) {
@@ -1700,8 +1715,14 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
if (c->tty_path)
fprintf(f,
- "%sTTYPath: %s\n",
- prefix, c->tty_path);
+ "%sTTYPath: %s\n"
+ "%sTTYReset: %s\n"
+ "%sTTYVHangup: %s\n"
+ "%sTTYVTDisallocate: %s\n",
+ prefix, c->tty_path,
+ prefix, yes_no(c->tty_reset),
+ prefix, yes_no(c->tty_vhangup),
+ prefix, yes_no(c->tty_vt_disallocate));
if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG ||
c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
@@ -1802,7 +1823,7 @@ void exec_status_start(ExecStatus *s, pid_t pid) {
dual_timestamp_get(&s->start_timestamp);
}
-void exec_status_exit(ExecStatus *s, pid_t pid, int code, int status, const char *utmp_id) {
+void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
assert(s);
if ((s->pid && s->pid != pid) ||
@@ -1815,8 +1836,12 @@ void exec_status_exit(ExecStatus *s, pid_t pid, int code, int status, const char
s->code = code;
s->status = status;
- if (utmp_id)
- utmp_put_dead_process(utmp_id, pid, code, status);
+ if (context) {
+ if (context->utmp_id)
+ utmp_put_dead_process(context->utmp_id, pid, code, status);
+
+ exec_context_tty_reset(context);
+ }
}
void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {