[gnome-session] main: don't use g_setenv after start up



commit 759b2b597196574444f85e99b16331bd0acb1510
Author: Ray Strode <rstrode redhat com>
Date:   Mon Mar 7 15:41:10 2016 -0500

    main: don't use g_setenv after start up
    
    It's not threadsafe and gettext makes us crash, so maintain child
    environment separate from process environment.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=754951

 gnome-session/gsm-autostart-app.c |   19 +++++++++++++++++--
 gnome-session/gsm-fail-whale.c    |    3 ++-
 gnome-session/gsm-session-save.c  |    4 +++-
 gnome-session/gsm-util.c          |   27 ++++++++++++++++-----------
 gnome-session/gsm-util.h          |    1 +
 5 files changed, 39 insertions(+), 15 deletions(-)
---
diff --git a/gnome-session/gsm-autostart-app.c b/gnome-session/gsm-autostart-app.c
index 4283cdc..5b74bd4 100644
--- a/gnome-session/gsm-autostart-app.c
+++ b/gnome-session/gsm-autostart-app.c
@@ -1056,6 +1056,8 @@ autostart_app_start_spawn (GsmAutostartApp *app,
         gboolean         success;
         GError          *local_error;
         const char      *startup_id;
+        const char * const *child_environment;
+        int i;
         GAppLaunchContext *ctx;
         GSpawnChildSetupFunc child_setup_func = NULL;
         gpointer             child_setup_data = NULL;
@@ -1070,8 +1072,21 @@ autostart_app_start_spawn (GsmAutostartApp *app,
         local_error = NULL;
         ctx = g_app_launch_context_new ();
 
-        if (g_getenv ("DISPLAY") != NULL) {
-                g_app_launch_context_setenv (ctx, "DISPLAY", g_getenv ("DISPLAY"));
+        child_environment = gsm_util_listenv ();
+        while (child_environment[i] != NULL) {
+                char **environment_tuple;
+                const char *key;
+                const char *value;
+
+                environment_tuple = g_strsplit (child_environment[i], "=", 2);
+                key = environment_tuple[0];
+                value = environment_tuple[1];
+
+                if (value != NULL)
+                        g_app_launch_context_setenv (ctx, key, value);
+
+                g_strfreev (environment_tuple);
+                i++;
         }
 
         if (startup_id != NULL) {
diff --git a/gnome-session/gsm-fail-whale.c b/gnome-session/gsm-fail-whale.c
index 1322f67..7b9a0a5 100644
--- a/gnome-session/gsm-fail-whale.c
+++ b/gnome-session/gsm-fail-whale.c
@@ -25,6 +25,7 @@
 #include <glib/gstdio.h>
 
 #include "gsm-fail-whale.h"
+#include "gsm-util.h"
 
 static void
 on_fail_whale_failed (void)
@@ -51,7 +52,7 @@ gsm_fail_whale_dialog_we_failed  (gboolean            debug_mode,
                 argv[i++] = "--extensions";
         argv[i++] = NULL;
 
-        if (!g_spawn_async (NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL)) {
+        if (!g_spawn_async (NULL, argv, (char **) gsm_util_listenv (), G_SPAWN_DO_NOT_REAP_CHILD, NULL, 
NULL, &pid, NULL)) {
                 exit (1);
         }
 
diff --git a/gnome-session/gsm-session-save.c b/gnome-session/gsm-session-save.c
index 4a2735f..d6000e0 100644
--- a/gnome-session/gsm-session-save.c
+++ b/gnome-session/gsm-session-save.c
@@ -177,9 +177,11 @@ gsm_session_clear_one_client (const char *filename,
         gboolean  result = TRUE;
         GKeyFile *key_file;
         char     *discard_exec = NULL;
+        char    **envp;
 
         g_debug ("GsmSessionSave: removing '%s' from saved session", filename);
 
+        envp = (char **) gsm_util_listenv ();
         key_file = g_key_file_new ();
         if (g_key_file_load_from_file (key_file, filename,
                                        G_KEY_FILE_NONE, NULL)) {
@@ -199,7 +201,7 @@ gsm_session_clear_one_client (const char *filename,
                 if (!g_shell_parse_argv (discard_exec, &argc, &argv, NULL))
                         goto out;
 
-                result = g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
+                result = g_spawn_async (NULL, argv, envp, G_SPAWN_SEARCH_PATH,
                                         NULL, NULL, NULL, NULL) && result;
 
                 g_strfreev (argv);
diff --git a/gnome-session/gsm-util.c b/gnome-session/gsm-util.c
index e7ceec4..5fa2130 100644
--- a/gnome-session/gsm-util.c
+++ b/gnome-session/gsm-util.c
@@ -33,6 +33,7 @@
 #include "gsm-util.h"
 
 static gchar *_saved_session_dir = NULL;
+static gchar **child_environment;
 
 char *
 gsm_util_find_desktop_file_for_app_name (const char *name,
@@ -381,7 +382,7 @@ gsm_util_init_error (gboolean    fatal,
         argv[11] = _("_Log out");
         argv[12] = NULL;
 
-        g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
+        g_spawn_sync (NULL, argv, child_environment, 0, NULL, NULL, NULL, NULL, NULL, NULL);
 
         g_free (msg);
 
@@ -497,16 +498,13 @@ gsm_util_setenv (const char *variable,
 {
         GError *bus_error;
 
-        /* Note: we're intentionally comparing pointers here:
-           The goal is to avoid an un-threadsafe env variable update
-           when this API is used in maybe_push_env_var() in main.c
-        */
-        if (g_getenv (variable) != value) {
-                if (!value)
-                        g_unsetenv (variable);
-                else
-                        g_setenv (variable, value, TRUE);
-        }
+        if (child_environment)
+                child_environment = g_listenv ();
+
+        if (!value)
+                child_environment = g_environ_unsetenv (child_environment, variable);
+        else
+                child_environment = g_environ_setenv (child_environment, variable, value, TRUE);
 
         bus_error = NULL;
 
@@ -518,3 +516,10 @@ gsm_util_setenv (const char *variable,
                 g_error_free (bus_error);
         }
 }
+
+const char * const *
+gsm_util_listenv (void)
+{
+        return (const char * const *) child_environment;
+
+}
diff --git a/gnome-session/gsm-util.h b/gnome-session/gsm-util.h
index 2ce9f9d..6b5e98a 100644
--- a/gnome-session/gsm-util.h
+++ b/gnome-session/gsm-util.h
@@ -49,6 +49,7 @@ char *      gsm_util_generate_startup_id            (void);
 
 void        gsm_util_setenv                         (const char *variable,
                                                      const char *value);
+const char * const * gsm_util_listenv               (void);
 
 void        gsm_quit                                (void);
 


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