-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;
-
- assert(s);
- assert(s->user);
- assert(s->user->slice);
-
- if (!s->scope) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *description = NULL;
- const char *kill_mode;
- char *scope, *job;
-
- description = strjoin("Session ", s->id, " of user ", s->user->name, NULL);
- if (!description)
- return log_oom();
-
- scope = strjoin("session-", s->id, ".scope", NULL);
- if (!scope)
- return log_oom();
-
- kill_mode = manager_shall_kill(s->manager, s->user->name) ? "control-group" : "none";
-
- r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", kill_mode, &error, &job);
- if (r < 0) {
- log_error("Failed to start session scope %s: %s %s",
- scope, bus_error_message(&error, r), error.name);
- free(scope);
- return r;
- } else {
- s->scope = scope;
-
- free(s->scope_job);
- s->scope_job = job;
- }
- }
-
- if (s->scope)
- hashmap_put(s->manager->session_units, s->scope, s);
-
- return 0;
-}
-