merge from gcc
[deliverable/binutils-gdb.git] / libiberty / pex-cygwin.c
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.
5
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.
11
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.
16
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. */
21
22 #include "pex-common.h"
23
24 #ifdef HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 #ifdef HAVE_SYS_WAIT_H
28 #include <sys/wait.h>
29 #endif
30
31 #include <process.h>
32 #include <io.h>
33 #include <fcntl.h>
34 #include <signal.h>
35
36 extern int _spawnv ();
37 extern int _spawnvp ();
38
39 /* Win32 supports pipes, and Cygwin provides waitpid. */
40
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;
49 {
50 int pid;
51 int pdes[2], org_stdin, org_stdout;
52 int input_desc, output_desc;
53 int retries, sleep_interval;
54
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;
59
60 /* If this is the first process, initialize. */
61 if (flags & PEXECUTE_FIRST)
62 last_pipe_input = STDIN_FILE_NO;
63
64 input_desc = last_pipe_input;
65
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))
69 {
70 if (_pipe (pdes, 256, O_BINARY) < 0)
71 {
72 *errmsg_fmt = "pipe";
73 *errmsg_arg = NULL;
74 return -1;
75 }
76 output_desc = pdes[WRITE_PORT];
77 last_pipe_input = pdes[READ_PORT];
78 }
79 else
80 {
81 /* Last process. */
82 output_desc = STDOUT_FILE_NO;
83 last_pipe_input = STDIN_FILE_NO;
84 }
85
86 if (input_desc != STDIN_FILE_NO)
87 {
88 org_stdin = dup (STDIN_FILE_NO);
89 dup2 (input_desc, STDIN_FILE_NO);
90 close (input_desc);
91 }
92
93 if (output_desc != STDOUT_FILE_NO)
94 {
95 org_stdout = dup (STDOUT_FILE_NO);
96 dup2 (output_desc, STDOUT_FILE_NO);
97 close (output_desc);
98 }
99
100 pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
101 (_P_NOWAIT, program, argv);
102
103 if (input_desc != STDIN_FILE_NO)
104 {
105 dup2 (org_stdin, STDIN_FILE_NO);
106 close (org_stdin);
107 }
108
109 if (output_desc != STDOUT_FILE_NO)
110 {
111 dup2 (org_stdout, STDOUT_FILE_NO);
112 close (org_stdout);
113 }
114
115 if (pid == -1)
116 {
117 *errmsg_fmt = install_error_msg;
118 *errmsg_arg = program;
119 return -1;
120 }
121
122 return pid;
123 }
124
125 int
126 pwait (pid, status, flags)
127 int pid;
128 int *status;
129 int flags ATTRIBUTE_UNUSED;
130 {
131 return waitpid (pid, status, 0);
132 }
This page took 0.042365 seconds and 4 git commands to generate.