gspawn, win32: fix child stderr when coverage enabled

This fixes test that were added in previous commit:
checking for empty stderr failed with coverage enabled, since
coverage warnings printed from gspawn-win32-helper process were treated
as child output. This is fixed by removing redirection after child
finishes execution.

The dup_noninherited renamed to reopen_noninherited,
since it actually always closes passed file descriptor.
This commit is contained in:
Vasily Galkin 2018-12-27 00:00:50 +03:00
parent cafb61a179
commit f7f597c841
2 changed files with 14 additions and 7 deletions

View File

@ -179,6 +179,7 @@ main (int ignored_argc, char **ignored_argv)
{ {
int child_err_report_fd = -1; int child_err_report_fd = -1;
int helper_sync_fd = -1; int helper_sync_fd = -1;
int saved_stderr_fd = -1;
int i; int i;
int fd; int fd;
int mode; int mode;
@ -280,6 +281,7 @@ main (int ignored_argc, char **ignored_argv)
} }
} }
saved_stderr_fd = reopen_noninherited (dup (2), _O_WRONLY);
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')
@ -315,15 +317,15 @@ main (int ignored_argc, char **ignored_argv)
*/ */
if (argv[ARG_CLOSE_DESCRIPTORS][0] == 'y') if (argv[ARG_CLOSE_DESCRIPTORS][0] == 'y')
for (i = 3; i < 1000; i++) /* FIXME real limit? */ for (i = 3; i < 1000; i++) /* FIXME real limit? */
if (i != child_err_report_fd && i != helper_sync_fd) if (i != child_err_report_fd && i != helper_sync_fd && i != saved_stderr_fd)
if (_get_osfhandle (i) != -1) if (_get_osfhandle (i) != -1)
close (i); close (i);
/* We don't want our child to inherit the error report and /* We don't want our child to inherit the error report and
* helper sync fds. * helper sync fds.
*/ */
child_err_report_fd = dup_noninherited (child_err_report_fd, _O_WRONLY); child_err_report_fd = reopen_noninherited (child_err_report_fd, _O_WRONLY);
helper_sync_fd = dup_noninherited (helper_sync_fd, _O_RDONLY); helper_sync_fd = reopen_noninherited (helper_sync_fd, _O_RDONLY);
/* 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')
@ -351,6 +353,11 @@ main (int ignored_argc, char **ignored_argv)
saved_errno = errno; saved_errno = errno;
/* Some coverage warnings may be printed on stderr during this process exit.
* Remove redirection so that they would go to original stderr
* instead of being treated as part of stderr of child process.
*/
dup2 (saved_stderr_fd, 2);
if (handle == -1 && saved_errno != 0) if (handle == -1 && saved_errno != 0)
{ {
int ec = (saved_errno == ENOENT) int ec = (saved_errno == ENOENT)

View File

@ -105,8 +105,8 @@ enum {
}; };
static int static int
dup_noninherited (int fd, reopen_noninherited (int fd,
int mode) int mode)
{ {
HANDLE filehandle; HANDLE filehandle;
@ -606,7 +606,7 @@ do_spawn_with_fds (gint *exit_status,
* helper process, and the started actual user process. As such that * helper process, and the started actual user process. As such that
* shouldn't harm, but it is unnecessary. * shouldn't harm, but it is unnecessary.
*/ */
child_err_report_pipe[0] = dup_noninherited (child_err_report_pipe[0], _O_RDONLY); child_err_report_pipe[0] = reopen_noninherited (child_err_report_pipe[0], _O_RDONLY);
if (flags & G_SPAWN_FILE_AND_ARGV_ZERO) if (flags & G_SPAWN_FILE_AND_ARGV_ZERO)
{ {
@ -625,7 +625,7 @@ do_spawn_with_fds (gint *exit_status,
* process won't read but won't get any EOF either, as it has the * process won't read but won't get any EOF either, as it has the
* write end open itself. * write end open itself.
*/ */
helper_sync_pipe[1] = dup_noninherited (helper_sync_pipe[1], _O_WRONLY); helper_sync_pipe[1] = reopen_noninherited (helper_sync_pipe[1], _O_WRONLY);
if (stdin_fd != -1) if (stdin_fd != -1)
{ {