X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogin%2Flogind-session.c;h=0c6e425603830f2bf74bef83523bc7fe1146de48;hp=fdeacb150acb42a84f203cb052fc412a613c6a50;hb=60240797a4ce464ec7a0537ccbec4c83f599251c;hpb=558c6490b1df7f82a63d0a747fda7412c4d28b0c diff --git a/src/login/logind-session.c b/src/login/logind-session.c index fdeacb150..0c6e42560 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -44,21 +44,6 @@ static void session_remove_fifo(Session *s); -static unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) { - uint64_t u = *(const dev_t*)p; - - return uint64_hash_func(&u, hash_key); -} - -static int devt_compare_func(const void *_a, const void *_b) { - dev_t a, b; - - a = *(const dev_t*) _a; - b = *(const dev_t*) _b; - - return a < b ? -1 : (a > b ? 1 : 0); -} - Session* session_new(Manager *m, const char *id) { Session *s; @@ -153,8 +138,6 @@ void session_free(Session *s) { hashmap_remove(s->manager->sessions, s->id); - s->vt_source = sd_event_source_unref(s->vt_source); - free(s->state_file); free(s); } @@ -978,8 +961,8 @@ int session_kill(Session *s, KillWho who, int signo) { static int session_open_vt(Session *s) { char path[sizeof("/dev/tty") + DECIMAL_STR_MAX(s->vtnr)]; - if (!s->vtnr) - return -1; + if (s->vtnr < 1) + return -ENODEV; if (s->vtfd >= 0) return s->vtfd; @@ -994,59 +977,56 @@ static int session_open_vt(Session *s) { return s->vtfd; } -static int session_vt_fn(sd_event_source *source, const struct signalfd_siginfo *si, void *data) { - Session *s = data; - - if (s->vtfd >= 0) - ioctl(s->vtfd, VT_RELDISP, 1); - - return 0; -} - -void session_prepare_vt(Session *s) { +int session_prepare_vt(Session *s) { int vt, r; struct vt_mode mode = { 0 }; - sigset_t mask; + + if (s->vtnr < 1) + return 0; vt = session_open_vt(s); if (vt < 0) - return; + return vt; r = fchown(vt, s->user->uid, -1); - if (r < 0) + if (r < 0) { + r = -errno; + log_error("Cannot change owner of /dev/tty%u: %m", s->vtnr); goto error; + } r = ioctl(vt, KDSKBMODE, K_OFF); - if (r < 0) + if (r < 0) { + r = -errno; + log_error("Cannot set K_OFF on /dev/tty%u: %m", s->vtnr); goto error; + } r = ioctl(vt, KDSETMODE, KD_GRAPHICS); - if (r < 0) - goto error; - - sigemptyset(&mask); - sigaddset(&mask, SIGUSR1); - sigprocmask(SIG_BLOCK, &mask, NULL); - - r = sd_event_add_signal(s->manager->event, &s->vt_source, SIGUSR1, session_vt_fn, s); - if (r < 0) + if (r < 0) { + r = -errno; + log_error("Cannot set KD_GRAPHICS on /dev/tty%u: %m", s->vtnr); goto error; + } /* Oh, thanks to the VT layer, VT_AUTO does not work with KD_GRAPHICS. * So we need a dummy handler here which just acknowledges *all* VT * switch requests. */ mode.mode = VT_PROCESS; - mode.relsig = SIGUSR1; - mode.acqsig = SIGUSR1; + mode.relsig = SIGRTMIN; + mode.acqsig = SIGRTMIN + 1; r = ioctl(vt, VT_SETMODE, &mode); - if (r < 0) + if (r < 0) { + r = -errno; + log_error("Cannot set VT_PROCESS on /dev/tty%u: %m", s->vtnr); goto error; + } - return; + return 0; error: - log_error("cannot mute VT %u for session %s (%d/%d)", s->vtnr, s->id, r, errno); session_restore_vt(s); + return r; } void session_restore_vt(Session *s) { @@ -1058,8 +1038,6 @@ void session_restore_vt(Session *s) { if (vt < 0) return; - s->vt_source = sd_event_source_unref(s->vt_source); - ioctl(vt, KDSETMODE, KD_TEXT); if (read_one_line_file("/sys/module/vt/parameters/default_utf8", &utf8) >= 0 && *utf8 == '1') @@ -1083,11 +1061,13 @@ bool session_is_controller(Session *s, const char *sender) { static void session_swap_controller(Session *s, char *name) { SessionDevice *sd; + char *c; if (s->controller) { - manager_drop_busname(s->manager, s->controller); - free(s->controller); + c = s->controller; s->controller = NULL; + manager_drop_busname(s->manager, c); + free(c); /* Drop all devices as they're now unused. Do that after the * controller is released to avoid sending out useles @@ -1125,8 +1105,6 @@ int session_set_controller(Session *s, const char *sender, bool force) { return r; } - session_swap_controller(s, t); - /* When setting a session controller, we forcibly mute the VT and set * it into graphics-mode. Applications can override that by changing * VT state after calling TakeControl(). However, this serves as a good @@ -1135,7 +1113,11 @@ int session_set_controller(Session *s, const char *sender, bool force) { * exits. * If logind crashes/restarts, we restore the controller during restart * or reset the VT in case it crashed/exited, too. */ - session_prepare_vt(s); + r = session_prepare_vt(s); + if (r < 0) + return r; + + session_swap_controller(s, t); return 0; } @@ -1164,6 +1146,7 @@ static const char* const session_type_table[_SESSION_TYPE_MAX] = { [SESSION_X11] = "x11", [SESSION_WAYLAND] = "wayland", [SESSION_MIR] = "mir", + [SESSION_WEB] = "web", }; DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);