From e80b0c4e4b76b41ed19273453d51fada8455cb1a Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 31 May 2023 12:00:58 +0100 Subject: [PATCH] gspawn: Use GUnixPipe on Unix Signed-off-by: Simon McVittie --- glib/gspawn.c | 118 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/glib/gspawn.c b/glib/gspawn.c index 4d0f1e274..0a7bf0a71 100644 --- a/glib/gspawn.c +++ b/glib/gspawn.c @@ -2268,6 +2268,16 @@ out_free_spawnattr: } #endif /* POSIX_SPAWN_AVAILABLE */ +static gboolean +source_fds_collide_with_pipe (const GUnixPipe *pipefd, + const int *source_fds, + gsize n_fds, + GError **error) +{ + return (_g_spawn_invalid_source_fd (pipefd->fds[G_UNIX_PIPE_END_READ], source_fds, n_fds, error) || + _g_spawn_invalid_source_fd (pipefd->fds[G_UNIX_PIPE_END_WRITE], source_fds, n_fds, error)); +} + static gboolean fork_exec (gboolean intermediate_child, const gchar *working_directory, @@ -2296,8 +2306,8 @@ fork_exec (gboolean intermediate_child, GError **error) { GPid pid = -1; - gint child_err_report_pipe[2] = { -1, -1 }; - gint child_pid_report_pipe[2] = { -1, -1 }; + GUnixPipe child_err_report_pipe = G_UNIX_PIPE_INIT; + GUnixPipe child_pid_report_pipe = G_UNIX_PIPE_INIT; guint pipe_flags = cloexec_pipes ? FD_CLOEXEC : 0; gint status; const gchar *chosen_search_path; @@ -2307,9 +2317,9 @@ fork_exec (gboolean intermediate_child, gchar **argv_buffer = NULL; gchar **argv_buffer_heap = NULL; gsize argv_buffer_len = 0; - gint stdin_pipe[2] = { -1, -1 }; - gint stdout_pipe[2] = { -1, -1 }; - gint stderr_pipe[2] = { -1, -1 }; + GUnixPipe stdin_pipe = G_UNIX_PIPE_INIT; + GUnixPipe stdout_pipe = G_UNIX_PIPE_INIT; + GUnixPipe stderr_pipe = G_UNIX_PIPE_INIT; gint child_close_fds[4] = { -1, -1, -1, -1 }; gint n_child_close_fds = 0; gint *source_fds_copy = NULL; @@ -2322,35 +2332,32 @@ fork_exec (gboolean intermediate_child, /* If pipes have been requested, open them */ if (stdin_pipe_out != NULL) { - if (!g_unix_open_pipe (stdin_pipe, pipe_flags, error)) + if (!g_unix_pipe_open (&stdin_pipe, pipe_flags, error)) goto cleanup_and_fail; - if (_g_spawn_invalid_source_fd (stdin_pipe[0], source_fds, n_fds, error) || - _g_spawn_invalid_source_fd (stdin_pipe[1], source_fds, n_fds, error)) + if (source_fds_collide_with_pipe (&stdin_pipe, source_fds, n_fds, error)) goto cleanup_and_fail; - child_close_fds[n_child_close_fds++] = stdin_pipe[1]; - stdin_fd = stdin_pipe[0]; + child_close_fds[n_child_close_fds++] = g_unix_pipe_get (&stdin_pipe, G_UNIX_PIPE_END_WRITE); + stdin_fd = g_unix_pipe_get (&stdin_pipe, G_UNIX_PIPE_END_READ); } if (stdout_pipe_out != NULL) { - if (!g_unix_open_pipe (stdout_pipe, pipe_flags, error)) + if (!g_unix_pipe_open (&stdout_pipe, pipe_flags, error)) goto cleanup_and_fail; - if (_g_spawn_invalid_source_fd (stdout_pipe[0], source_fds, n_fds, error) || - _g_spawn_invalid_source_fd (stdout_pipe[1], source_fds, n_fds, error)) + if (source_fds_collide_with_pipe (&stdout_pipe, source_fds, n_fds, error)) goto cleanup_and_fail; - child_close_fds[n_child_close_fds++] = stdout_pipe[0]; - stdout_fd = stdout_pipe[1]; + child_close_fds[n_child_close_fds++] = g_unix_pipe_get (&stdout_pipe, G_UNIX_PIPE_END_READ); + stdout_fd = g_unix_pipe_get (&stdout_pipe, G_UNIX_PIPE_END_WRITE); } if (stderr_pipe_out != NULL) { - if (!g_unix_open_pipe (stderr_pipe, pipe_flags, error)) + if (!g_unix_pipe_open (&stderr_pipe, pipe_flags, error)) goto cleanup_and_fail; - if (_g_spawn_invalid_source_fd (stderr_pipe[0], source_fds, n_fds, error) || - _g_spawn_invalid_source_fd (stderr_pipe[1], source_fds, n_fds, error)) + if (source_fds_collide_with_pipe (&stderr_pipe, source_fds, n_fds, error)) goto cleanup_and_fail; - child_close_fds[n_child_close_fds++] = stderr_pipe[0]; - stderr_fd = stderr_pipe[1]; + child_close_fds[n_child_close_fds++] = g_unix_pipe_get (&stderr_pipe, G_UNIX_PIPE_END_READ); + stderr_fd = g_unix_pipe_get (&stderr_pipe, G_UNIX_PIPE_END_WRITE); } child_close_fds[n_child_close_fds++] = -1; @@ -2488,18 +2495,16 @@ fork_exec (gboolean intermediate_child, if (n_fds > 0) memcpy (source_fds_copy, source_fds, sizeof (*source_fds) * n_fds); - if (!g_unix_open_pipe (child_err_report_pipe, pipe_flags, error)) + if (!g_unix_pipe_open (&child_err_report_pipe, pipe_flags, error)) goto cleanup_and_fail; - if (_g_spawn_invalid_source_fd (child_err_report_pipe[0], source_fds, n_fds, error) || - _g_spawn_invalid_source_fd (child_err_report_pipe[1], source_fds, n_fds, error)) + if (source_fds_collide_with_pipe (&child_err_report_pipe, source_fds, n_fds, error)) goto cleanup_and_fail; if (intermediate_child) { - if (!g_unix_open_pipe (child_pid_report_pipe, pipe_flags, error)) + if (!g_unix_pipe_open (&child_pid_report_pipe, pipe_flags, error)) goto cleanup_and_fail; - if (_g_spawn_invalid_source_fd (child_pid_report_pipe[0], source_fds, n_fds, error) || - _g_spawn_invalid_source_fd (child_pid_report_pipe[1], source_fds, n_fds, error)) + if (source_fds_collide_with_pipe (&child_pid_report_pipe, source_fds, n_fds, error)) goto cleanup_and_fail; } @@ -2538,8 +2543,8 @@ fork_exec (gboolean intermediate_child, * not needed in the close_descriptors case, * though */ - g_clear_fd (&child_err_report_pipe[0], NULL); - g_clear_fd (&child_pid_report_pipe[0], NULL); + g_unix_pipe_close (&child_err_report_pipe, G_UNIX_PIPE_END_READ, NULL); + g_unix_pipe_close (&child_pid_report_pipe, G_UNIX_PIPE_END_READ, NULL); if (child_close_fds[0] != -1) { int i = -1; @@ -2561,16 +2566,16 @@ fork_exec (gboolean intermediate_child, if (grandchild_pid < 0) { /* report -1 as child PID */ - write_all (child_pid_report_pipe[1], &grandchild_pid, - sizeof(grandchild_pid)); + write_all (g_unix_pipe_get (&child_pid_report_pipe, G_UNIX_PIPE_END_WRITE), + &grandchild_pid, sizeof(grandchild_pid)); - write_err_and_exit (child_err_report_pipe[1], + write_err_and_exit (g_unix_pipe_get (&child_err_report_pipe, G_UNIX_PIPE_END_WRITE), CHILD_FORK_FAILED); } else if (grandchild_pid == 0) { - g_clear_fd (&child_pid_report_pipe[1], NULL); - do_exec (child_err_report_pipe[1], + g_unix_pipe_close (&child_pid_report_pipe, G_UNIX_PIPE_END_WRITE, NULL); + do_exec (g_unix_pipe_get (&child_err_report_pipe, G_UNIX_PIPE_END_WRITE), stdin_fd, stdout_fd, stderr_fd, @@ -2595,8 +2600,9 @@ fork_exec (gboolean intermediate_child, } else { - write_all (child_pid_report_pipe[1], &grandchild_pid, sizeof(grandchild_pid)); - g_clear_fd (&child_pid_report_pipe[1], NULL); + write_all (g_unix_pipe_get (&child_pid_report_pipe, G_UNIX_PIPE_END_WRITE), + &grandchild_pid, sizeof(grandchild_pid)); + g_unix_pipe_close (&child_pid_report_pipe, G_UNIX_PIPE_END_WRITE, NULL); _exit (0); } @@ -2606,7 +2612,7 @@ fork_exec (gboolean intermediate_child, /* Just run the child. */ - do_exec (child_err_report_pipe[1], + do_exec (g_unix_pipe_get (&child_err_report_pipe, G_UNIX_PIPE_END_WRITE), stdin_fd, stdout_fd, stderr_fd, @@ -2638,8 +2644,8 @@ fork_exec (gboolean intermediate_child, gint n_ints = 0; /* Close the uncared-about ends of the pipes */ - g_clear_fd (&child_err_report_pipe[1], NULL); - g_clear_fd (&child_pid_report_pipe[1], NULL); + g_unix_pipe_close (&child_err_report_pipe, G_UNIX_PIPE_END_WRITE, NULL); + g_unix_pipe_close (&child_pid_report_pipe, G_UNIX_PIPE_END_WRITE, NULL); /* If we had an intermediate child, reap it */ if (intermediate_child) @@ -2657,7 +2663,7 @@ fork_exec (gboolean intermediate_child, } - if (!read_ints (child_err_report_pipe[0], + if (!read_ints (g_unix_pipe_get (&child_err_report_pipe, G_UNIX_PIPE_END_READ), buf, 2, &n_ints, error)) goto cleanup_and_fail; @@ -2738,7 +2744,7 @@ fork_exec (gboolean intermediate_child, { n_ints = 0; - if (!read_ints (child_pid_report_pipe[0], + if (!read_ints (g_unix_pipe_get (&child_pid_report_pipe, G_UNIX_PIPE_END_READ), buf, 1, &n_ints, error)) goto cleanup_and_fail; @@ -2761,8 +2767,8 @@ fork_exec (gboolean intermediate_child, } /* Success against all odds! return the information */ - g_clear_fd (&child_err_report_pipe[0], NULL); - g_clear_fd (&child_pid_report_pipe[0], NULL); + g_unix_pipe_close (&child_err_report_pipe, G_UNIX_PIPE_END_READ, NULL); + g_unix_pipe_close (&child_pid_report_pipe, G_UNIX_PIPE_END_READ, NULL); g_free (search_path_buffer_heap); g_free (argv_buffer_heap); @@ -2776,18 +2782,18 @@ fork_exec (gboolean intermediate_child, success: /* Close the uncared-about ends of the pipes */ - g_clear_fd (&stdin_pipe[0], NULL); - g_clear_fd (&stdout_pipe[1], NULL); - g_clear_fd (&stderr_pipe[1], NULL); + g_unix_pipe_close (&stdin_pipe, G_UNIX_PIPE_END_READ, NULL); + g_unix_pipe_close (&stdout_pipe, G_UNIX_PIPE_END_WRITE, NULL); + g_unix_pipe_close (&stderr_pipe, G_UNIX_PIPE_END_WRITE, NULL); if (stdin_pipe_out != NULL) - *stdin_pipe_out = g_steal_fd (&stdin_pipe[1]); + *stdin_pipe_out = g_unix_pipe_steal (&stdin_pipe, G_UNIX_PIPE_END_WRITE); if (stdout_pipe_out != NULL) - *stdout_pipe_out = g_steal_fd (&stdout_pipe[0]); + *stdout_pipe_out = g_unix_pipe_steal (&stdout_pipe, G_UNIX_PIPE_END_READ); if (stderr_pipe_out != NULL) - *stderr_pipe_out = g_steal_fd (&stderr_pipe[0]); + *stderr_pipe_out = g_unix_pipe_steal (&stderr_pipe, G_UNIX_PIPE_END_READ); return TRUE; @@ -2811,17 +2817,11 @@ success: } } - g_clear_fd (&stdin_pipe[0], NULL); - g_clear_fd (&stdin_pipe[1], NULL); - g_clear_fd (&stdout_pipe[0], NULL); - g_clear_fd (&stdout_pipe[1], NULL); - g_clear_fd (&stderr_pipe[0], NULL); - g_clear_fd (&stderr_pipe[1], NULL); - - g_clear_fd (&child_err_report_pipe[0], NULL); - g_clear_fd (&child_err_report_pipe[1], NULL); - g_clear_fd (&child_pid_report_pipe[0], NULL); - g_clear_fd (&child_pid_report_pipe[1], NULL); + g_unix_pipe_clear (&stdin_pipe); + g_unix_pipe_clear (&stdout_pipe); + g_unix_pipe_clear (&stderr_pipe); + g_unix_pipe_clear (&child_err_report_pipe); + g_unix_pipe_clear (&child_pid_report_pipe); g_clear_pointer (&search_path_buffer_heap, g_free); g_clear_pointer (&argv_buffer_heap, g_free);