Merge pull request #1524 from mnussbaum/user-unit-wip
Allow compositors to run as systemd user units
This commit is contained in:
commit
841b4fd918
|
@ -487,6 +487,123 @@ static int dbus_event(int fd, uint32_t mask, void *data) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool contains_str(const char *needle, const char **haystack) {
|
||||||
|
for (int i = 0; haystack[i]; i++) {
|
||||||
|
if (strcmp(haystack[i], needle) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool get_greeter_session(char **session_id) {
|
||||||
|
char *class = NULL;
|
||||||
|
char **user_sessions = NULL;
|
||||||
|
int user_session_count = sd_uid_get_sessions(getuid(), 1, &user_sessions);
|
||||||
|
|
||||||
|
if (user_session_count < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to get sessions");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user_session_count == 0) {
|
||||||
|
wlr_log(WLR_ERROR, "User has no sessions");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < user_session_count; ++i) {
|
||||||
|
int ret = sd_session_get_class(user_sessions[i], &class);
|
||||||
|
if (ret < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(class, "greeter") == 0) {
|
||||||
|
*session_id = strdup(user_sessions[i]);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(class);
|
||||||
|
for (int i = 0; i < user_session_count; ++i) {
|
||||||
|
free(user_sessions[i]);
|
||||||
|
}
|
||||||
|
free(user_sessions);
|
||||||
|
|
||||||
|
return *session_id != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool get_display_session(char **session_id) {
|
||||||
|
assert(session_id != NULL);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
// If there's a session active for the current process then just use that
|
||||||
|
ret = sd_pid_get_session(getpid(), session_id);
|
||||||
|
if (ret == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *type = NULL;
|
||||||
|
char *state = NULL;
|
||||||
|
|
||||||
|
// Find any active sessions for the user if the process isn't part of an
|
||||||
|
// active session itself
|
||||||
|
ret = sd_uid_get_display(getuid(), session_id);
|
||||||
|
if (ret < 0 && ret != -ENODATA) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to get display: %s", strerror(-ret));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0 && !get_greeter_session(session_id)) {
|
||||||
|
wlr_log(WLR_ERROR, "Couldn't find an active session or a greeter session");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(*session_id != NULL);
|
||||||
|
|
||||||
|
// Check that the available session is graphical
|
||||||
|
ret = sd_session_get_type(*session_id, &type);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Couldn't get a type for session '%s': %s",
|
||||||
|
*session_id, strerror(-ret));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *graphical_session_types[] = {"wayland", "x11", "mir", NULL};
|
||||||
|
if (!contains_str(type, graphical_session_types)) {
|
||||||
|
wlr_log(WLR_ERROR, "Session '%s' isn't a graphical session (type: '%s')",
|
||||||
|
*session_id, type);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the session is active
|
||||||
|
ret = sd_session_get_state(*session_id, &state);
|
||||||
|
if (ret < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Couldn't get state for session '%s': %s",
|
||||||
|
*session_id, strerror(-ret));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *active_states[] = {"active", "online", NULL};
|
||||||
|
if (!contains_str(state, active_states)) {
|
||||||
|
wlr_log(WLR_ERROR, "Session '%s' is not active", *session_id);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(type);
|
||||||
|
free(state);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error:
|
||||||
|
free(type);
|
||||||
|
free(state);
|
||||||
|
free(*session_id);
|
||||||
|
*session_id = NULL;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static struct wlr_session *logind_session_create(struct wl_display *disp) {
|
static struct wlr_session *logind_session_create(struct wl_display *disp) {
|
||||||
int ret;
|
int ret;
|
||||||
struct logind_session *session = calloc(1, sizeof(*session));
|
struct logind_session *session = calloc(1, sizeof(*session));
|
||||||
|
@ -495,9 +612,7 @@ static struct wlr_session *logind_session_create(struct wl_display *disp) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sd_pid_get_session(getpid(), &session->id);
|
if (!get_display_session(&session->id)) {
|
||||||
if (ret < 0) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to get session id: %s", strerror(-ret));
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue