launcher: Handle tty setup and teardown in launcher
diff --git a/src/weston-launch.c b/src/weston-launch.c
index 87f4641..059010c 100644
--- a/src/weston-launch.c
+++ b/src/weston-launch.c
@@ -28,6 +28,7 @@
#include <assert.h>
#include <poll.h>
#include <errno.h>
+#include <termios.h>
#include <error.h>
#include <getopt.h>
@@ -45,6 +46,7 @@
#include <termios.h>
#include <linux/vt.h>
#include <linux/major.h>
+#include <linux/kd.h>
#include <pwd.h>
#include <grp.h>
@@ -69,6 +71,8 @@
int ttynr;
int sock[2];
int drm_fd;
+ struct termios terminal_attributes;
+ int kb_mode;
struct passwd *pw;
int signalfd;
@@ -369,6 +373,7 @@
static void
quit(struct weston_launch *wl, int status)
{
+ struct vt_mode mode = { 0 };
int err;
close(wl->signalfd);
@@ -382,6 +387,20 @@
pam_end(wl->ph, err);
}
+ if (ioctl(wl->tty, KDSKBMODE, wl->kb_mode))
+ fprintf(stderr, "failed to restore keyboard mode: %m\n");
+
+ if (ioctl(wl->tty, KDSETMODE, KD_TEXT))
+ fprintf(stderr, "failed to set KD_TEXT mode on tty: %m\n");
+
+ if (tcsetattr(wl->tty, TCSANOW, &wl->terminal_attributes) < 0)
+ fprintf(stderr,
+ "could not restore terminal to canonical mode\n");
+
+ mode.mode = VT_AUTO;
+ if (ioctl(wl->tty, VT_SETMODE, &mode) < 0)
+ fprintf(stderr, "could not reset vt handling\n");
+
exit(status);
}
@@ -441,9 +460,11 @@
static int
setup_tty(struct weston_launch *wl, const char *tty)
{
+ struct termios raw_attributes;
struct stat buf;
struct vt_mode mode = { 0 };
char *t;
+ int ret;
if (!wl->new_user) {
wl->tty = STDIN_FILENO;
@@ -481,6 +502,30 @@
wl->ttynr = minor(buf.st_rdev);
}
+ if (tcgetattr(wl->tty, &wl->terminal_attributes) < 0)
+ error(1, errno, "could not get terminal attributes: %m\n");
+
+ /* Ignore control characters and disable echo */
+ raw_attributes = wl->terminal_attributes;
+ cfmakeraw(&raw_attributes);
+
+ /* Fix up line endings to be normal (cfmakeraw hoses them) */
+ raw_attributes.c_oflag |= OPOST | OCRNL;
+
+ if (tcsetattr(wl->tty, TCSANOW, &raw_attributes) < 0)
+ error(1, errno, "could not put terminal into raw mode: %m\n");
+
+ ioctl(wl->tty, KDGKBMODE, &wl->kb_mode);
+ ret = ioctl(wl->tty, KDSKBMODE, K_OFF);
+ if (ret)
+ ret = ioctl(wl->tty, KDSKBMODE, K_RAW);
+ if (ret)
+ error(1, errno, "failed to set keyboard mode on tty: %m\n");
+
+ ret = ioctl(wl->tty, KDSETMODE, KD_GRAPHICS);
+ if (ret)
+ error(1, errno, "failed to set KD_GRAPHICS mode on tty: %m\n");
+
mode.mode = VT_PROCESS;
mode.relsig = SIGUSR1;
mode.acqsig = SIGUSR2;