- int retval;
-
- do
- retval = close (fd);
- while (retval < 0 && errno == EINTR);
-
- return retval;
-}
-#define close nonintr_close
-
-static inline int
-nonintr_open (const char *pathname, int oflag, mode_t mode)
-{
- 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 _MSC_VER || defined __MINGW32__
-
- /* 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;
-
- prog_argv = prepare_spawn (prog_argv);
-
- if (pipe_stdout)
- if (_pipe (ifd, 4096, O_BINARY | O_NOINHERIT) < 0)
- error (EXIT_FAILURE, errno, _("cannot create pipe"));
- if (pipe_stdin)
- if (_pipe (ofd, 4096, O_BINARY | O_NOINHERIT) < 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_noinherit (STDIN_FILENO);
- if (pipe_stdout || prog_stdout != NULL)
- orig_stdout = dup_noinherit (STDOUT_FILENO);
- if (null_stderr)
- orig_stderr = dup_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) and also orig_stdin,
- orig_stdout, orig_stderr (which is not explicitly wanted but
- harmless). */
- child = spawnvp (P_NOWAIT, prog_path, prog_argv);
- 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)
- dup2 (orig_stderr, STDERR_FILENO), close (orig_stderr);
- if (pipe_stdout || prog_stdout != NULL)
- dup2 (orig_stdout, STDOUT_FILENO), close (orig_stdout);
- if (pipe_stdin || prog_stdin != NULL)
- dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin);
-
- if (pipe_stdin)
- close (ofd[0]);
- if (pipe_stdout)
- close (ifd[1]);
- if (child == -1)