From e30bbca6679605487e52e52f810c54a0464b6d37 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Sat, 10 Nov 2012 13:16:29 -0500 Subject: [PATCH] gspawn: support creating pipes with O_CLOEXEC Add a new flag, G_SPAWN_CLOEXEC_PIPES, for creating the stdin/out/err pipes with O_CLOEXEC (for the usual reasons). --- glib/gspawn.c | 37 +++++++++++-------------------------- glib/gspawn.h | 5 ++++- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/glib/gspawn.c b/glib/gspawn.c index 3db3c8d..0e6106c 100644 --- a/glib/gspawn.c +++ b/glib/gspawn.c @@ -53,7 +53,7 @@ #include "gtestutils.h" #include "gutils.h" #include "glibintl.h" - +#include "glib-unix.h" /** * SECTION:spawn @@ -69,8 +69,6 @@ static gint g_execute (const gchar *file, gboolean search_path, gboolean search_path_from_envp); -static gboolean make_pipe (gint p[2], - GError **error); static gboolean fork_exec_with_pipes (gboolean intermediate_child, const gchar *working_directory, gchar **argv, @@ -82,6 +80,7 @@ static gboolean fork_exec_with_pipes (gboolean intermediate_child, gboolean stderr_to_null, gboolean child_inherits_stdin, gboolean file_and_argv_zero, + gboolean cloexec_pipes, GSpawnChildSetupFunc child_setup, gpointer user_data, GPid *child_pid, @@ -289,6 +288,7 @@ g_spawn_sync (const gchar *working_directory, (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0, (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0, (flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0, + (flags & G_SPAWN_CLOEXEC_PIPES) != 0, child_setup, user_data, &pid, @@ -669,6 +669,7 @@ g_spawn_async_with_pipes (const gchar *working_directory, (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0, (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0, (flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0, + (flags & G_SPAWN_CLOEXEC_PIPES) != 0, child_setup, user_data, child_pid, @@ -1301,6 +1302,7 @@ fork_exec_with_pipes (gboolean intermediate_child, gboolean stderr_to_null, gboolean child_inherits_stdin, gboolean file_and_argv_zero, + gboolean cloexec_pipes, GSpawnChildSetupFunc child_setup, gpointer user_data, GPid *child_pid, @@ -1315,21 +1317,22 @@ fork_exec_with_pipes (gboolean intermediate_child, gint stderr_pipe[2] = { -1, -1 }; gint child_err_report_pipe[2] = { -1, -1 }; gint child_pid_report_pipe[2] = { -1, -1 }; + guint pipe_flags = cloexec_pipes ? FD_CLOEXEC : 0; gint status; - if (!make_pipe (child_err_report_pipe, error)) + if (!g_unix_open_pipe (child_err_report_pipe, pipe_flags, error)) return FALSE; - if (intermediate_child && !make_pipe (child_pid_report_pipe, error)) + if (intermediate_child && !g_unix_open_pipe (child_pid_report_pipe, pipe_flags, error)) goto cleanup_and_fail; - if (standard_input && !make_pipe (stdin_pipe, error)) + if (standard_input && !g_unix_open_pipe (stdin_pipe, pipe_flags, error)) goto cleanup_and_fail; - if (standard_output && !make_pipe (stdout_pipe, error)) + if (standard_output && !g_unix_open_pipe (stdout_pipe, pipe_flags, error)) goto cleanup_and_fail; - if (standard_error && !make_pipe (stderr_pipe, error)) + if (standard_error && !g_unix_open_pipe (stderr_pipe, FD_CLOEXEC, error)) goto cleanup_and_fail; pid = fork (); @@ -1614,24 +1617,6 @@ fork_exec_with_pipes (gboolean intermediate_child, return FALSE; } -static gboolean -make_pipe (gint p[2], - GError **error) -{ - if (pipe (p) < 0) - { - gint errsv = errno; - g_set_error (error, - G_SPAWN_ERROR, - G_SPAWN_ERROR_FAILED, - _("Failed to create pipe for communicating with child process (%s)"), - g_strerror (errsv)); - return FALSE; - } - else - return TRUE; -} - /* Based on execvp from GNU C Library */ static void diff --git a/glib/gspawn.h b/glib/gspawn.h index 5b5853a..7a993e9 100644 --- a/glib/gspawn.h +++ b/glib/gspawn.h @@ -167,6 +167,8 @@ typedef void (* GSpawnChildSetupFunc) (gpointer user_data); * @G_SPAWN_SEARCH_PATH_FROM_ENVP: if argv[0] is not an abolute path, * it will be looked for in the PATH from the passed child * environment. Since: 2.34 + * @G_SPAWN_CLOEXEC_PIPES: create all pipes with the O_CLOEXEC flag set. + * Since: 2.40. * * Flags passed to g_spawn_sync(), g_spawn_async() and g_spawn_async_with_pipes(). */ @@ -182,7 +184,8 @@ typedef enum G_SPAWN_STDERR_TO_DEV_NULL = 1 << 4, G_SPAWN_CHILD_INHERITS_STDIN = 1 << 5, G_SPAWN_FILE_AND_ARGV_ZERO = 1 << 6, - G_SPAWN_SEARCH_PATH_FROM_ENVP = 1 << 7 + G_SPAWN_SEARCH_PATH_FROM_ENVP = 1 << 7, + G_SPAWN_CLOEXEC_PIPES = 1 << 8 } GSpawnFlags; GLIB_AVAILABLE_IN_ALL -- 2.7.4