launcher: Handle tty setup and teardown in launcher

dev
Kristian Høgsberg 11 years ago
parent 1eb482d814
commit 81b4963949
  1. 12
      src/compositor-drm.c
  2. 2
      src/tty.c
  3. 45
      src/weston-launch.c

@ -2242,10 +2242,12 @@ drm_restore(struct weston_compositor *ec)
{ {
struct drm_compositor *d = (struct drm_compositor *) ec; struct drm_compositor *d = (struct drm_compositor *) ec;
if (ec->launcher == NULL && drmDropMaster(d->drm.fd) < 0) if (ec->launcher == NULL) {
if (drmDropMaster(d->drm.fd) < 0)
weston_log("failed to drop master: %m\n"); weston_log("failed to drop master: %m\n");
tty_reset(d->tty); tty_reset(d->tty);
} }
}
static void static void
drm_destroy(struct weston_compositor *ec) drm_destroy(struct weston_compositor *ec)
@ -2266,9 +2268,11 @@ drm_destroy(struct weston_compositor *ec)
if (d->gbm) if (d->gbm)
gbm_device_destroy(d->gbm); gbm_device_destroy(d->gbm);
if (d->base.launcher == NULL && drmDropMaster(d->drm.fd) < 0) if (d->base.launcher == NULL) {
if (drmDropMaster(d->drm.fd) < 0)
weston_log("failed to drop master: %m\n"); weston_log("failed to drop master: %m\n");
tty_destroy(d->tty); tty_destroy(d->tty);
}
close(d->drm.fd); close(d->drm.fd);
@ -2366,6 +2370,7 @@ switch_vt_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *d
{ {
struct drm_compositor *ec = data; struct drm_compositor *ec = data;
if (ec->tty)
tty_activate_vt(ec->tty, key - KEY_F1 + 1); tty_activate_vt(ec->tty, key - KEY_F1 + 1);
} }
@ -2585,11 +2590,13 @@ drm_compositor_create(struct wl_display *display,
ec->base.wl_display = display; ec->base.wl_display = display;
ec->session_listener.notify = session_notify; ec->session_listener.notify = session_notify;
wl_signal_add(&ec->base.session_signal, &ec->session_listener); wl_signal_add(&ec->base.session_signal, &ec->session_listener);
if (ec->base.launcher == NULL) {
ec->tty = tty_create(&ec->base, tty); ec->tty = tty_create(&ec->base, tty);
if (!ec->tty) { if (!ec->tty) {
weston_log("failed to initialize tty\n"); weston_log("failed to initialize tty\n");
goto err_udev; goto err_udev;
} }
}
drm_device = find_primary_gpu(ec, seat_id); drm_device = find_primary_gpu(ec, seat_id);
if (drm_device == NULL) { if (drm_device == NULL) {
@ -2692,6 +2699,7 @@ err_udev_dev:
err_tty: err_tty:
if (ec->base.launcher == NULL && drmDropMaster(ec->drm.fd) < 0) if (ec->base.launcher == NULL && drmDropMaster(ec->drm.fd) < 0)
weston_log("failed to drop master: %m\n"); weston_log("failed to drop master: %m\n");
if (ec->tty)
tty_destroy(ec->tty); tty_destroy(ec->tty);
err_udev: err_udev:
udev_unref(ec->udev); udev_unref(ec->udev);

@ -219,7 +219,6 @@ tty_create(struct weston_compositor *compositor, int tty_nr)
goto err_kdkbmode; goto err_kdkbmode;
} }
if (compositor->launcher == NULL) {
mode.mode = VT_PROCESS; mode.mode = VT_PROCESS;
mode.relsig = SIGUSR1; mode.relsig = SIGUSR1;
mode.acqsig = SIGUSR1; mode.acqsig = SIGUSR1;
@ -232,7 +231,6 @@ tty_create(struct weston_compositor *compositor, int tty_nr)
wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, tty); wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, tty);
if (!tty->vt_source) if (!tty->vt_source)
goto err_vtmode; goto err_vtmode;
}
return tty; return tty;

@ -28,6 +28,7 @@
#include <assert.h> #include <assert.h>
#include <poll.h> #include <poll.h>
#include <errno.h> #include <errno.h>
#include <termios.h>
#include <error.h> #include <error.h>
#include <getopt.h> #include <getopt.h>
@ -45,6 +46,7 @@
#include <termios.h> #include <termios.h>
#include <linux/vt.h> #include <linux/vt.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/kd.h>
#include <pwd.h> #include <pwd.h>
#include <grp.h> #include <grp.h>
@ -69,6 +71,8 @@ struct weston_launch {
int ttynr; int ttynr;
int sock[2]; int sock[2];
int drm_fd; int drm_fd;
struct termios terminal_attributes;
int kb_mode;
struct passwd *pw; struct passwd *pw;
int signalfd; int signalfd;
@ -369,6 +373,7 @@ handle_socket_msg(struct weston_launch *wl)
static void static void
quit(struct weston_launch *wl, int status) quit(struct weston_launch *wl, int status)
{ {
struct vt_mode mode = { 0 };
int err; int err;
close(wl->signalfd); close(wl->signalfd);
@ -382,6 +387,20 @@ quit(struct weston_launch *wl, int status)
pam_end(wl->ph, err); 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); exit(status);
} }
@ -441,9 +460,11 @@ handle_signal(struct weston_launch *wl)
static int static int
setup_tty(struct weston_launch *wl, const char *tty) setup_tty(struct weston_launch *wl, const char *tty)
{ {
struct termios raw_attributes;
struct stat buf; struct stat buf;
struct vt_mode mode = { 0 }; struct vt_mode mode = { 0 };
char *t; char *t;
int ret;
if (!wl->new_user) { if (!wl->new_user) {
wl->tty = STDIN_FILENO; wl->tty = STDIN_FILENO;
@ -481,6 +502,30 @@ setup_tty(struct weston_launch *wl, const char *tty)
wl->ttynr = minor(buf.st_rdev); 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.mode = VT_PROCESS;
mode.relsig = SIGUSR1; mode.relsig = SIGUSR1;
mode.acqsig = SIGUSR2; mode.acqsig = SIGUSR2;

Loading…
Cancel
Save