diff options
-rw-r--r-- | include/wlr/session.h | 12 | ||||
-rw-r--r-- | include/wlr/session/interface.h | 5 | ||||
-rw-r--r-- | session/direct.c | 50 | ||||
-rw-r--r-- | session/logind.c | 29 | ||||
-rw-r--r-- | session/session.c | 6 |
5 files changed, 59 insertions, 43 deletions
diff --git a/include/wlr/session.h b/include/wlr/session.h index 4a5b2174..52dbf8ca 100644 --- a/include/wlr/session.h +++ b/include/wlr/session.h @@ -9,16 +9,18 @@ struct session_impl; struct wlr_session { const struct session_impl *impl; - - bool active; struct wl_signal session_signal; + bool active; + + int drm_fd; + unsigned vtnr; + char seat[8]; }; struct wlr_session *wlr_session_start(struct wl_display *disp); void wlr_session_finish(struct wlr_session *session); -int wlr_session_open_file(struct wlr_session *restrict session, - const char *restrict path); +int wlr_session_open_file(struct wlr_session *session, const char *path); void wlr_session_close_file(struct wlr_session *session, int fd); -bool wlr_session_change_vt(struct wlr_session *session, int vt); +bool wlr_session_change_vt(struct wlr_session *session, unsigned vt); #endif diff --git a/include/wlr/session/interface.h b/include/wlr/session/interface.h index f75acfa4..4938110d 100644 --- a/include/wlr/session/interface.h +++ b/include/wlr/session/interface.h @@ -6,10 +6,9 @@ struct session_impl { struct wlr_session *(*start)(struct wl_display *disp); void (*finish)(struct wlr_session *session); - int (*open)(struct wlr_session *restrict session, - const char *restrict path); + int (*open)(struct wlr_session *session, const char *path); void (*close)(struct wlr_session *session, int fd); - bool (*change_vt)(struct wlr_session *session, int vt); + bool (*change_vt)(struct wlr_session *session, unsigned vt); }; #endif diff --git a/session/direct.c b/session/direct.c index 353a93bc..3932af68 100644 --- a/session/direct.c +++ b/session/direct.c @@ -30,8 +30,7 @@ const struct session_impl session_direct; struct direct_session { struct wlr_session base; int tty_fd; - int drm_fd; - int kb_mode; + int old_kbmode; int sock; pid_t child; @@ -93,8 +92,7 @@ static int send_message(int sock, enum session_message_type type, const char *pa return err ? -err : fd; } -static int direct_session_open(struct wlr_session *restrict base, - const char *restrict path) { +static int direct_session_open(struct wlr_session *base, const char *path) { struct direct_session *session = wl_container_of(base, session, base); struct stat st; @@ -115,7 +113,7 @@ static int direct_session_open(struct wlr_session *restrict base, } if (maj == DRM_MAJOR) { - session->drm_fd = fd; + session->base.drm_fd = fd; } return fd; @@ -124,17 +122,17 @@ static int direct_session_open(struct wlr_session *restrict base, static void direct_session_close(struct wlr_session *base, int fd) { struct direct_session *session = wl_container_of(base, session, base); - if (fd == session->drm_fd) { + if (fd == session->base.drm_fd) { send_message(session->sock, SESSION_DROPMASTER, NULL); - session->drm_fd = -1; + session->base.drm_fd = -1; } close(fd); } -static bool direct_change_vt(struct wlr_session *base, int vt) { +static bool direct_change_vt(struct wlr_session *base, unsigned vt) { struct direct_session *session = wl_container_of(base, session, base); - return ioctl(session->tty_fd, VT_ACTIVATE, vt) == 0; + return ioctl(session->tty_fd, VT_ACTIVATE, (int)vt) == 0; } static void direct_session_finish(struct wlr_session *base) { @@ -143,10 +141,16 @@ static void direct_session_finish(struct wlr_session *base) { .mode = VT_AUTO, }; - ioctl(session->tty_fd, KDSKBMODE, session->kb_mode); + errno = 0; + + ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode); ioctl(session->tty_fd, KDSETMODE, KD_TEXT); ioctl(session->tty_fd, VT_SETMODE, &mode); + if (errno) { + wlr_log(L_ERROR, "Failed to restore tty"); + } + send_message(session->sock, SESSION_END, NULL); close(session->sock); wait(NULL); @@ -175,8 +179,11 @@ static int vt_handler(int signo, void *data) { } static bool setup_tty(struct direct_session *session, struct wl_display *display) { - // TODO: Change this to accept any TTY, instead of just the current one session->tty_fd = dup(STDIN_FILENO); + if (session->tty_fd == -1) { + wlr_log_errno(L_ERROR, "Cannot open tty"); + return false; + } struct stat st; if (fstat(session->tty_fd, &st) == -1 || major(st.st_rdev) != TTY_MAJOR || @@ -185,9 +192,10 @@ static bool setup_tty(struct direct_session *session, struct wl_display *display goto error; } - int ret; + int tty = minor(st.st_rdev); + int ret, kd_mode; + session->base.vtnr = tty; - int kd_mode; ret = ioctl(session->tty_fd, KDGETMODE, &kd_mode); if (ret) { wlr_log_errno(L_ERROR, "Failed to get tty mode"); @@ -200,10 +208,10 @@ static bool setup_tty(struct direct_session *session, struct wl_display *display goto error; } - ioctl(session->tty_fd, VT_ACTIVATE, minor(st.st_rdev)); - ioctl(session->tty_fd, VT_WAITACTIVE, minor(st.st_rdev)); + ioctl(session->tty_fd, VT_ACTIVATE, tty); + ioctl(session->tty_fd, VT_WAITACTIVE, tty); - if (ioctl(session->tty_fd, KDGKBMODE, &session->kb_mode)) { + if (ioctl(session->tty_fd, KDGKBMODE, &session->old_kbmode)) { wlr_log_errno(L_ERROR, "Failed to read keyboard mode"); goto error; } @@ -311,8 +319,6 @@ static void communicate(int sock) { return; } } - - } #ifdef HAS_LIBCAP @@ -379,8 +385,16 @@ static struct wlr_session *direct_session_start(struct wl_display *disp) { goto error_session; } + // XXX: Is it okay to trust the environment like this? + const char *seat = getenv("XDG_SEAT"); + if (!seat) { + seat = "seat0"; + } + wlr_log(L_INFO, "Successfully loaded direct session"); + snprintf(session->base.seat, sizeof(session->base.seat), "%s", seat); + session->base.drm_fd = -1; session->base.impl = &session_direct; session->base.active = true; wl_signal_init(&session->base.session_signal); diff --git a/session/logind.c b/session/logind.c index 6eb837ed..cfbdb4c7 100644 --- a/session/logind.c +++ b/session/logind.c @@ -26,13 +26,9 @@ struct logind_session { char *id; char *path; - char *seat; - - int drm_fd; }; -static int logind_take_device(struct wlr_session *restrict base, - const char *restrict path) { +static int logind_take_device(struct wlr_session *base, const char *path) { struct logind_session *session = wl_container_of(base, session, base); int ret; @@ -72,7 +68,7 @@ static int logind_take_device(struct wlr_session *restrict base, } if (major(st.st_rdev) == DRM_MAJOR) { - session->drm_fd = fd; + session->base.drm_fd = fd; } error: @@ -102,14 +98,14 @@ static void logind_release_device(struct wlr_session *base, int fd) { } if (major(st.st_rdev) == DRM_MAJOR) { - session->drm_fd = -1; + session->base.drm_fd = -1; } sd_bus_error_free(&error); sd_bus_message_unref(msg); } -static bool logind_change_vt(struct wlr_session *base, int vt) { +static bool logind_change_vt(struct wlr_session *base, unsigned vt) { struct logind_session *session = wl_container_of(base, session, base); int ret; @@ -187,7 +183,6 @@ static void logind_session_finish(struct wlr_session *base) { sd_bus_unref(session->bus); free(session->id); free(session->path); - free(session->seat); free(session); } @@ -242,7 +237,7 @@ static int resume_device(sd_bus_message *msg, void *userdata, sd_bus_error *ret_ } if (major == DRM_MAJOR) { - dup2(fd, session->drm_fd); + dup2(fd, session->base.drm_fd); session->base.active = true; wl_signal_emit(&session->base.session_signal, session); } @@ -305,11 +300,20 @@ static struct wlr_session *logind_session_start(struct wl_display *disp) { goto error; } - ret = sd_session_get_seat(session->id, &session->seat); + ret = sd_session_get_vt(session->id, &session->base.vtnr); + if (ret < 0) { + wlr_log(L_ERROR, "Session not running in virtual terminal"); + goto error; + } + + char *seat; + ret = sd_session_get_seat(session->id, &seat); if (ret < 0) { wlr_log(L_ERROR, "Failed to get seat id: %s", strerror(-ret)); goto error; } + snprintf(session->base.seat, sizeof(session->base.seat), "%s", seat); + free(seat); const char *fmt = "/org/freedesktop/login1/session/%s"; int len = snprintf(NULL, 0, fmt, session->id); @@ -345,7 +349,7 @@ static struct wlr_session *logind_session_start(struct wl_display *disp) { wlr_log(L_INFO, "Successfully loaded logind session"); - session->drm_fd = -1; + session->base.drm_fd = -1; session->base.impl = &session_logind; session->base.active = true; wl_signal_init(&session->base.session_signal); @@ -357,7 +361,6 @@ error_bus: error: free(session->path); free(session->id); - free(session->seat); return NULL; } diff --git a/session/session.c b/session/session.c index 9de93b1d..6f6aa2ea 100644 --- a/session/session.c +++ b/session/session.c @@ -33,9 +33,7 @@ void wlr_session_finish(struct wlr_session *session) { session->impl->finish(session); }; -int wlr_session_open_file(struct wlr_session *restrict session, - const char *restrict path) { - +int wlr_session_open_file(struct wlr_session *session, const char *path) { return session->impl->open(session, path); } @@ -43,6 +41,6 @@ void wlr_session_close_file(struct wlr_session *session, int fd) { session->impl->close(session, fd); } -bool wlr_session_change_vt(struct wlr_session *session, int vt) { +bool wlr_session_change_vt(struct wlr_session *session, unsigned vt) { return session->impl->change_vt(session, vt); } |