chiark / gitweb /
logind: introduce session "positions"
[elogind.git] / src / login / logind-session.c
index dc4b3e1621f033a8561e2d76fe345c88905b4c3c..ff0a7a4f2e2253094317f1e2cba5a3d3b3636aac 100644 (file)
@@ -125,6 +125,7 @@ void session_free(Session *s) {
                 if (s->seat->pending_switch == s)
                         s->seat->pending_switch = NULL;
 
+                seat_evict_position(s->seat, s);
                 LIST_REMOVE(sessions_by_seat, s->seat->sessions, s);
         }
 
@@ -231,6 +232,9 @@ int session_save(Session *s) {
         if (s->seat && seat_has_vts(s->seat))
                 fprintf(f, "VTNR=%u\n", s->vtnr);
 
+        if (!s->vtnr)
+                fprintf(f, "POS=%u\n", s->pos);
+
         if (s->leader > 0)
                 fprintf(f, "LEADER=%lu\n", (unsigned long) s->leader);
 
@@ -266,6 +270,7 @@ int session_load(Session *s) {
         _cleanup_free_ char *remote = NULL,
                 *seat = NULL,
                 *vtnr = NULL,
+                *pos = NULL,
                 *leader = NULL,
                 *type = NULL,
                 *class = NULL,
@@ -290,6 +295,7 @@ int session_load(Session *s) {
                            "REMOTE_USER",    &s->remote_user,
                            "SERVICE",        &s->service,
                            "VTNR",           &vtnr,
+                           "POS",            &pos,
                            "LEADER",         &leader,
                            "TYPE",           &type,
                            "CLASS",          &class,
@@ -350,6 +356,13 @@ int session_load(Session *s) {
         if (!s->seat || !seat_has_vts(s->seat))
                 s->vtnr = 0;
 
+        if (pos && s->seat) {
+                unsigned int npos;
+
+                safe_atou(pos, &npos);
+                seat_claim_position(s->seat, s, npos);
+        }
+
         if (leader) {
                 k = parse_pid(leader, &s->leader);
                 if (k >= 0)
@@ -444,72 +457,6 @@ int session_activate(Session *s) {
         return 0;
 }
 
-static int session_link_x11_socket(Session *s) {
-        _cleanup_free_ char *t = NULL, *f = NULL;
-        char *c;
-        size_t k;
-
-        assert(s);
-        assert(s->user);
-        assert(s->user->runtime_path);
-
-        if (s->user->display)
-                return 0;
-
-        if (!s->display || !display_is_local(s->display))
-                return 0;
-
-        k = strspn(s->display+1, "0123456789");
-        f = new(char, sizeof("/tmp/.X11-unix/X") + k);
-        if (!f)
-                return log_oom();
-
-        c = stpcpy(f, "/tmp/.X11-unix/X");
-        memcpy(c, s->display+1, k);
-        c[k] = 0;
-
-        if (access(f, F_OK) < 0) {
-                log_warning("Session %s has display %s with non-existing socket %s.", s->id, s->display, f);
-                return -ENOENT;
-        }
-
-        /* Note that this cannot be in a subdir to avoid
-         * vulnerabilities since we are privileged but the runtime
-         * path is owned by the user */
-
-        t = strappend(s->user->runtime_path, "/X11-display");
-        if (!t)
-                return log_oom();
-
-        if (link(f, t) < 0) {
-                if (errno == EEXIST) {
-                        unlink(t);
-
-                        if (link(f, t) >= 0)
-                                goto done;
-                }
-
-                if (symlink(f, t) < 0) {
-
-                        if (errno == EEXIST) {
-                                unlink(t);
-
-                                if (symlink(f, t) >= 0)
-                                        goto done;
-                        }
-
-                        log_error("Failed to link %s to %s: %m", f, t);
-                        return -errno;
-                }
-        }
-
-done:
-        log_info("Linked %s to %s.", f, t);
-        s->user->display = s;
-
-        return 0;
-}
-
 static int session_start_scope(Session *s) {
         int r;
 
@@ -581,9 +528,6 @@ int session_start(Session *s) {
                    "MESSAGE=New session %s of user %s.", s->id, s->user->name,
                    NULL);
 
-        /* Create X11 symlink */
-        session_link_x11_socket(s);
-
         if (!dual_timestamp_is_set(&s->timestamp))
                 dual_timestamp_get(&s->timestamp);
 
@@ -634,26 +578,6 @@ static int session_stop_scope(Session *s) {
         return 0;
 }
 
-static int session_unlink_x11_socket(Session *s) {
-        _cleanup_free_ char *t = NULL;
-        int r;
-
-        assert(s);
-        assert(s->user);
-
-        if (s->user->display != s)
-                return 0;
-
-        s->user->display = NULL;
-
-        t = strappend(s->user->runtime_path, "/X11-display");
-        if (!t)
-                return log_oom();
-
-        r = unlink(t);
-        return r < 0 ? -errno : 0;
-}
-
 int session_stop(Session *s) {
         int r;
 
@@ -693,9 +617,6 @@ int session_finalize(Session *s) {
         while ((sd = hashmap_first(s->devices)))
                 session_device_free(sd);
 
-        /* Remove X11 symlink */
-        session_unlink_x11_socket(s);
-
         unlink(s->state_file);
         session_add_to_gc_queue(s);
         user_add_to_gc_queue(s->user);