diff options
author | Philip Withnall <pwithnall@endlessos.org> | 2021-02-15 13:34:26 +0000 |
---|---|---|
committer | Philip Withnall <pwithnall@endlessos.org> | 2021-02-16 13:44:00 +0000 |
commit | a34b6741342daa7575cd80c9dfc181e9b28b8c49 (patch) | |
tree | a82ef2ada3668bfb6fac2056cea3dd73cc5c5eb6 | |
parent | ba403908a22a490872ee3ee293cc99b40c4535c5 (diff) | |
download | glib-a34b6741342daa7575cd80c9dfc181e9b28b8c49.tar.gz |
gspawn-win32: Refactor internal spawn functions
This should introduce no functional changes, but condenses the variants
of the internal spawn implementation down to be more like `gspawn.c`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2097
-rw-r--r-- | glib/gspawn-win32.c | 233 |
1 files changed, 114 insertions, 119 deletions
diff --git a/glib/gspawn-win32.c b/glib/gspawn-win32.c index 9e4d496cc..f56a07ec7 100644 --- a/glib/gspawn-win32.c +++ b/glib/gspawn-win32.c @@ -531,19 +531,23 @@ do_spawn_directly (gint *exit_status, } static gboolean -do_spawn_with_fds (gint *exit_status, - gboolean do_return_handle, - const gchar *working_directory, - gchar **argv, - char **envp, - GSpawnFlags flags, - GSpawnChildSetupFunc child_setup, - GPid *child_pid, - gint stdin_fd, - gint stdout_fd, - gint stderr_fd, - gint *err_report, - GError **error) +fork_exec (gint *exit_status, + gboolean do_return_handle, + const gchar *working_directory, + const gchar * const *argv, + const gchar * const *envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + gint *stdin_pipe_out, + gint *stdout_pipe_out, + gint *stderr_pipe_out, + gint stdin_fd, + gint stdout_fd, + gint stderr_fd, + gint *err_report, + GError **error) { char **protected_argv; char args[ARG_COUNT][10]; @@ -561,6 +565,13 @@ do_spawn_with_fds (gint *exit_status, gchar *helper_process; wchar_t *whelper, **wargv, **wenvp; gchar *glib_dll_directory; + int stdin_pipe[2] = { -1, -1 }; + int stdout_pipe[2] = { -1, -1 }; + int stderr_pipe[2] = { -1, -1 }; + + g_assert (stdin_pipe_out == NULL || stdin_fd < 0); + g_assert (stdout_pipe_out == NULL || stdout_fd < 0); + g_assert (stderr_pipe_out == NULL || stderr_fd < 0); if (child_setup && !warned_about_child_setup) { @@ -568,6 +579,27 @@ do_spawn_with_fds (gint *exit_status, g_warning ("passing a child setup function to the g_spawn functions is pointless on Windows and it is ignored"); } + if (stdin_pipe_out != NULL) + { + if (!make_pipe (stdin_pipe, error)) + goto cleanup_and_fail; + stdin_fd = stdin_pipe[0]; + } + + if (stdout_pipe_out != NULL) + { + if (!make_pipe (stdout_pipe, error)) + goto cleanup_and_fail; + stdout_fd = stdout_pipe[1]; + } + + if (stderr_pipe_out != NULL) + { + if (!make_pipe (stderr_pipe, error)) + goto cleanup_and_fail; + stderr_fd = stderr_pipe[1]; + } + argc = protect_argv (argv, &protected_argv); if (stdin_fd == -1 && stdout_fd == -1 && stderr_fd == -1 && @@ -840,7 +872,21 @@ do_spawn_with_fds (gint *exit_status, if (rc != -1) CloseHandle ((HANDLE) rc); - + + /* Close the other process's ends of the pipes in this process, + * otherwise the reader will never get EOF. + */ + close_and_invalidate (&stdin_pipe[0]); + close_and_invalidate (&stdout_pipe[1]); + close_and_invalidate (&stderr_pipe[1]); + + if (stdin_pipe_out != NULL) + *stdin_pipe_out = stdin_pipe[1]; + if (stdout_pipe_out != NULL) + *stdout_pipe_out = stdout_pipe[0]; + if (stderr_pipe_out != NULL) + *stderr_pipe_out = stderr_pipe[0]; + return TRUE; cleanup_and_fail: @@ -856,70 +902,6 @@ do_spawn_with_fds (gint *exit_status, if (helper_sync_pipe[1] != -1) close (helper_sync_pipe[1]); - return FALSE; -} - -static gboolean -do_spawn_with_pipes (gint *exit_status, - gboolean do_return_handle, - const gchar *working_directory, - gchar **argv, - char **envp, - GSpawnFlags flags, - GSpawnChildSetupFunc child_setup, - GPid *child_pid, - gint *standard_input, - gint *standard_output, - gint *standard_error, - gint *err_report, - GError **error) -{ - int stdin_pipe[2] = { -1, -1 }; - int stdout_pipe[2] = { -1, -1 }; - int stderr_pipe[2] = { -1, -1 }; - - if (standard_input && !make_pipe (stdin_pipe, error)) - goto cleanup_and_fail; - - if (standard_output && !make_pipe (stdout_pipe, error)) - goto cleanup_and_fail; - - if (standard_error && !make_pipe (stderr_pipe, error)) - goto cleanup_and_fail; - - if (!do_spawn_with_fds (exit_status, - do_return_handle, - working_directory, - argv, - envp, - flags, - child_setup, - child_pid, - stdin_pipe[0], - stdout_pipe[1], - stderr_pipe[1], - err_report, - error)) - goto cleanup_and_fail; - - /* Close the other process's ends of the pipes in this process, - * otherwise the reader will never get EOF. - */ - close_and_invalidate (&stdin_pipe[0]); - close_and_invalidate (&stdout_pipe[1]); - close_and_invalidate (&stderr_pipe[1]); - - if (standard_input) - *standard_input = stdin_pipe[1]; - if (standard_output) - *standard_output = stdout_pipe[0]; - if (standard_error) - *standard_error = stderr_pipe[0]; - - return TRUE; - - cleanup_and_fail: - if (stdin_pipe[0] != -1) close (stdin_pipe[0]); if (stdin_pipe[1] != -1) @@ -979,20 +961,24 @@ g_spawn_sync (const gchar *working_directory, if (standard_error) *standard_error = NULL; - - if (!do_spawn_with_pipes (&status, - FALSE, - working_directory, - argv, - envp, - flags, - child_setup, - NULL, - NULL, - standard_output ? &outpipe : NULL, - standard_error ? &errpipe : NULL, - &reportpipe, - error)) + + if (!fork_exec (&status, + FALSE, + working_directory, + (const gchar * const *) argv, + (const gchar * const *) envp, + flags, + child_setup, + user_data, + NULL, + NULL, + standard_output ? &outpipe : NULL, + standard_error ? &errpipe : NULL, + -1, + -1, + -1, + &reportpipe, + error)) return FALSE; /* Read data from child. */ @@ -1199,20 +1185,24 @@ g_spawn_async_with_pipes (const gchar *working_directory, /* can't inherit stdin if we have an input pipe. */ g_return_val_if_fail (standard_input == NULL || !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE); - - return do_spawn_with_pipes (NULL, - (flags & G_SPAWN_DO_NOT_REAP_CHILD), - working_directory, - argv, - envp, - flags, - child_setup, - child_pid, - standard_input, - standard_output, - standard_error, - NULL, - error); + + return fork_exec (NULL, + (flags & G_SPAWN_DO_NOT_REAP_CHILD), + working_directory, + (const gchar * const *) argv, + (const gchar * const *) envp, + flags, + child_setup, + user_data, + child_pid, + standard_input, + standard_output, + standard_error, + -1, + -1, + -1, + NULL, + error); } gboolean @@ -1237,19 +1227,24 @@ g_spawn_async_with_fds (const gchar *working_directory, g_return_val_if_fail (stdin_fd == -1 || !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE); - return do_spawn_with_fds (NULL, - (flags & G_SPAWN_DO_NOT_REAP_CHILD), - working_directory, - argv, - envp, - flags, - child_setup, - child_pid, - stdin_fd, - stdout_fd, - stderr_fd, - NULL, - error); + return fork_exec (NULL, + (flags & G_SPAWN_DO_NOT_REAP_CHILD), + working_directory, + (const gchar * const *) argv, + (const gchar * const *) envp, + flags, + child_setup, + user_data, + child_pid, + NULL, + NULL, + NULL, + stdin_fd, + stdout_fd, + stderr_fd, + NULL, + error); + } gboolean |