Commit e1e73daf authored by Philip Withnall's avatar Philip Withnall

gsubprocess: Copy parent process’ environ when clearing subprocess’

Previously, this was done at the time of spawning the subprocess, which
meant the g_subprocess_launcher_*_environ() functions could not be used
to modify the parent process’ environment.

Change the code to copy the parent process’ environment when
g_subprocess_launcher_set_environ(NULL) is called. Document the change
and add a unit test.

https://bugzilla.gnome.org/show_bug.cgi?id=778422
parent c7d32573
......@@ -240,8 +240,12 @@ g_subprocess_launcher_new (GSubprocessFlags flags)
* As an alternative, you can use g_subprocess_launcher_setenv(),
* g_subprocess_launcher_unsetenv(), etc.
*
* Pass %NULL to inherit the parent process' environment. Pass an
* empty array to set an empty environment.
* Pass an empty array to set an empty environment. Pass %NULL to inherit the
* parent process’ environment. As of GLib 2.54, the parent process’ environment
* will be copied when g_subprocess_launcher_set_environ() is called.
* Previously, it was copied when the subprocess was executed. This means the
* copied environment may now be modified (using g_subprocess_launcher_setenv(),
* etc.) before launching the subprocess.
*
* On UNIX, all strings in this array can be arbitrary byte strings.
* On Windows, they should be in UTF-8.
......@@ -254,6 +258,9 @@ g_subprocess_launcher_set_environ (GSubprocessLauncher *self,
{
g_strfreev (self->envp);
self->envp = g_strdupv (env);
if (self->envp == NULL)
self->envp = g_get_environ ();
}
/**
......
......@@ -948,6 +948,51 @@ test_env (void)
g_object_unref (proc);
}
/* Test that explicitly inheriting and modifying the parent process’
* environment works. */
static void
test_env_inherit (void)
{
GError *local_error = NULL;
GError **error = &local_error;
GSubprocessLauncher *launcher;
GSubprocess *proc;
GPtrArray *args;
GInputStream *stdout;
gchar *result;
gchar **split;
g_setenv ("TEST_ENV_INHERIT1", "1", TRUE);
g_setenv ("TEST_ENV_INHERIT2", "2", TRUE);
args = get_test_subprocess_args ("env", NULL);
launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE);
g_subprocess_launcher_set_environ (launcher, NULL);
g_subprocess_launcher_setenv (launcher, "TWO", "2", TRUE);
g_subprocess_launcher_unsetenv (launcher, "TEST_ENV_INHERIT1");
g_assert_null (g_subprocess_launcher_getenv (launcher, "TEST_ENV_INHERIT1"));
g_assert_cmpstr (g_subprocess_launcher_getenv (launcher, "TEST_ENV_INHERIT2"), ==, "2");
g_assert_cmpstr (g_subprocess_launcher_getenv (launcher, "TWO"), ==, "2");
proc = g_subprocess_launcher_spawn (launcher, error, args->pdata[0], "env", NULL);
g_ptr_array_free (args, TRUE);
g_assert_no_error (local_error);
stdout = g_subprocess_get_stdout_pipe (proc);
result = splice_to_string (stdout, error);
split = g_strsplit (result, "\n", -1);
g_assert_null (g_environ_getenv (split, "TEST_ENV_INHERIT1"));
g_assert_cmpstr (g_environ_getenv (split, "TEST_ENV_INHERIT2"), ==, "2");
g_assert_cmpstr (g_environ_getenv (split, "TWO"), ==, "2");
g_strfreev (split);
g_free (result);
g_object_unref (proc);
}
static void
test_cwd (void)
{
......@@ -1265,6 +1310,7 @@ main (int argc, char **argv)
g_test_add_func ("/gsubprocess/communicate-nothing", test_communicate_nothing);
g_test_add_func ("/gsubprocess/terminate", test_terminate);
g_test_add_func ("/gsubprocess/env", test_env);
g_test_add_func ("/gsubprocess/env/inherit", test_env_inherit);
g_test_add_func ("/gsubprocess/cwd", test_cwd);
#ifdef G_OS_UNIX
g_test_add_func ("/gsubprocess/stdout-file", test_stdout_file);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment