1 /* Utilities to execute a program in a subprocess (possibly linked by pipes
2 with other subprocesses), and wait for it. Generic Win32 specialization.
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
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"
33 #ifdef HAVE_SYS_WAIT_H
43 /* mingw32 headers may not define the following. */
53 # define WAIT_GRANDCHILD 1
56 /* This is a kludge to get around the Microsoft C spawn functions' propensity
57 to remove the outermost set of double quotes from all arguments. */
59 static const char * const *
60 fix_argv (char * const *argvec
)
66 /* See whether we need to change anything. */
67 for (command0
= argvec
[0]; *command0
!= '\0'; command0
++)
70 if (*command0
== '\0')
72 for (i
= 1; argvec
[i
] != NULL
; i
++)
73 if (strpbrk (argvec
[i
], "\" \t") != NULL
)
76 if (argvec
[i
] == NULL
)
77 return (const char * const *) argvec
;
80 for (i
= 0; argvec
[i
] != NULL
; i
++)
82 argv
= xmalloc ((i
+ 1) * sizeof (char *));
83 for (i
= 0; argvec
[i
] != NULL
; i
++)
84 argv
[i
] = xstrdup (argvec
[i
]);
87 /* Ensure that the executable pathname uses Win32 backslashes. This
88 is not necessary on NT, but on W9x, forward slashes causes
89 failure of spawn* and exec* functions (and probably any function
90 that calls CreateProcess) *iff* the executable pathname (argv[0])
91 is a quoted string. And quoting is necessary in case a pathname
92 contains embedded white space. You can't win. */
93 for (command0
= argv
[0]; *command0
!= '\0'; command0
++)
97 for (i
= 1; argv
[i
] != 0; i
++)
100 char *temp
, *newtemp
;
104 for (j
= 0; j
< len
; j
++)
108 newtemp
= xmalloc (len
+ 2);
109 strncpy (newtemp
, temp
, j
);
111 strncpy (&newtemp
[j
+1], &temp
[j
], len
-j
);
126 for (i
= 0; argv
[i
] != 0; i
++)
128 if (strpbrk (argv
[i
], " \t"))
130 int len
, trailing_backslash
;
133 len
= strlen (argv
[i
]);
134 trailing_backslash
= 0;
136 /* There is an added complication when an arg with embedded white
137 space ends in a backslash (such as in the case of -iprefix arg
138 passed to cpp). The resulting quoted strings gets misinterpreted
139 by the command interpreter -- it thinks that the ending quote
140 is escaped by the trailing backslash and things get confused.
141 We handle this case by escaping the trailing backslash, provided
142 it was not escaped in the first place. */
144 && argv
[i
][len
-1] == '\\'
145 && argv
[i
][len
-2] != '\\')
147 trailing_backslash
= 1;
148 ++len
; /* to escape the final backslash. */
151 len
+= 2; /* and for the enclosing quotes. */
153 temp
= xmalloc (len
+ 1);
155 strcpy (temp
+ 1, argv
[i
]);
156 if (trailing_backslash
)
157 temp
[len
- 2] = '\\';
166 return (const char * const *) argv
;
169 static int pex_win32_open_read (struct pex_obj
*, const char *, int);
170 static int pex_win32_open_write (struct pex_obj
*, const char *, int);
171 static long pex_win32_exec_child (struct pex_obj
*, int, const char *,
172 char * const *, int, int, int,
173 const char **, int *);
174 static int pex_win32_close (struct pex_obj
*, int);
175 static int pex_win32_wait (struct pex_obj
*, long, int *,
176 struct pex_time
*, int, const char **, int *);
177 static int pex_win32_pipe (struct pex_obj
*, int *, int);
178 static FILE *pex_win32_fdopenr (struct pex_obj
*, int, int);
180 /* The list of functions we pass to the common routines. */
182 const struct pex_funcs funcs
=
185 pex_win32_open_write
,
186 pex_win32_exec_child
,
194 /* Return a newly initialized pex_obj structure. */
197 pex_init (int flags
, const char *pname
, const char *tempbase
)
199 return pex_init_common (flags
, pname
, tempbase
, &funcs
);
202 /* Open a file for reading. */
205 pex_win32_open_read (struct pex_obj
*obj ATTRIBUTE_UNUSED
, const char *name
,
208 return _open (name
, _O_RDONLY
| (binary
? _O_BINARY
: _O_TEXT
));
211 /* Open a file for writing. */
214 pex_win32_open_write (struct pex_obj
*obj ATTRIBUTE_UNUSED
, const char *name
,
217 /* Note that we can't use O_EXCL here because gcc may have already
218 created the temporary file via make_temp_file. */
220 (_O_WRONLY
| _O_CREAT
| _O_TRUNC
221 | (binary
? _O_BINARY
: _O_TEXT
)),
222 _S_IREAD
| _S_IWRITE
);
228 pex_win32_close (struct pex_obj
*obj ATTRIBUTE_UNUSED
, int fd
)
233 /* Execute a child. */
236 pex_win32_exec_child (struct pex_obj
*obj ATTRIBUTE_UNUSED
, int flags
,
237 const char *executable
, char * const * argv
,
238 int in
, int out
, int errdes
, const char **errmsg
,
241 int org_in
, org_out
, org_errdes
;
248 if (in
!= STDIN_FILE_NO
)
250 org_in
= _dup (STDIN_FILE_NO
);
257 if (_dup2 (in
, STDIN_FILE_NO
) < 0)
271 if (out
!= STDOUT_FILE_NO
)
273 org_out
= _dup (STDOUT_FILE_NO
);
280 if (_dup2 (out
, STDOUT_FILE_NO
) < 0)
286 if (_close (out
) < 0)
294 if (errdes
!= STDERR_FILE_NO
295 || (flags
& PEX_STDERR_TO_STDOUT
) != 0)
297 org_errdes
= _dup (STDERR_FILE_NO
);
304 if (_dup2 ((flags
& PEX_STDERR_TO_STDOUT
) != 0 ? STDOUT_FILE_NO
: errdes
,
311 if (errdes
!= STDERR_FILE_NO
)
313 if (_close (errdes
) < 0)
322 pid
= (((flags
& PEX_SEARCH
) != 0 ? _spawnvp
: _spawnv
)
323 (_P_NOWAIT
, executable
, fix_argv (argv
)));
328 *errmsg
= ((flags
& PEX_SEARCH
) != 0) ? "_spawnvp" : "_spawnv";
331 if (in
!= STDIN_FILE_NO
)
333 if (_dup2 (org_in
, STDIN_FILE_NO
) < 0)
339 if (_close (org_in
) < 0)
347 if (out
!= STDOUT_FILE_NO
)
349 if (_dup2 (org_out
, STDOUT_FILE_NO
) < 0)
355 if (_close (org_out
) < 0)
363 if (errdes
!= STDERR_FILE_NO
364 || (flags
& PEX_STDERR_TO_STDOUT
) != 0)
366 if (_dup2 (org_errdes
, STDERR_FILE_NO
) < 0)
372 if (_close (org_errdes
) < 0)
383 /* Wait for a child process to complete. MS CRTDLL doesn't return
384 enough information in status to decide if the child exited due to a
385 signal or not, rather it simply returns an integer with the exit
386 code of the child; eg., if the child exited with an abort() call
387 and didn't have a handler for SIGABRT, it simply returns with
388 status == 3. We fix the status code to conform to the usual WIF*
389 macros. Note that WIFSIGNALED will never be true under CRTDLL. */
392 pex_win32_wait (struct pex_obj
*obj ATTRIBUTE_UNUSED
, long pid
,
393 int *status
, struct pex_time
*time
, int done ATTRIBUTE_UNUSED
,
394 const char **errmsg
, int *err
)
399 memset (time
, 0, sizeof *time
);
401 /* FIXME: If done is non-zero, we should probably try to kill the
404 if (_cwait (&termstat
, pid
, WAIT_CHILD
) < 0)
411 /* cwait returns the child process exit code in termstat. A value
412 of 3 indicates that the child caught a signal, but not which one.
413 Since only SIGABRT, SIGFPE and SIGINT do anything, we report
419 *status
= ((termstat
& 0xff) << 8);
427 pex_win32_pipe (struct pex_obj
*obj ATTRIBUTE_UNUSED
, int *p
,
430 return _pipe (p
, 256, binary
? _O_BINARY
: _O_TEXT
);
433 /* Get a FILE pointer to read from a file descriptor. */
436 pex_win32_fdopenr (struct pex_obj
*obj ATTRIBUTE_UNUSED
, int fd
,
439 return fdopen (fd
, binary
? "rb" : "r");
This page took 0.037611 seconds and 4 git commands to generate.