From 8f84934b86f04eebb9d7aebf32321925e1764958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sun, 7 May 2017 12:48:32 +0200 Subject: systemd user-session needs to be updated to get all user-defined enviroment when the session starts. 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. See: https://bugzilla.gnome.org/show_bug.cgi?id=736660 --- mate-session/gsm-util.c | 131 +++++++++++++++++++++++++++++++++++++++++++++--- mate-session/gsm-util.h | 4 ++ mate-session/main.c | 4 ++ 3 files changed, 133 insertions(+), 6 deletions(-) (limited to 'mate-session') diff --git a/mate-session/gsm-util.c b/mate-session/gsm-util.c index b026f12..92e813b 100644 --- a/mate-session/gsm-util.c +++ b/mate-session/gsm-util.c @@ -551,21 +551,140 @@ 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; 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/mate-session/gsm-util.h b/mate-session/gsm-util.h index 112ce6f..2c406af 100644 --- a/mate-session/gsm-util.h +++ b/mate-session/gsm-util.h @@ -50,6 +50,10 @@ char * gsm_util_generate_startup_id (void); gboolean gsm_util_export_activation_environment (GError **error); +#ifdef HAVE_SYSTEMD +gboolean gsm_util_export_user_environment (GError **error); +#endif + void gsm_util_setenv (const char *variable, const char *value); diff --git a/mate-session/main.c b/mate-session/main.c index da931af..161772d 100644 --- a/mate-session/main.c +++ b/mate-session/main.c @@ -622,6 +622,10 @@ int main(int argc, char** argv) gsm_util_export_activation_environment (NULL); +#ifdef HAVE_SYSTEMD + gsm_util_export_user_environment (NULL); +#endif + mdm_log_init(); /* Allows to enable/disable debug from GSettings only if it is not set from argument */ -- cgit v1.2.1