summaryrefslogtreecommitdiff
path: root/glib/gspawn.h
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2011-10-15 15:52:28 -0400
committerMatthias Clasen <mclasen@redhat.com>2011-10-15 15:54:45 -0400
commit409d93148f2d95c2966f75fe0901edd1e06c99a9 (patch)
tree2d96297c3bb9d21f0da809870b28883ca5b0abaa /glib/gspawn.h
parent5ff803d91f252bfeb4a9cfaf2f94ecdea6e6a687 (diff)
downloadglib-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.h36
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);