#include "bus-error.h"
#include "logind-session.h"
-static unsigned devt_hash_func(const void *p) {
+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);
+ return uint64_hash_func(&u, hash_key);
}
static int devt_compare_func(const void *_a, const void *_b) {
return NULL;
}
- s->id = path_get_file_name(s->state_file);
+ s->id = basename(s->state_file);
if (hashmap_put(m->sessions, s->id, s) < 0) {
hashmap_free(s->devices);
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);
}
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);
_cleanup_free_ char *remote = NULL,
*seat = NULL,
*vtnr = NULL,
+ *pos = NULL,
*leader = NULL,
*type = NULL,
*class = NULL,
"REMOTE_USER", &s->remote_user,
"SERVICE", &s->service,
"VTNR", &vtnr,
+ "POS", &pos,
"LEADER", &leader,
"TYPE", &type,
"CLASS", &class,
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)
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;
"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);
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;
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);
SessionState session_get_state(Session *s) {
assert(s);
- if (s->closing)
- return SESSION_CLOSING;
-
if (s->scope_job)
return SESSION_OPENING;