mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-31 12:53:07 +02:00
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). https://bugzilla.gnome.org/show_bug.cgi?id=672102
This commit is contained in:
parent
292de8cc52
commit
2054ccad95
@ -53,7 +53,7 @@
|
|||||||
#include "gtestutils.h"
|
#include "gtestutils.h"
|
||||||
#include "gutils.h"
|
#include "gutils.h"
|
||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
|
#include "glib-unix.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:spawn
|
* SECTION:spawn
|
||||||
@ -69,8 +69,6 @@ static gint g_execute (const gchar *file,
|
|||||||
gboolean search_path,
|
gboolean search_path,
|
||||||
gboolean search_path_from_envp);
|
gboolean search_path_from_envp);
|
||||||
|
|
||||||
static gboolean make_pipe (gint p[2],
|
|
||||||
GError **error);
|
|
||||||
static gboolean fork_exec_with_pipes (gboolean intermediate_child,
|
static gboolean fork_exec_with_pipes (gboolean intermediate_child,
|
||||||
const gchar *working_directory,
|
const gchar *working_directory,
|
||||||
gchar **argv,
|
gchar **argv,
|
||||||
@ -82,6 +80,7 @@ static gboolean fork_exec_with_pipes (gboolean intermediate_child,
|
|||||||
gboolean stderr_to_null,
|
gboolean stderr_to_null,
|
||||||
gboolean child_inherits_stdin,
|
gboolean child_inherits_stdin,
|
||||||
gboolean file_and_argv_zero,
|
gboolean file_and_argv_zero,
|
||||||
|
gboolean cloexec_pipes,
|
||||||
GSpawnChildSetupFunc child_setup,
|
GSpawnChildSetupFunc child_setup,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GPid *child_pid,
|
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_STDERR_TO_DEV_NULL) != 0,
|
||||||
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
||||||
(flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
|
(flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
|
||||||
|
(flags & G_SPAWN_CLOEXEC_PIPES) != 0,
|
||||||
child_setup,
|
child_setup,
|
||||||
user_data,
|
user_data,
|
||||||
&pid,
|
&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_STDERR_TO_DEV_NULL) != 0,
|
||||||
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
(flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
|
||||||
(flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
|
(flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
|
||||||
|
(flags & G_SPAWN_CLOEXEC_PIPES) != 0,
|
||||||
child_setup,
|
child_setup,
|
||||||
user_data,
|
user_data,
|
||||||
child_pid,
|
child_pid,
|
||||||
@ -1311,6 +1312,7 @@ fork_exec_with_pipes (gboolean intermediate_child,
|
|||||||
gboolean stderr_to_null,
|
gboolean stderr_to_null,
|
||||||
gboolean child_inherits_stdin,
|
gboolean child_inherits_stdin,
|
||||||
gboolean file_and_argv_zero,
|
gboolean file_and_argv_zero,
|
||||||
|
gboolean cloexec_pipes,
|
||||||
GSpawnChildSetupFunc child_setup,
|
GSpawnChildSetupFunc child_setup,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GPid *child_pid,
|
GPid *child_pid,
|
||||||
@ -1325,21 +1327,22 @@ fork_exec_with_pipes (gboolean intermediate_child,
|
|||||||
gint stderr_pipe[2] = { -1, -1 };
|
gint stderr_pipe[2] = { -1, -1 };
|
||||||
gint child_err_report_pipe[2] = { -1, -1 };
|
gint child_err_report_pipe[2] = { -1, -1 };
|
||||||
gint child_pid_report_pipe[2] = { -1, -1 };
|
gint child_pid_report_pipe[2] = { -1, -1 };
|
||||||
|
guint pipe_flags = cloexec_pipes ? FD_CLOEXEC : 0;
|
||||||
gint status;
|
gint status;
|
||||||
|
|
||||||
if (!make_pipe (child_err_report_pipe, error))
|
if (!g_unix_open_pipe (child_err_report_pipe, pipe_flags, error))
|
||||||
return FALSE;
|
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;
|
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;
|
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;
|
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;
|
goto cleanup_and_fail;
|
||||||
|
|
||||||
pid = fork ();
|
pid = fork ();
|
||||||
@ -1623,24 +1626,6 @@ fork_exec_with_pipes (gboolean intermediate_child,
|
|||||||
return FALSE;
|
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 */
|
/* Based on execvp from GNU C Library */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -166,6 +166,8 @@ typedef void (* GSpawnChildSetupFunc) (gpointer user_data);
|
|||||||
* @G_SPAWN_SEARCH_PATH_FROM_ENVP: if <literal>argv[0]</literal> is not an abolute path,
|
* @G_SPAWN_SEARCH_PATH_FROM_ENVP: if <literal>argv[0]</literal> is not an abolute path,
|
||||||
* it will be looked for in the <envar>PATH</envar> from the passed child
|
* it will be looked for in the <envar>PATH</envar> from the passed child
|
||||||
* environment. Since: 2.34
|
* environment. Since: 2.34
|
||||||
|
* @G_SPAWN_CLOEXEC_PIPES: On UNIX, returned pipe file descriptors will have the
|
||||||
|
* close-on-exec flag set. Since: 2.36
|
||||||
*
|
*
|
||||||
* Flags passed to g_spawn_sync(), g_spawn_async() and g_spawn_async_with_pipes().
|
* Flags passed to g_spawn_sync(), g_spawn_async() and g_spawn_async_with_pipes().
|
||||||
*/
|
*/
|
||||||
@ -180,7 +182,8 @@ typedef enum
|
|||||||
G_SPAWN_STDERR_TO_DEV_NULL = 1 << 4,
|
G_SPAWN_STDERR_TO_DEV_NULL = 1 << 4,
|
||||||
G_SPAWN_CHILD_INHERITS_STDIN = 1 << 5,
|
G_SPAWN_CHILD_INHERITS_STDIN = 1 << 5,
|
||||||
G_SPAWN_FILE_AND_ARGV_ZERO = 1 << 6,
|
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;
|
} GSpawnFlags;
|
||||||
|
|
||||||
GQuark g_spawn_error_quark (void);
|
GQuark g_spawn_error_quark (void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user