[glib/wip/subprocess-2013: 3/6] gspawn: support creating pipes with O_CLOEXEC



commit 757642f9cff3d4a2055778d6a4cfead75acdeba7
Author: Ryan Lortie <desrt desrt ca>
Date:   Sat Nov 10 13:16:29 2012 -0500

    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 |    3 ++-
 2 files changed, 13 insertions(+), 27 deletions(-)
---
diff --git a/glib/gspawn.c b/glib/gspawn.c
index 3545a78..718cc62 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,
@@ -312,6 +311,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,
@@ -679,6 +679,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,
@@ -1311,6 +1312,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,
@@ -1325,21 +1327,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 ();
@@ -1623,24 +1626,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 24bd521..7358eca 100644
--- a/glib/gspawn.h
+++ b/glib/gspawn.h
@@ -180,7 +180,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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]