[gnome-session/wip/laney/systemd-user: 49/54] gsm-systemd: Find user's graphical session, not the current pid's session
- From: Iain Lane <iainl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-session/wip/laney/systemd-user: 49/54] gsm-systemd: Find user's graphical session, not the current pid's session
- Date: Tue, 23 Oct 2018 16:48:58 +0000 (UTC)
commit 0fa5472f64b121057b001328dda2298d5a60ed6d
Author: Iain Lane <iain orangesquash org uk>
Date: Tue Dec 12 09:51:29 2017 +0000
gsm-systemd: Find user's graphical session, not the current pid's session
If we're started by systemd --user, we won't be in the XDG session of
the user. The session will still exist, and we want to monitor when it
closes so that we know when to die ourselves.
gnome-session/gsm-systemd.c | 88 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 84 insertions(+), 4 deletions(-)
---
diff --git a/gnome-session/gsm-systemd.c b/gnome-session/gsm-systemd.c
index ac72f546..1791f037 100644
--- a/gnome-session/gsm-systemd.c
+++ b/gnome-session/gsm-systemd.c
@@ -268,6 +268,86 @@ static void sd_proxy_signal_cb (GDBusProxy *proxy,
GVariant *parameters,
gpointer user_data);
+static gboolean
+gsm_systemd_find_session (gchar **session_id)
+{
+ const gchar * const graphical_session_types[] = { "wayland", "x11", "mir", NULL };
+ const gchar * const active_states[] = { "active", "online", NULL };
+ g_autofree gchar *class = NULL;
+ g_autofree gchar *local_session_id = NULL;
+ g_autofree gchar *type = NULL;
+ g_autofree gchar *state = NULL;
+ g_auto(GStrv) sessions = NULL;
+ int n_sessions;
+ int saved_errno;
+
+ g_return_val_if_fail (session_id != NULL, FALSE);
+
+ if ((saved_errno = sd_uid_get_display (getuid (), &local_session_id)) < 0) {
+ /* no session, maybe there's a greeter session */
+ if (saved_errno == -ENODATA) {
+ if ((n_sessions = sd_uid_get_sessions (getuid (), 1, &sessions)) < 0) {
+ g_critical ("Failed to get all sessions for user %d", getuid ());
+ return FALSE;
+ }
+
+ if (n_sessions == 0) {
+ g_critical ("User %d has no sessions", getuid ());
+ return FALSE;
+ }
+
+ for (int i = 0; i < n_sessions; ++i) {
+ if ((saved_errno = sd_session_get_class (sessions[i], &class)) < 0) {
+ g_warning ("Couldn't get class for session '%d': %s",
+ i,
+ g_strerror (-saved_errno));
+ continue;
+ }
+
+ if (g_strcmp0 (class, "greeter") == 0) {
+ local_session_id = g_strdup (sessions[i]);
+ break;
+ }
+ }
+ } else {
+ g_critical ("Couldn't get display: %s (%s)", g_strerror (-saved_errno),
local_session_id);
+ return FALSE;
+ }
+ }
+
+ if ((saved_errno = sd_session_get_type (local_session_id, &type)) < 0) {
+ g_critical ("Couldn't get type for session '%s': %s",
+ local_session_id,
+ g_strerror (-saved_errno));
+ return FALSE;
+ }
+
+ if (!g_strv_contains (graphical_session_types, type)) {
+ g_critical ("Session '%s' is not a graphical session (type: '%s')",
+ local_session_id,
+ type);
+ }
+
+ /* display sessions can be 'closing' if they are logged out but
+ * some processes are lingering; we shouldn't consider these */
+ if ((saved_errno = sd_session_get_state (local_session_id, &state)) < 0) {
+ g_critical ("Couldn't get state for session '%s': %s",
+ local_session_id,
+ g_strerror (-saved_errno));
+ return FALSE;
+ }
+
+ if (!g_strv_contains (active_states, state)) {
+ g_critical ("Session '%s' is not active", local_session_id);
+ return FALSE;
+ }
+
+
+ *session_id = g_steal_pointer (&local_session_id);
+
+ return TRUE;
+}
+
static void
gsm_systemd_init (GsmSystemd *manager)
{
@@ -304,7 +384,7 @@ gsm_systemd_init (GsmSystemd *manager)
g_signal_connect (manager->priv->sd_proxy, "g-signal",
G_CALLBACK (sd_proxy_signal_cb), manager);
- sd_pid_get_session (getpid (), &manager->priv->session_id);
+ gsm_systemd_find_session (&manager->priv->session_id);
if (manager->priv->session_id == NULL) {
g_warning ("Could not get session id for session. Check that logind is "
@@ -312,6 +392,8 @@ gsm_systemd_init (GsmSystemd *manager)
return;
}
+ g_debug ("Found session ID: %s", manager->priv->session_id);
+
res = g_dbus_proxy_call_sync (manager->priv->sd_proxy,
"GetSession",
g_variant_new ("(s)", manager->priv->session_id),
@@ -956,9 +1038,7 @@ gsm_systemd_is_last_session_for_user (GsmSystem *system)
gboolean is_last_session;
int ret, i;
- ret = sd_pid_get_session (getpid (), &session);
-
- if (ret != 0) {
+ if (!gsm_systemd_find_session (&session)) {
return FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]