diff --git a/src/weston-launch.c b/src/weston-launch.c index 8118d038..03a6a430 100644 --- a/src/weston-launch.c +++ b/src/weston-launch.c @@ -64,6 +64,10 @@ #define KDSKBMUTE 0x4B51 #endif +#ifndef EVIOCREVOKE +#define EVIOCREVOKE _IOW('E', 0x91, int) +#endif + #define MAX_ARGV_SIZE 256 struct weston_launch { @@ -73,6 +77,7 @@ struct weston_launch { int ttynr; int sock[2]; int drm_fd; + int last_input_fd; int kb_mode; struct passwd *pw; @@ -335,6 +340,9 @@ err0: if (fd != -1 && major(s.st_rdev) == DRM_MAJOR) wl->drm_fd = fd; + if (fd != -1 && major(s.st_rdev) == INPUT_MAJOR && + wl->last_input_fd < fd) + wl->last_input_fd = fd; return 0; } @@ -406,6 +414,22 @@ quit(struct weston_launch *wl, int status) exit(status); } +static void +close_input_fds(struct weston_launch *wl) +{ + struct stat s; + int fd; + + for (fd = 3; fd <= wl->last_input_fd; fd++) { + if (fstat(fd, &s) == 0 && major(s.st_rdev) == INPUT_MAJOR) { + /* EVIOCREVOKE may fail if the kernel doesn't + * support it, but all we can do is ignore it. */ + ioctl(fd, EVIOCREVOKE, 0); + close(fd); + } + } +} + static int handle_signal(struct weston_launch *wl) { @@ -444,6 +468,7 @@ handle_signal(struct weston_launch *wl) break; case SIGUSR1: send_reply(wl, WESTON_LAUNCHER_DEACTIVATE); + close_input_fds(wl); drmDropMaster(wl->drm_fd); ioctl(wl->tty, VT_RELDISP, 1); break;