glib/win32: check if dup() failed in helper process

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau 2022-01-26 19:40:55 +04:00
parent 34ce1b1f93
commit 674072b139
2 changed files with 31 additions and 30 deletions

View File

@ -153,6 +153,21 @@ protect_wargv (gint argc,
return argc; return argc;
} }
static int
checked_dup2 (int oldfd, int newfd, int report_fd, gboolean close_old)
{
if (oldfd == newfd)
return newfd;
if (dup2 (oldfd, newfd) == -1)
write_err_and_exit (report_fd, CHILD_DUP_FAILED);
if (close_old)
close (oldfd);
return newfd;
}
#if (defined (_MSC_VER) && _MSC_VER >= 1400) #if (defined (_MSC_VER) && _MSC_VER >= 1400)
/* /*
* This is the (empty) invalid parameter handler * This is the (empty) invalid parameter handler
@ -255,20 +270,12 @@ main (int ignored_argc, char **ignored_argv)
else if (argv[ARG_STDIN][0] == 'z') else if (argv[ARG_STDIN][0] == 'z')
{ {
fd = open ("NUL:", O_RDONLY); fd = open ("NUL:", O_RDONLY);
if (fd != 0) checked_dup2 (fd, 0, child_err_report_fd, TRUE);
{
dup2 (fd, 0);
close (fd);
}
} }
else else
{ {
fd = atoi (argv[ARG_STDIN]); fd = atoi (argv[ARG_STDIN]);
if (fd != 0) checked_dup2 (fd, 0, child_err_report_fd, TRUE);
{
dup2 (fd, 0);
close (fd);
}
} }
if (argv[ARG_STDOUT][0] == '-') if (argv[ARG_STDOUT][0] == '-')
@ -276,42 +283,28 @@ main (int ignored_argc, char **ignored_argv)
else if (argv[ARG_STDOUT][0] == 'z') else if (argv[ARG_STDOUT][0] == 'z')
{ {
fd = open ("NUL:", O_WRONLY); fd = open ("NUL:", O_WRONLY);
if (fd != 1) checked_dup2 (fd, 1, child_err_report_fd, TRUE);
{
dup2 (fd, 1);
close (fd);
}
} }
else else
{ {
fd = atoi (argv[ARG_STDOUT]); fd = atoi (argv[ARG_STDOUT]);
if (fd != 1) checked_dup2 (fd, 1, child_err_report_fd, TRUE);
{
dup2 (fd, 1);
close (fd);
}
} }
saved_stderr_fd = reopen_noninherited (dup (2), _O_WRONLY); saved_stderr_fd = reopen_noninherited (dup (2), _O_WRONLY);
if (saved_stderr_fd == -1)
write_err_and_exit (child_err_report_fd, CHILD_DUP_FAILED);
if (argv[ARG_STDERR][0] == '-') if (argv[ARG_STDERR][0] == '-')
; /* Nothing */ ; /* Nothing */
else if (argv[ARG_STDERR][0] == 'z') else if (argv[ARG_STDERR][0] == 'z')
{ {
fd = open ("NUL:", O_WRONLY); fd = open ("NUL:", O_WRONLY);
if (fd != 2) checked_dup2 (fd, 2, child_err_report_fd, TRUE);
{
dup2 (fd, 2);
close (fd);
}
} }
else else
{ {
fd = atoi (argv[ARG_STDERR]); fd = atoi (argv[ARG_STDERR]);
if (fd != 2) checked_dup2 (fd, 2, child_err_report_fd, TRUE);
{
dup2 (fd, 2);
close (fd);
}
} }
/* argv[ARG_WORKING_DIRECTORY] is the directory in which to run the /* argv[ARG_WORKING_DIRECTORY] is the directory in which to run the
@ -337,6 +330,8 @@ main (int ignored_argc, char **ignored_argv)
*/ */
child_err_report_fd = reopen_noninherited (child_err_report_fd, _O_WRONLY); child_err_report_fd = reopen_noninherited (child_err_report_fd, _O_WRONLY);
helper_sync_fd = reopen_noninherited (helper_sync_fd, _O_RDONLY); helper_sync_fd = reopen_noninherited (helper_sync_fd, _O_RDONLY);
if (helper_sync_fd == -1)
write_err_and_exit (child_err_report_fd, CHILD_DUP_FAILED);
/* argv[ARG_WAIT] is "w" to wait for the program to exit */ /* argv[ARG_WAIT] is "w" to wait for the program to exit */
if (argv[ARG_WAIT][0] == 'w') if (argv[ARG_WAIT][0] == 'w')

View File

@ -89,6 +89,7 @@ enum
CHILD_CHDIR_FAILED, CHILD_CHDIR_FAILED,
CHILD_SPAWN_FAILED, CHILD_SPAWN_FAILED,
CHILD_SPAWN_NOENT, CHILD_SPAWN_NOENT,
CHILD_DUP_FAILED,
}; };
enum { enum {
@ -393,6 +394,11 @@ set_child_error (gintptr report[2],
_("Failed to execute child process (%s)"), _("Failed to execute child process (%s)"),
g_strerror (report[1])); g_strerror (report[1]));
break; break;
case CHILD_DUP_FAILED:
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
_("Failed to dup() in child process (%s)"),
g_strerror (report[1]));
break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
} }