OSDN Git Service

include/
[pf3gnuchains/gcc-fork.git] / libiberty / pex-win32.c
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.
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., 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA.  */
21
22 #include "pex-common.h"
23
24 #ifdef HAVE_STDLIB_H
25 #include <stdlib.h>
26 #endif
27 #ifdef HAVE_STRING_H
28 #include <string.h>
29 #endif
30 #ifdef HAVE_UNISTD_H
31 #include <unistd.h>
32 #endif
33 #ifdef HAVE_SYS_WAIT_H
34 #include <sys/wait.h>
35 #endif
36
37 #include <process.h>
38 #include <io.h>
39 #include <fcntl.h>
40 #include <signal.h>
41 #include <sys/stat.h>
42
43 /* mingw32 headers may not define the following.  */
44
45 #ifndef _P_WAIT
46 #  define _P_WAIT       0
47 #  define _P_NOWAIT     1
48 #  define _P_OVERLAY    2
49 #  define _P_NOWAITO    3
50 #  define _P_DETACH     4
51
52 #  define WAIT_CHILD            0
53 #  define WAIT_GRANDCHILD       1
54 #endif
55
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.  */
58
59 static const char * const *
60 fix_argv (char * const *argvec)
61 {
62   char **argv;
63   int i;
64   char *command0;
65
66   /* See whether we need to change anything.  */
67   for (command0 = argvec[0]; *command0 != '\0'; command0++)
68     if (*command0 == '/')
69       break;
70   if (*command0 == '\0')
71     {
72       for (i = 1; argvec[i] != NULL; i++)
73         if (strpbrk (argvec[i], "\" \t") != NULL)
74           break;
75
76       if (argvec[i] == NULL)
77         return (const char * const *) argvec;
78     }
79
80   for (i = 0; argvec[i] != NULL; i++)
81     ;
82   argv = XNEWVEC (char *, i + 1);
83   for (i = 0; argvec[i] != NULL; i++)
84     argv[i] = xstrdup (argvec[i]);
85   argv[i] = NULL;
86
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++)
94     if (*command0 == '/')
95       *command0 = '\\';
96
97   for (i = 1; argv[i] != 0; i++)
98     {
99       int len, j;
100       char *temp, *newtemp;
101
102       temp = argv[i];
103       len = strlen (temp);
104       for (j = 0; j < len; j++)
105         {
106           if (temp[j] == '"')
107             {
108               newtemp = XNEWVEC (char, len + 2);
109               strncpy (newtemp, temp, j);
110               newtemp [j] = '\\';
111               strncpy (&newtemp [j+1], &temp [j], len-j);
112               newtemp [len+1] = 0;
113               temp = newtemp;
114               len++;
115               j++;
116             }
117         }
118
119       if (argv[i] != temp)
120         {
121           free (argv[i]);
122           argv[i] = temp;
123         }
124     }
125
126   for (i = 0; argv[i] != 0; i++)
127     {
128       if (strpbrk (argv[i], " \t"))
129         {
130           int len, trailing_backslash;
131           char *temp;
132
133           len = strlen (argv[i]);
134           trailing_backslash = 0;
135
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.  */
143           if (len > 1 
144               && argv[i][len-1] == '\\' 
145               && argv[i][len-2] != '\\')
146             {
147               trailing_backslash = 1;
148               ++len;                    /* to escape the final backslash. */
149             }
150
151           len += 2;                     /* and for the enclosing quotes. */
152
153           temp = XNEWVEC (char, len + 1);
154           temp[0] = '"';
155           strcpy (temp + 1, argv[i]);
156           if (trailing_backslash)
157             temp[len - 2] = '\\';
158           temp[len - 1] = '"';
159           temp[len] = '\0';
160
161           free (argv[i]);
162           argv[i] = temp;
163         }
164     }
165
166   return (const char * const *) argv;
167 }
168
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);
179
180 /* The list of functions we pass to the common routines.  */
181
182 const struct pex_funcs funcs =
183 {
184   pex_win32_open_read,
185   pex_win32_open_write,
186   pex_win32_exec_child,
187   pex_win32_close,
188   pex_win32_wait,
189   pex_win32_pipe,
190   pex_win32_fdopenr,
191   NULL /* cleanup */
192 };
193
194 /* Return a newly initialized pex_obj structure.  */
195
196 struct pex_obj *
197 pex_init (int flags, const char *pname, const char *tempbase)
198 {
199   return pex_init_common (flags, pname, tempbase, &funcs);
200 }
201
202 /* Open a file for reading.  */
203
204 static int
205 pex_win32_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
206                      int binary)
207 {
208   return _open (name, _O_RDONLY | (binary ? _O_BINARY : _O_TEXT));
209 }
210
211 /* Open a file for writing.  */
212
213 static int
214 pex_win32_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
215                       int binary)
216 {
217   /* Note that we can't use O_EXCL here because gcc may have already
218      created the temporary file via make_temp_file.  */
219   return _open (name,
220                 (_O_WRONLY | _O_CREAT | _O_TRUNC
221                  | (binary ? _O_BINARY : _O_TEXT)),
222                 _S_IREAD | _S_IWRITE);
223 }
224
225 /* Close a file.  */
226
227 static int
228 pex_win32_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
229 {
230   return _close (fd);
231 }
232
233 /* Execute a child.  */
234
235 static long
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,
239                       int *err)
240 {
241   int org_in, org_out, org_errdes;
242   long pid;
243
244   org_in = -1;
245   org_out = -1;
246   org_errdes = -1;
247
248   if (in != STDIN_FILE_NO)
249     {
250       org_in = _dup (STDIN_FILE_NO);
251       if (org_in < 0)
252         {
253           *err = errno;
254           *errmsg = "_dup";
255           return -1;
256         }
257       if (_dup2 (in, STDIN_FILE_NO) < 0)
258         {
259           *err = errno;
260           *errmsg = "_dup2";
261           return -1;
262         }
263       if (_close (in) < 0)
264         {
265           *err = errno;
266           *errmsg = "_close";
267           return -1;
268         }
269     }
270
271   if (out != STDOUT_FILE_NO)
272     {
273       org_out = _dup (STDOUT_FILE_NO);
274       if (org_out < 0)
275         {
276           *err = errno;
277           *errmsg = "_dup";
278           return -1;
279         }
280       if (_dup2 (out, STDOUT_FILE_NO) < 0)
281         {
282           *err = errno;
283           *errmsg = "_dup2";
284           return -1;
285         }
286       if (_close (out) < 0)
287         {
288           *err = errno;
289           *errmsg = "_close";
290           return -1;
291         }
292     }
293
294   if (errdes != STDERR_FILE_NO
295       || (flags & PEX_STDERR_TO_STDOUT) != 0)
296     {
297       org_errdes = _dup (STDERR_FILE_NO);
298       if (org_errdes < 0)
299         {
300           *err = errno;
301           *errmsg = "_dup";
302           return -1;
303         }
304       if (_dup2 ((flags & PEX_STDERR_TO_STDOUT) != 0 ? STDOUT_FILE_NO : errdes,
305                  STDERR_FILE_NO) < 0)
306         {
307           *err = errno;
308           *errmsg = "_dup2";
309           return -1;
310         }
311       if (errdes != STDERR_FILE_NO)
312         {
313           if (_close (errdes) < 0)
314             {
315               *err = errno;
316               *errmsg = "_close";
317               return -1;
318             }
319         }
320     }
321
322   pid = (((flags & PEX_SEARCH) != 0 ? _spawnvp : _spawnv)
323          (_P_NOWAIT, executable, fix_argv (argv)));
324
325   if (pid == -1)
326     {
327       *err = errno;
328       *errmsg = ((flags & PEX_SEARCH) != 0) ? "_spawnvp" : "_spawnv";
329     }
330
331   if (in != STDIN_FILE_NO)
332     {
333       if (_dup2 (org_in, STDIN_FILE_NO) < 0)
334         {
335           *err = errno;
336           *errmsg = "_dup2";
337           return -1;
338         }
339       if (_close (org_in) < 0)
340         {
341           *err = errno;
342           *errmsg = "_close";
343           return -1;
344         }
345     }
346
347   if (out != STDOUT_FILE_NO)
348     {
349       if (_dup2 (org_out, STDOUT_FILE_NO) < 0)
350         {
351           *err = errno;
352           *errmsg = "_dup2";
353           return -1;
354         }
355       if (_close (org_out) < 0)
356         {
357           *err = errno;
358           *errmsg = "_close";
359           return -1;
360         }
361     }
362
363   if (errdes != STDERR_FILE_NO
364       || (flags & PEX_STDERR_TO_STDOUT) != 0)
365     {
366       if (_dup2 (org_errdes, STDERR_FILE_NO) < 0)
367         {
368           *err = errno;
369           *errmsg = "_dup2";
370           return -1;
371         }
372       if (_close (org_errdes) < 0)
373         {
374           *err = errno;
375           *errmsg = "_close";
376           return -1;
377         }
378     }
379
380   return pid;
381 }
382
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. */
390
391 static int
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)
395 {
396   int termstat;
397
398   if (time != NULL)
399     memset (time, 0, sizeof *time);
400
401   /* FIXME: If done is non-zero, we should probably try to kill the
402      process.  */
403
404   if (_cwait (&termstat, pid, WAIT_CHILD) < 0)
405     {
406       *err = errno;
407       *errmsg = "_cwait";
408       return -1;
409     }
410
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
414      SIGABRT.  */
415
416   if (termstat == 3)
417     *status = SIGABRT;
418   else
419     *status = ((termstat & 0xff) << 8);
420
421   return 0;
422 }
423
424 /* Create a pipe.  */
425
426 static int
427 pex_win32_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
428                 int binary)
429 {
430   return _pipe (p, 256, binary ? _O_BINARY : _O_TEXT);
431 }
432
433 /* Get a FILE pointer to read from a file descriptor.  */
434
435 static FILE *
436 pex_win32_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
437                    int binary)
438 {
439   return fdopen (fd, binary ? "rb" : "r");
440 }