chiark / gitweb /
systemctl: prefix list-units and list-machines output with a circle indicating a...
[elogind.git] / src / login / logind-seat.c
index 631be5f7409830d87592f6b278ce3057911e1b6a..3f5efdc8ea706f8195b463163f838a5d4d34fd75 100644 (file)
@@ -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;
@@ -459,6 +457,7 @@ int seat_stop_sessions(Seat *s, bool force) {
 }
 
 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);