mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-13 07:56:17 +01:00
gspawn: Use g_clear_fd() instead of reinventing it
g_clear_fd() is documented to be async-signal safe whenever the fd is either negative or valid (which it should be here) and the error is NULL (which it always is here). Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
e93e1cb547
commit
6fd1037361
@ -263,23 +263,6 @@ g_spawn_async (const gchar *working_directory,
|
||||
error);
|
||||
}
|
||||
|
||||
/* Avoids a danger in threaded situations (calling close()
|
||||
* on a file descriptor twice, and another thread has
|
||||
* re-opened it since the first close)
|
||||
*
|
||||
* This function is called between fork() and exec() and hence must be
|
||||
* async-signal-safe (see signal-safety(7)).
|
||||
*/
|
||||
static void
|
||||
close_and_invalidate (gint *fd)
|
||||
{
|
||||
if (*fd < 0)
|
||||
return;
|
||||
|
||||
g_close (*fd, NULL);
|
||||
*fd = -1;
|
||||
}
|
||||
|
||||
/* Some versions of OS X define READ_OK in public headers */
|
||||
#undef READ_OK
|
||||
|
||||
@ -484,8 +467,7 @@ g_spawn_sync (const gchar *working_directory,
|
||||
failed = TRUE;
|
||||
break;
|
||||
case READ_EOF:
|
||||
close_and_invalidate (&outpipe);
|
||||
outpipe = -1;
|
||||
g_clear_fd (&outpipe, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -503,8 +485,7 @@ g_spawn_sync (const gchar *working_directory,
|
||||
failed = TRUE;
|
||||
break;
|
||||
case READ_EOF:
|
||||
close_and_invalidate (&errpipe);
|
||||
errpipe = -1;
|
||||
g_clear_fd (&errpipe, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -516,12 +497,9 @@ g_spawn_sync (const gchar *working_directory,
|
||||
}
|
||||
|
||||
/* These should only be open still if we had an error. */
|
||||
|
||||
if (outpipe >= 0)
|
||||
close_and_invalidate (&outpipe);
|
||||
if (errpipe >= 0)
|
||||
close_and_invalidate (&errpipe);
|
||||
|
||||
g_clear_fd (&outpipe, NULL);
|
||||
g_clear_fd (&errpipe, NULL);
|
||||
|
||||
/* Wait for child to exit, even if we have
|
||||
* an error pending.
|
||||
*/
|
||||
@ -1822,7 +1800,7 @@ do_exec (gint child_err_report_fd,
|
||||
if (safe_dup2 (read_null, 0) < 0)
|
||||
write_err_and_exit (child_err_report_fd,
|
||||
CHILD_DUPFD_FAILED);
|
||||
close_and_invalidate (&read_null);
|
||||
g_clear_fd (&read_null, NULL);
|
||||
}
|
||||
|
||||
/* Like with stdin above, it's possible the caller assigned
|
||||
@ -1859,7 +1837,7 @@ do_exec (gint child_err_report_fd,
|
||||
if (safe_dup2 (write_null, 1) < 0)
|
||||
write_err_and_exit (child_err_report_fd,
|
||||
CHILD_DUPFD_FAILED);
|
||||
close_and_invalidate (&write_null);
|
||||
g_clear_fd (&write_null, NULL);
|
||||
}
|
||||
|
||||
if (IS_STD_FILENO (stderr_fd) && stderr_fd != STDERR_FILENO)
|
||||
@ -1891,7 +1869,7 @@ do_exec (gint child_err_report_fd,
|
||||
if (safe_dup2 (write_null, 2) < 0)
|
||||
write_err_and_exit (child_err_report_fd,
|
||||
CHILD_DUPFD_FAILED);
|
||||
close_and_invalidate (&write_null);
|
||||
g_clear_fd (&write_null, NULL);
|
||||
}
|
||||
|
||||
/* Close all file descriptors but stdin, stdout and stderr, and any of source_fds,
|
||||
@ -1982,7 +1960,7 @@ do_exec (gint child_err_report_fd,
|
||||
if (safe_dup2 (source_fds[i], target_fds[i]) < 0)
|
||||
write_err_and_exit (child_err_report_fd, CHILD_DUPFD_FAILED);
|
||||
|
||||
close_and_invalidate (&source_fds[i]);
|
||||
g_clear_fd (&source_fds[i], NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2272,12 +2250,12 @@ do_posix_spawn (const gchar * const *argv,
|
||||
|
||||
out_close_fds:
|
||||
for (i = 0; i < num_parent_close_fds; i++)
|
||||
close_and_invalidate (&parent_close_fds [i]);
|
||||
g_clear_fd (&parent_close_fds[i], NULL);
|
||||
|
||||
if (duped_source_fds != NULL)
|
||||
{
|
||||
for (i = 0; i < n_fds; i++)
|
||||
close_and_invalidate (&duped_source_fds[i]);
|
||||
g_clear_fd (&duped_source_fds[i], NULL);
|
||||
g_free (duped_source_fds);
|
||||
}
|
||||
|
||||
@ -2560,13 +2538,13 @@ fork_exec (gboolean intermediate_child,
|
||||
* not needed in the close_descriptors case,
|
||||
* though
|
||||
*/
|
||||
close_and_invalidate (&child_err_report_pipe[0]);
|
||||
close_and_invalidate (&child_pid_report_pipe[0]);
|
||||
g_clear_fd (&child_err_report_pipe[0], NULL);
|
||||
g_clear_fd (&child_pid_report_pipe[0], NULL);
|
||||
if (child_close_fds[0] != -1)
|
||||
{
|
||||
int i = -1;
|
||||
while (child_close_fds[++i] != -1)
|
||||
close_and_invalidate (&child_close_fds[i]);
|
||||
g_clear_fd (&child_close_fds[i], NULL);
|
||||
}
|
||||
|
||||
if (intermediate_child)
|
||||
@ -2591,7 +2569,7 @@ fork_exec (gboolean intermediate_child,
|
||||
}
|
||||
else if (grandchild_pid == 0)
|
||||
{
|
||||
close_and_invalidate (&child_pid_report_pipe[1]);
|
||||
g_clear_fd (&child_pid_report_pipe[1], NULL);
|
||||
do_exec (child_err_report_pipe[1],
|
||||
stdin_fd,
|
||||
stdout_fd,
|
||||
@ -2618,7 +2596,7 @@ fork_exec (gboolean intermediate_child,
|
||||
else
|
||||
{
|
||||
write_all (child_pid_report_pipe[1], &grandchild_pid, sizeof(grandchild_pid));
|
||||
close_and_invalidate (&child_pid_report_pipe[1]);
|
||||
g_clear_fd (&child_pid_report_pipe[1], NULL);
|
||||
|
||||
_exit (0);
|
||||
}
|
||||
@ -2660,8 +2638,8 @@ fork_exec (gboolean intermediate_child,
|
||||
gint n_ints = 0;
|
||||
|
||||
/* Close the uncared-about ends of the pipes */
|
||||
close_and_invalidate (&child_err_report_pipe[1]);
|
||||
close_and_invalidate (&child_pid_report_pipe[1]);
|
||||
g_clear_fd (&child_err_report_pipe[1], NULL);
|
||||
g_clear_fd (&child_pid_report_pipe[1], NULL);
|
||||
|
||||
/* If we had an intermediate child, reap it */
|
||||
if (intermediate_child)
|
||||
@ -2783,8 +2761,8 @@ fork_exec (gboolean intermediate_child,
|
||||
}
|
||||
|
||||
/* Success against all odds! return the information */
|
||||
close_and_invalidate (&child_err_report_pipe[0]);
|
||||
close_and_invalidate (&child_pid_report_pipe[0]);
|
||||
g_clear_fd (&child_err_report_pipe[0], NULL);
|
||||
g_clear_fd (&child_pid_report_pipe[0], NULL);
|
||||
|
||||
g_free (search_path_buffer_heap);
|
||||
g_free (argv_buffer_heap);
|
||||
@ -2798,9 +2776,9 @@ fork_exec (gboolean intermediate_child,
|
||||
|
||||
success:
|
||||
/* Close the uncared-about ends of the pipes */
|
||||
close_and_invalidate (&stdin_pipe[0]);
|
||||
close_and_invalidate (&stdout_pipe[1]);
|
||||
close_and_invalidate (&stderr_pipe[1]);
|
||||
g_clear_fd (&stdin_pipe[0], NULL);
|
||||
g_clear_fd (&stdout_pipe[1], NULL);
|
||||
g_clear_fd (&stderr_pipe[1], NULL);
|
||||
|
||||
if (stdin_pipe_out != NULL)
|
||||
*stdin_pipe_out = g_steal_fd (&stdin_pipe[1]);
|
||||
@ -2833,17 +2811,17 @@ success:
|
||||
}
|
||||
}
|
||||
|
||||
close_and_invalidate (&stdin_pipe[0]);
|
||||
close_and_invalidate (&stdin_pipe[1]);
|
||||
close_and_invalidate (&stdout_pipe[0]);
|
||||
close_and_invalidate (&stdout_pipe[1]);
|
||||
close_and_invalidate (&stderr_pipe[0]);
|
||||
close_and_invalidate (&stderr_pipe[1]);
|
||||
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);
|
||||
|
||||
close_and_invalidate (&child_err_report_pipe[0]);
|
||||
close_and_invalidate (&child_err_report_pipe[1]);
|
||||
close_and_invalidate (&child_pid_report_pipe[0]);
|
||||
close_and_invalidate (&child_pid_report_pipe[1]);
|
||||
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_clear_pointer (&search_path_buffer_heap, g_free);
|
||||
g_clear_pointer (&argv_buffer_heap, g_free);
|
||||
|
Loading…
Reference in New Issue
Block a user