[gnome-session] gsm-util: export environment to systemd



commit 0af8ef83205fcb4ee52a9f66121d20177b050f65
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.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=736660

 gnome-session/gsm-util.c |  132 +++++++++++++++++++++++++++++++++++++++++++--
 gnome-session/gsm-util.h |    3 +
 gnome-session/main.c     |    4 ++
 3 files changed, 133 insertions(+), 6 deletions(-)
---
diff --git a/gnome-session/gsm-util.c b/gnome-session/gsm-util.c
index 292fa65..4772c6e 100644
--- a/gnome-session/gsm-util.c
+++ b/gnome-session/gsm-util.c
@@ -570,11 +570,124 @@ gsm_util_export_activation_environment (GError     **error)
         return environment_updated;
 }
 
+#ifdef HAVE_SYSTEMD
+gboolean
+gsm_util_export_user_environment (GError     **error)
+{
+
+        GDBusConnection *connection;
+        gboolean         environment_updated = FALSE;
+        char           **entries;
+        int              i = 0;
+        GVariantBuilder  builder;
+        GRegex          *regex;
+        GVariant        *reply;
+        GError          *bus_error = NULL;
+
+        connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
+
+        if (connection == NULL) {
+                return FALSE;
+        }
+
+        regex = g_regex_new ("^[a-zA-Z_][a-zA-Z0-9_]*=([[:blank:]]|[^[:cntrl:]])*$", G_REGEX_OPTIMIZE, 0, 
error);
+
+        if (regex == NULL) {
+                return FALSE;
+        }
+
+        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))
+                    continue;
+
+                if (!g_regex_match (regex, entry, 0, NULL))
+                    continue;
+
+                g_variant_builder_add (&builder, "s", entry);
+        }
+        g_regex_unref (regex);
+
+        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 (child_environment == NULL)
                 child_environment = g_listenv ();
@@ -584,15 +697,22 @@ gsm_util_setenv (const char *variable,
         else
                 child_environment = g_environ_setenv (child_environment, 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
 }
 
 const char * const *
diff --git a/gnome-session/gsm-util.h b/gnome-session/gsm-util.h
index b195d0b..763cae4 100644
--- a/gnome-session/gsm-util.h
+++ b/gnome-session/gsm-util.h
@@ -52,6 +52,9 @@ void        gsm_util_setenv                         (const char *variable,
 const char * const * gsm_util_listenv               (void);
 
 gboolean    gsm_util_export_activation_environment  (GError     **error);
+#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 29de33a..dce8bd0 100644
--- a/gnome-session/main.c
+++ b/gnome-session/main.c
@@ -379,6 +379,10 @@ main (int argc, char **argv)
 
         gsm_util_export_activation_environment (NULL);
 
+#ifdef HAVE_SYSTEMD
+        gsm_util_export_user_environment (NULL);
+#endif
+
         {
                 gchar *ibus_path;
 


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