[Spice-devel] [PATCH spice-xpi 1/2] xpi: use safer g_environ_setenv()

Marc-André Lureau marcandre.lureau at gmail.com
Mon Jan 28 10:03:56 PST 2013


Quoting GLib:

Environment variable handling in UNIX is not thread-safe, and your
program may crash if one thread calls g_setenv() while another thread
is calling getenv(). (And note that many functions, such as gettext(),
call getenv() internally.) This function is only safe to use at the
very start of your program, before creating any other threads (or
creating objects that create worker threads of their own).

If you need to set up the environment for a child process, you can use
g_get_environ() to get an environment array, modify that with
g_environ_setenv() and g_environ_unsetenv(), and then pass that array
directly to execvpe(), g_spawn_async(), or the like.
---
 SpiceXPI/src/plugin/plugin.cpp | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/SpiceXPI/src/plugin/plugin.cpp b/SpiceXPI/src/plugin/plugin.cpp
index cb4bc8e..8233885 100644
--- a/SpiceXPI/src/plugin/plugin.cpp
+++ b/SpiceXPI/src/plugin/plugin.cpp
@@ -608,11 +608,6 @@ void nsPluginInstance::Connect()
 
     std::string socket_file(m_tmp_dir);
     socket_file += "/spice-xpi";
-    if (setenv("SPICE_XPI_SOCKET", socket_file.c_str(), 1))
-    {
-        g_critical("could not set SPICE_XPI_SOCKET env variable");
-        return;
-    }
 
     /* use a pipe for the children to wait until it gets tracked */
     int pipe_fds[2] = { -1, -1 };
@@ -636,13 +631,21 @@ void nsPluginInstance::Connect()
         close(pipe_fds[0]);
         pipe_fds[0] = -1;
 
-        execl("/usr/libexec/spice-xpi-client", "/usr/libexec/spice-xpi-client", NULL);
+        gchar **env = g_get_environ();
+        env = g_environ_setenv(env, "SPICE_XPI_SOCKET", socket_file.c_str(), TRUE);
+
+        execle("/usr/libexec/spice-xpi-client",
+               "/usr/libexec/spice-xpi-client", NULL,
+               env);
         g_message("failed to run spice-xpi-client, running spicec instead");
 
         // TODO: temporary fallback for backward compatibility
-        execl("/usr/bin/spicec", "/usr/bin/spicec", "--controller", NULL);
-        g_critical("ERROR failed to run spicec fallback");
+        execle("/usr/bin/spicec",
+               "/usr/bin/spicec", "--controller", NULL,
+               env);
 
+        g_critical("ERROR failed to run spicec fallback");
+        g_strfreev(env);
         exit(EXIT_FAILURE);
     }
     else
-- 
1.8.1.rc1.17.g75ed918



More information about the Spice-devel mailing list