diff options
author | Dan Winship <danw@gnome.org> | 2011-10-15 15:52:28 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2011-10-15 15:54:45 -0400 |
commit | 409d93148f2d95c2966f75fe0901edd1e06c99a9 (patch) | |
tree | 2d96297c3bb9d21f0da809870b28883ca5b0abaa /glib/gspawn.h | |
parent | 5ff803d91f252bfeb4a9cfaf2f94ecdea6e6a687 (diff) | |
download | glib-409d93148f2d95c2966f75fe0901edd1e06c99a9.tar.gz |
gutils: Add functions for working with environment arrays
When spawning a child process, it is not safe to call setenv() before
the fork() (because setenv() isn't thread-safe), but it's also not
safe to call it after the fork() (because it's not async-signal-safe).
So the only safe way to alter the environment for a child process from
a threaded program is to pass a fully-formed envp array to
exec*/g_spawn*/etc.
So, add g_environ_getenv(), g_environ_setenv(), and
g_environ_unsetenv(), which act like their namesakes, but work on
arbitrary arrays rather than working directly on the environment.
http://bugzilla.gnome.org/show_bug.cgi?id=659326
Diffstat (limited to 'glib/gspawn.h')
-rw-r--r-- | glib/gspawn.h | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/glib/gspawn.h b/glib/gspawn.h index 84e0eeb31..ace73d15c 100644 --- a/glib/gspawn.h +++ b/glib/gspawn.h @@ -97,24 +97,36 @@ typedef enum * @user_data: user data to pass to the function. * * Specifies the type of the setup function passed to g_spawn_async(), - * g_spawn_sync() and g_spawn_async_with_pipes(). On POSIX platforms it - * is called in the child after GLib has performed all the setup it plans - * to perform but before calling exec(). On POSIX actions taken in this - * function will thus only affect the child, not the parent. + * g_spawn_sync() and g_spawn_async_with_pipes(), which can, in very + * limited ways, be used to affect the child's execution. * - * Note that POSIX allows only async-signal-safe functions (see signal(7)) - * to be called in the child between fork() and exec(), which drastically - * limits the usefulness of child setup functions. + * On POSIX platforms, the function is called in the child after GLib + * has performed all the setup it plans to perform, but before calling + * exec(). Actions taken in this function will only affect the child, + * not the parent. * - * Also note that modifying the environment from the child setup function - * may not have the intended effect, since it will get overridden by - * a non-%NULL @env argument to the <literal>g_spawn...</literal> functions. - * - * On Windows the function is called in the parent. Its usefulness on + * On Windows, the function is called in the parent. Its usefulness on * Windows is thus questionable. In many cases executing the child setup * function in the parent can have ill effects, and you should be very * careful when porting software to Windows that uses child setup * functions. + * + * However, even on POSIX, you are extremely limited in what you can + * safely do from a #GSpawnChildSetupFunc, because any mutexes that + * were held by other threads in the parent process at the time of the + * fork() will still be locked in the child process, and they will + * never be unlocked (since the threads that held them don't exist in + * the child). POSIX allows only async-signal-safe functions (see + * <citerefentry><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>) + * to be called in the child between fork() and exec(), which + * drastically limits the usefulness of child setup functions. + * + * In particular, it is not safe to call any function which may + * call malloc(), which includes POSIX functions such as setenv(). + * If you need to set up the child environment differently from + * the parent, you should use g_get_environ(), g_environ_setenv(), + * and g_environ_unsetev(), and then pass the complete environment + * list to the <literal>g_spawn...</literal> function. */ typedef void (* GSpawnChildSetupFunc) (gpointer user_data); |