- int retval;
-
- do
- retval = open (pathname, oflag, mode);
- while (retval < 0 && errno == EINTR);
-
- return retval;
-}
-#undef open /* avoid warning on VMS */
-#define open nonintr_open
-
-#endif
-
-
-/* Open a pipe connected to a child process.
- *
- * write system read
- * parent -> fd[1] -> STDIN_FILENO -> child if pipe_stdin
- * parent <- fd[0] <- STDOUT_FILENO <- child if pipe_stdout
- * read system write
- *
- * At least one of pipe_stdin, pipe_stdout must be true.
- * pipe_stdin and prog_stdin together determine the child's standard input.
- * pipe_stdout and prog_stdout together determine the child's standard output.
- * If pipe_stdin is true, prog_stdin is ignored.
- * If pipe_stdout is true, prog_stdout is ignored.
- */
-static pid_t
-create_pipe (const char *progname,
- const char *prog_path, char **prog_argv,
- bool pipe_stdin, bool pipe_stdout,
- const char *prog_stdin, const char *prog_stdout,
- bool null_stderr,
- bool slave_process, bool exit_on_error,
- int fd[2])
-{
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-
- /* Native Woe32 API.
- This uses _pipe(), dup2(), and spawnv(). It could also be implemented
- using the low-level functions CreatePipe(), DuplicateHandle(),
- CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
- and cvs source code. */
- int ifd[2];
- int ofd[2];
- int orig_stdin;
- int orig_stdout;
- int orig_stderr;
- int child;
- int nulloutfd;
- int stdinfd;
- int stdoutfd;
-
- /* FIXME: Need to free memory allocated by prepare_spawn. */
- prog_argv = prepare_spawn (prog_argv);
-
- if (pipe_stdout)
- if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0)
- error (EXIT_FAILURE, errno, _("cannot create pipe"));
- if (pipe_stdin)
- if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0)
- error (EXIT_FAILURE, errno, _("cannot create pipe"));
-/* Data flow diagram:
- *
- * write system read
- * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
- * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
- * read system write
- *
- */
-
- /* Save standard file handles of parent process. */
- if (pipe_stdin || prog_stdin != NULL)
- orig_stdin = dup_safer_noinherit (STDIN_FILENO);
- if (pipe_stdout || prog_stdout != NULL)
- orig_stdout = dup_safer_noinherit (STDOUT_FILENO);
- if (null_stderr)
- orig_stderr = dup_safer_noinherit (STDERR_FILENO);
- child = -1;
-
- /* Create standard file handles of child process. */
- nulloutfd = -1;
- stdinfd = -1;
- stdoutfd = -1;
- if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
- && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
- && (!null_stderr
- || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
- && (nulloutfd == STDERR_FILENO
- || (dup2 (nulloutfd, STDERR_FILENO) >= 0
- && close (nulloutfd) >= 0))))
- && (pipe_stdin
- || prog_stdin == NULL
- || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
- && (stdinfd == STDIN_FILENO
- || (dup2 (stdinfd, STDIN_FILENO) >= 0
- && close (stdinfd) >= 0))))
- && (pipe_stdout
- || prog_stdout == NULL
- || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
- && (stdoutfd == STDOUT_FILENO
- || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
- && close (stdoutfd) >= 0)))))
- /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
- but it inherits all open()ed or dup2()ed file handles (which is what
- we want in the case of STD*_FILENO). */
- /* Use spawnvpe and pass the environment explicitly. This is needed if
- the program has modified the environment using putenv() or [un]setenv().
- On Windows, programs have two environments, one in the "environment
- block" of the process and managed through SetEnvironmentVariable(), and
- one inside the process, in the location retrieved by the 'environ'
- macro. When using spawnvp() without 'e', the child process inherits a
- copy of the environment block - ignoring the effects of putenv() and
- [un]setenv(). */
- {
- child = spawnvpe (P_NOWAIT, prog_path, (const char **) prog_argv,
- (const char **) environ);
- if (child < 0 && errno == ENOEXEC)
- {
- /* prog is not an native executable. Try to execute it as a
- shell script. Note that prepare_spawn() has already prepended
- a hidden element "sh.exe" to prog_argv. */
- --prog_argv;
- child = spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
- (const char **) environ);
- }
- }
- if (stdinfd >= 0)
- close (stdinfd);
- if (stdoutfd >= 0)
- close (stdoutfd);
- if (nulloutfd >= 0)
- close (nulloutfd);
-
- /* Restore standard file handles of parent process. */
- if (null_stderr)
- undup_safer_noinherit (orig_stderr, STDERR_FILENO);
- if (pipe_stdout || prog_stdout != NULL)
- undup_safer_noinherit (orig_stdout, STDOUT_FILENO);
- if (pipe_stdin || prog_stdin != NULL)
- undup_safer_noinherit (orig_stdin, STDIN_FILENO);
-
- if (pipe_stdin)
- close (ofd[0]);
- if (pipe_stdout)
- close (ifd[1]);
- if (child == -1)