summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2015-09-16 13:48:24 -0400
committerRay Strode <rstrode@redhat.com>2015-09-16 14:18:25 -0400
commit415230016aa7e038a48994b5c0248de7569af23f (patch)
treea47acfb1f7daaa93527a5f52e531e0f37e82d957
parente9310040c25d7e8eb4dc43b7fc7dcff71dbc7cab (diff)
downloadgnome-session-wip/halfline/env-to-systemd.tar.gz
gsm-util: export environment to systemdwip/halfline/env-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.
-rw-r--r--gnome-session/gsm-util.c124
-rw-r--r--gnome-session/gsm-util.h3
-rw-r--r--gnome-session/main.c4
3 files changed, 125 insertions, 6 deletions
diff --git a/gnome-session/gsm-util.c b/gnome-session/gsm-util.c
index b7d2cdab..ce8ac8c9 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 2ce9f9d9..a76e636f 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 e68b6f4b..dd1e6915 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.