launcher: Handle drm set/drop master and vt switch signals in launcher
diff --git a/src/weston-launch.c b/src/weston-launch.c
index 80c06a8..87f4641 100644
--- a/src/weston-launch.c
+++ b/src/weston-launch.c
@@ -68,6 +68,7 @@
int tty;
int ttynr;
int sock[2];
+ int drm_fd;
struct passwd *pw;
int signalfd;
@@ -223,6 +224,8 @@
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGTERM);
+ sigaddset(&mask, SIGUSR1);
+ sigaddset(&mask, SIGUSR2);
ret = sigprocmask(SIG_BLOCK, &mask, NULL);
assert(ret == 0);
@@ -243,48 +246,15 @@
}
static int
-handle_setmaster(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
+send_reply(struct weston_launch *wl, int reply)
{
- int ret = -1;
- struct cmsghdr *cmsg;
- struct weston_launcher_set_master *message;
- union cmsg_data *data;
+ int len;
- if (len != sizeof(*message)) {
- error(0, 0, "missing value in setmaster request");
- goto out;
- }
-
- message = msg->msg_iov->iov_base;
-
- cmsg = CMSG_FIRSTHDR(msg);
- if (!cmsg ||
- cmsg->cmsg_level != SOL_SOCKET ||
- cmsg->cmsg_type != SCM_RIGHTS) {
- error(0, 0, "invalid control message");
- goto out;
- }
-
- data = (union cmsg_data *) CMSG_DATA(cmsg);
- if (data->fd == -1) {
- error(0, 0, "missing drm fd in socket request");
- goto out;
- }
-
- if (message->set_master)
- ret = drmSetMaster(data->fd);
- else
- ret = drmDropMaster(data->fd);
-
- close(data->fd);
-out:
do {
- len = send(wl->sock[0], &ret, sizeof ret, 0);
+ len = send(wl->sock[0], &reply, sizeof reply, 0);
} while (len < 0 && errno == EINTR);
- if (len < 0)
- return -1;
- return 0;
+ return len;
}
static int
@@ -354,6 +324,9 @@
if (len < 0)
return -1;
+ if (major(s.st_rdev) == DRM_MAJOR)
+ wl->drm_fd = fd;
+
return 0;
}
@@ -388,9 +361,6 @@
case WESTON_LAUNCHER_OPEN:
ret = handle_open(wl, &msg, len);
break;
- case WESTON_LAUNCHER_DRM_SET_MASTER:
- ret = handle_setmaster(wl, &msg, len);
- break;
}
return ret;
@@ -451,6 +421,16 @@
if (wl->child)
kill(wl->child, sig.ssi_signo);
break;
+ case SIGUSR1:
+ send_reply(wl, WESTON_LAUNCHER_DEACTIVATE);
+ drmDropMaster(wl->drm_fd);
+ ioctl(wl->tty, VT_RELDISP, 1);
+ break;
+ case SIGUSR2:
+ ioctl(wl->tty, VT_RELDISP, VT_ACKACQ);
+ drmSetMaster(wl->drm_fd);
+ send_reply(wl, WESTON_LAUNCHER_ACTIVATE);
+ break;
default:
return -1;
}
@@ -462,6 +442,7 @@
setup_tty(struct weston_launch *wl, const char *tty)
{
struct stat buf;
+ struct vt_mode mode = { 0 };
char *t;
if (!wl->new_user) {
@@ -500,6 +481,12 @@
wl->ttynr = minor(buf.st_rdev);
}
+ mode.mode = VT_PROCESS;
+ mode.relsig = SIGUSR1;
+ mode.acqsig = SIGUSR2;
+ if (ioctl(wl->tty, VT_SETMODE, &mode) < 0)
+ error(1, errno, "failed to take control of vt handling\n");
+
return 0;
}