X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flogin%2Flogind-seat.c;h=3f5efdc8ea706f8195b463163f838a5d4d34fd75;hb=22fdeadcc06e95fe41ac4de872ec245c0887547f;hp=b8f18c47a33bc715327e39369730a756c9430593;hpb=49e6fdbf14b35d8840c3b263fd15259624b07818;p=elogind.git diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index b8f18c47a..3f5efdc8e 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -139,8 +139,8 @@ int seat_save(Seat *s) { fputs("UIDS=", f); LIST_FOREACH(sessions_by_seat, i, s->sessions) fprintf(f, - "%lu%c", - (unsigned long) i->user->uid, + UID_FMT"%c", + i->user->uid, i->sessions_by_seat_next ? ' ' : '\n'); } @@ -154,7 +154,7 @@ int seat_save(Seat *s) { finish: if (r < 0) - log_error("Failed to save seat data for %s: %s", s->id, strerror(-r)); + log_error("Failed to save seat data %s: %s", s->state_file, strerror(-r)); return r; } @@ -168,14 +168,12 @@ int seat_load(Seat *s) { } static int vt_allocate(unsigned int vtnr) { - _cleanup_free_ char *p = NULL; + char p[sizeof("/dev/tty") + DECIMAL_STR_MAX(unsigned int)]; _cleanup_close_ int fd = -1; assert(vtnr >= 1); - if (asprintf(&p, "/dev/tty%u", vtnr) < 0) - return -ENOMEM; - + snprintf(p, sizeof(p), "/dev/tty%u", vtnr); fd = open_terminal(p, O_RDWR|O_NOCTTY|O_CLOEXEC); if (fd < 0) return -errno; @@ -418,7 +416,7 @@ int seat_start(Seat *s) { return 0; } -int seat_stop(Seat *s) { +int seat_stop(Seat *s, bool force) { int r = 0; assert(s); @@ -430,7 +428,7 @@ int seat_stop(Seat *s) { "MESSAGE=Removed seat %s.", s->id, NULL); - seat_stop_sessions(s); + seat_stop_sessions(s, force); unlink(s->state_file); seat_add_to_gc_queue(s); @@ -443,14 +441,14 @@ int seat_stop(Seat *s) { return r; } -int seat_stop_sessions(Seat *s) { +int seat_stop_sessions(Seat *s, bool force) { Session *session; int r = 0, k; assert(s); LIST_FOREACH(sessions_by_seat, session, s->sessions) { - k = session_stop(session); + k = session_stop(session, force); if (k < 0) r = k; } @@ -459,6 +457,7 @@ int seat_stop_sessions(Seat *s) { } void seat_evict_position(Seat *s, Session *session) { + Session *iter; unsigned int pos = session->pos; session->pos = 0; @@ -466,8 +465,19 @@ void seat_evict_position(Seat *s, Session *session) { if (!pos) return; - if (pos < s->position_count && s->positions[pos] == session) + if (pos < s->position_count && s->positions[pos] == session) { s->positions[pos] = NULL; + + /* There might be another session claiming the same + * position (eg., during gdm->session transition), so lets look + * for it and set it on the free slot. */ + LIST_FOREACH(sessions_by_seat, iter, s->sessions) { + if (iter->pos == pos) { + s->positions[pos] = iter; + break; + } + } + } } void seat_claim_position(Seat *s, Session *session, unsigned int pos) { @@ -475,7 +485,7 @@ void seat_claim_position(Seat *s, Session *session, unsigned int pos) { if (seat_has_vts(s)) pos = session->vtnr; - if (!GREEDY_REALLOC0(s->positions, s->position_count, pos + 1)) + if (!GREEDY_REALLOC0_T(s->positions, s->position_count, pos + 1)) return; seat_evict_position(s, session);