launcher: Handle tty setup and teardown in launcher
This commit is contained in:
+20
-12
@@ -2242,9 +2242,11 @@ 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) {
|
||||||
weston_log("failed to drop master: %m\n");
|
if (drmDropMaster(d->drm.fd) < 0)
|
||||||
tty_reset(d->tty);
|
weston_log("failed to drop master: %m\n");
|
||||||
|
tty_reset(d->tty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -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) {
|
||||||
weston_log("failed to drop master: %m\n");
|
if (drmDropMaster(d->drm.fd) < 0)
|
||||||
tty_destroy(d->tty);
|
weston_log("failed to drop master: %m\n");
|
||||||
|
tty_destroy(d->tty);
|
||||||
|
}
|
||||||
|
|
||||||
close(d->drm.fd);
|
close(d->drm.fd);
|
||||||
|
|
||||||
@@ -2366,7 +2370,8 @@ 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;
|
||||||
|
|
||||||
tty_activate_vt(ec->tty, key - KEY_F1 + 1);
|
if (ec->tty)
|
||||||
|
tty_activate_vt(ec->tty, key - KEY_F1 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2585,10 +2590,12 @@ 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);
|
||||||
ec->tty = tty_create(&ec->base, tty);
|
if (ec->base.launcher == NULL) {
|
||||||
if (!ec->tty) {
|
ec->tty = tty_create(&ec->base, tty);
|
||||||
weston_log("failed to initialize tty\n");
|
if (!ec->tty) {
|
||||||
goto err_udev;
|
weston_log("failed to initialize tty\n");
|
||||||
|
goto err_udev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_device = find_primary_gpu(ec, seat_id);
|
drm_device = find_primary_gpu(ec, seat_id);
|
||||||
@@ -2692,7 +2699,8 @@ 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");
|
||||||
tty_destroy(ec->tty);
|
if (ec->tty)
|
||||||
|
tty_destroy(ec->tty);
|
||||||
err_udev:
|
err_udev:
|
||||||
udev_unref(ec->udev);
|
udev_unref(ec->udev);
|
||||||
err_compositor:
|
err_compositor:
|
||||||
|
|||||||
@@ -219,21 +219,19 @@ 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;
|
if (ioctl(tty->fd, VT_SETMODE, &mode) < 0) {
|
||||||
if (ioctl(tty->fd, VT_SETMODE, &mode) < 0) {
|
weston_log("failed to take control of vt handling\n");
|
||||||
weston_log("failed to take control of vt handling\n");
|
goto err_kdmode;
|
||||||
goto err_kdmode;
|
|
||||||
}
|
|
||||||
|
|
||||||
tty->vt_source =
|
|
||||||
wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, tty);
|
|
||||||
if (!tty->vt_source)
|
|
||||||
goto err_vtmode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tty->vt_source =
|
||||||
|
wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, tty);
|
||||||
|
if (!tty->vt_source)
|
||||||
|
goto err_vtmode;
|
||||||
|
|
||||||
return tty;
|
return tty;
|
||||||
|
|
||||||
err_vtmode:
|
err_vtmode:
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user