[gnome-session/wip/halfline/env-to-systemd] gsm-util: export environment to systemd



commit 415230016aa7e038a48994b5c0248de7569af23f
Author: Ray Strode <rstrode redhat com>
Date:   Wed Sep 16 13:48:24 2015 -0400

    gsm-util: export environment to systemd
    
    If we get passed an environment variable, send it along to the
    systemd --user session so things running in that context can pick it
    up.
    
    Also, things in the session can then sync their environment with that
    central location to make sure they get environment updates.

 gnome-session/gsm-util.c |  124 +++++++++++++++++++++++++++++++++++++++++++--
 gnome-session/gsm-util.h |    3 +
 gnome-session/main.c     |    4 ++
 3 files changed, 125 insertions(+), 6 deletions(-)
---
diff --git a/gnome-session/gsm-util.c b/gnome-session/gsm-util.c
index b7d2cda..ce8ac8c 100644
--- a/gnome-session/gsm-util.c
+++ b/gnome-session/gsm-util.c
@@ -491,24 +491,136 @@ gsm_util_update_activation_environment (const char  *variable,
         return environment_updated;
 }
 
+#ifdef HAVE_SYSTEMD
+gboolean
+gsm_util_export_user_environment (GError     **error)
+{
+
+        GDBusConnection *connection;
+        gboolean         environment_updated;
+        char           **entries;
+        int              i = 0;
+        GVariantBuilder  builder;
+        GVariant        *reply;
+        GError          *bus_error = NULL;
+
+        environment_updated = FALSE;
+        connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
+
+        if (connection == NULL) {
+                return FALSE;
+        }
+
+        entries = g_get_environ ();
+
+        g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+        for (entries = g_get_environ (); entries[i] != NULL; i++) {
+                const char *entry = entries[i];
+
+                if (g_utf8_validate (entry, -1, NULL)) {
+                        g_variant_builder_add (&builder, "s", entry);
+                }
+
+        }
+
+        g_strfreev (entries);
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             "org.freedesktop.systemd1",
+                                             "/org/freedesktop/systemd1",
+                                             "org.freedesktop.systemd1.Manager",
+                                             "SetEnvironment",
+                                             g_variant_new ("(@as)",
+                                                            g_variant_builder_end (&builder)),
+                                             NULL,
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1, NULL, &bus_error);
+
+        if (bus_error != NULL) {
+                g_propagate_error (error, bus_error);
+        } else {
+                environment_updated = TRUE;
+                g_variant_unref (reply);
+        }
+
+        g_clear_object (&connection);
+
+        return environment_updated;
+}
+
+static gboolean
+gsm_util_update_user_environment (const char  *variable,
+                                  const char  *value,
+                                  GError     **error)
+{
+        GDBusConnection *connection;
+        gboolean         environment_updated;
+        char            *entry;
+        GVariantBuilder  builder;
+        GVariant        *reply;
+        GError          *bus_error = NULL;
+
+        environment_updated = FALSE;
+        connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
+
+        if (connection == NULL) {
+                return FALSE;
+        }
+
+        g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+        entry = g_strdup_printf ("%s=%s", variable, value);
+        g_variant_builder_add (&builder, "s", entry);
+        g_free (entry);
+
+        reply = g_dbus_connection_call_sync (connection,
+                                             "org.freedesktop.systemd1",
+                                             "/org/freedesktop/systemd1",
+                                             "org.freedesktop.systemd1.Manager",
+                                             "SetEnvironment",
+                                             g_variant_new ("(@as)",
+                                                            g_variant_builder_end (&builder)),
+                                             NULL,
+                                             G_DBUS_CALL_FLAGS_NONE,
+                                             -1, NULL, &bus_error);
+
+        if (bus_error != NULL) {
+                g_propagate_error (error, bus_error);
+        } else {
+                environment_updated = TRUE;
+                g_variant_unref (reply);
+        }
+
+        g_clear_object (&connection);
+
+        return environment_updated;
+}
+#endif
+
 void
 gsm_util_setenv (const char *variable,
                  const char *value)
 {
-        GError *bus_error;
+        GError *error = NULL;
 
         if (!value)
                 g_unsetenv (variable);
         else
                 g_setenv (variable, value, TRUE);
 
-        bus_error = NULL;
-
         /* If this fails it isn't fatal, it means some things like session
          * management and keyring won't work in activated clients.
          */
-        if (!gsm_util_update_activation_environment (variable, value, &bus_error)) {
-                g_warning ("Could not make bus activated clients aware of %s=%s environment variable: %s", 
variable, value, bus_error->message);
-                g_error_free (bus_error);
+        if (!gsm_util_update_activation_environment (variable, value, &error)) {
+                g_warning ("Could not make bus activated clients aware of %s=%s environment variable: %s", 
variable, value, error->message);
+                g_clear_error (&error);
+        }
+
+#ifdef HAVE_SYSTEMD
+        /* If this fails, the system user session won't get the updated environment
+         */
+        if (!gsm_util_update_user_environment (variable, value, &error)) {
+                g_debug ("Could not make systemd aware of %s=%s environment variable: %s", variable, value, 
error->message);
+                g_clear_error (&error);
         }
+#endif
 }
diff --git a/gnome-session/gsm-util.h b/gnome-session/gsm-util.h
index 2ce9f9d..a76e636 100644
--- a/gnome-session/gsm-util.h
+++ b/gnome-session/gsm-util.h
@@ -49,6 +49,9 @@ char *      gsm_util_generate_startup_id            (void);
 
 void        gsm_util_setenv                         (const char *variable,
                                                      const char *value);
+#ifdef HAVE_SYSTEMD
+gboolean    gsm_util_export_user_environment        (GError     **error);
+#endif
 
 void        gsm_quit                                (void);
 
diff --git a/gnome-session/main.c b/gnome-session/main.c
index e68b6f4..dd1e691 100644
--- a/gnome-session/main.c
+++ b/gnome-session/main.c
@@ -333,6 +333,10 @@ main (int argc, char **argv)
                 exit (1);
         }
 
+#ifdef HAVE_SYSTEMD
+        gsm_util_export_user_environment (NULL);
+#endif
+
         /* From 3.14 GDM sets XDG_CURRENT_DESKTOP. For compatibility with
          * older versions of GDM,  other display managers, and startx,
          * set a fallback value if we don't find it set.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]