2003-01-24 Paolo Carlini <pcarlini@unitus.it>
[official-gcc.git] / libiberty / pex-cygwin.c
blobf5d18db3424380ff896632d0239bf500e0e12b01
1 /* Utilities to execute a program in a subprocess (possibly linked by pipes
2 with other subprocesses), and wait for it. Cygwin specialization.
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
4 Free Software Foundation, Inc.
6 This file is part of the libiberty library.
7 Libiberty is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 Libiberty is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with libiberty; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include "pex-common.h"
24 #ifdef HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 #ifdef HAVE_SYS_WAIT_H
28 #include <sys/wait.h>
29 #endif
31 #include <process.h>
32 #include <io.h>
33 #include <fcntl.h>
34 #include <signal.h>
36 extern int _spawnv ();
37 extern int _spawnvp ();
39 /* Win32 supports pipes, and Cygwin provides waitpid. */
41 int
42 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
43 const char *program;
44 char * const *argv;
45 const char *this_pname;
46 const char *temp_base;
47 char **errmsg_fmt, **errmsg_arg;
48 int flags;
50 int pid;
51 int pdes[2], org_stdin, org_stdout;
52 int input_desc, output_desc;
53 int retries, sleep_interval;
55 /* Pipe waiting from last process, to be used as input for the next one.
56 Value is STDIN_FILE_NO if no pipe is waiting
57 (i.e. the next command is the first of a group). */
58 static int last_pipe_input;
60 /* If this is the first process, initialize. */
61 if (flags & PEXECUTE_FIRST)
62 last_pipe_input = STDIN_FILE_NO;
64 input_desc = last_pipe_input;
66 /* If this isn't the last process, make a pipe for its output,
67 and record it as waiting to be the input to the next process. */
68 if (! (flags & PEXECUTE_LAST))
70 if (_pipe (pdes, 256, O_BINARY) < 0)
72 *errmsg_fmt = "pipe";
73 *errmsg_arg = NULL;
74 return -1;
76 output_desc = pdes[WRITE_PORT];
77 last_pipe_input = pdes[READ_PORT];
79 else
81 /* Last process. */
82 output_desc = STDOUT_FILE_NO;
83 last_pipe_input = STDIN_FILE_NO;
86 if (input_desc != STDIN_FILE_NO)
88 org_stdin = dup (STDIN_FILE_NO);
89 dup2 (input_desc, STDIN_FILE_NO);
90 close (input_desc);
93 if (output_desc != STDOUT_FILE_NO)
95 org_stdout = dup (STDOUT_FILE_NO);
96 dup2 (output_desc, STDOUT_FILE_NO);
97 close (output_desc);
100 pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
101 (_P_NOWAIT, program, argv);
103 if (input_desc != STDIN_FILE_NO)
105 dup2 (org_stdin, STDIN_FILE_NO);
106 close (org_stdin);
109 if (output_desc != STDOUT_FILE_NO)
111 dup2 (org_stdout, STDOUT_FILE_NO);
112 close (org_stdout);
115 if (pid == -1)
117 *errmsg_fmt = install_error_msg;
118 *errmsg_arg = program;
119 return -1;
122 return pid;
126 pwait (pid, status, flags)
127 int pid;
128 int *status;
129 int flags ATTRIBUTE_UNUSED;
131 return waitpid (pid, status, 0);