OSDN Git Service

* pex-unix.c (pex_unix_exec_child): Save/restore environ.
[pf3gnuchains/gcc-fork.git] / libiberty / pex-unix.c
1 /* Utilities to execute a program in a subprocess (possibly linked by pipes
2    with other subprocesses), and wait for it.  Generic Unix version
3    (also used for UWIN and VMS).
4    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2009
5    Free Software Foundation, Inc.
6
7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 Libiberty is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public
19 License along with libiberty; see the file COPYING.LIB.  If not,
20 write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA.  */
22
23 #include "config.h"
24 #include "libiberty.h"
25 #include "pex-common.h"
26
27 #include <stdio.h>
28 #include <signal.h>
29 #include <errno.h>
30 #ifdef NEED_DECLARATION_ERRNO
31 extern int errno;
32 #endif
33 #ifdef HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif
36 #ifdef HAVE_STRING_H
37 #include <string.h>
38 #endif
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42
43 #include <sys/types.h>
44
45 #ifdef HAVE_FCNTL_H
46 #include <fcntl.h>
47 #endif
48 #ifdef HAVE_SYS_WAIT_H
49 #include <sys/wait.h>
50 #endif
51 #ifdef HAVE_GETRUSAGE
52 #include <sys/time.h>
53 #include <sys/resource.h>
54 #endif
55 #ifdef HAVE_SYS_STAT_H
56 #include <sys/stat.h>
57 #endif
58
59
60 #ifdef vfork /* Autoconf may define this to fork for us. */
61 # define VFORK_STRING "fork"
62 #else
63 # define VFORK_STRING "vfork"
64 #endif
65 #ifdef HAVE_VFORK_H
66 #include <vfork.h>
67 #endif
68 #if defined(VMS) && defined (__LONG_POINTERS)
69 #ifndef __CHAR_PTR32
70 typedef char * __char_ptr32
71 __attribute__ ((mode (SI)));
72 #endif
73
74 typedef __char_ptr32 *__char_ptr_char_ptr32
75 __attribute__ ((mode (SI)));
76
77 /* Return a 32 bit pointer to an array of 32 bit pointers 
78    given a 64 bit pointer to an array of 64 bit pointers.  */
79
80 static __char_ptr_char_ptr32
81 to_ptr32 (char **ptr64)
82 {
83   int argc;
84   __char_ptr_char_ptr32 short_argv;
85
86   for (argc=0; ptr64[argc]; argc++);
87
88   /* Reallocate argv with 32 bit pointers.  */
89   short_argv = (__char_ptr_char_ptr32) decc$malloc
90     (sizeof (__char_ptr32) * (argc + 1));
91
92   for (argc=0; ptr64[argc]; argc++)
93     short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]);
94
95   short_argv[argc] = (__char_ptr32) 0;
96   return short_argv;
97
98 }
99 #else
100 #define to_ptr32(argv) argv
101 #endif
102
103 /* File mode to use for private and world-readable files.  */
104
105 #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH)
106 #define PUBLIC_MODE  \
107     (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
108 #else
109 #define PUBLIC_MODE 0666
110 #endif
111
112 /* Get the exit status of a particular process, and optionally get the
113    time that it took.  This is simple if we have wait4, slightly
114    harder if we have waitpid, and is a pain if we only have wait.  */
115
116 static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *);
117
118 #ifdef HAVE_WAIT4
119
120 static pid_t
121 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
122           struct pex_time *time)
123 {
124   pid_t ret;
125   struct rusage r;
126
127 #ifdef HAVE_WAITPID
128   if (time == NULL)
129     return waitpid (pid, status, 0);
130 #endif
131
132   ret = wait4 (pid, status, 0, &r);
133
134   if (time != NULL)
135     {
136       time->user_seconds = r.ru_utime.tv_sec;
137       time->user_microseconds= r.ru_utime.tv_usec;
138       time->system_seconds = r.ru_stime.tv_sec;
139       time->system_microseconds= r.ru_stime.tv_usec;
140     }
141
142   return ret;
143 }
144
145 #else /* ! defined (HAVE_WAIT4) */
146
147 #ifdef HAVE_WAITPID
148
149 #ifndef HAVE_GETRUSAGE
150
151 static pid_t
152 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
153           struct pex_time *time)
154 {
155   if (time != NULL)
156     memset (time, 0, sizeof (struct pex_time));
157   return waitpid (pid, status, 0);
158 }
159
160 #else /* defined (HAVE_GETRUSAGE) */
161
162 static pid_t
163 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
164           struct pex_time *time)
165 {
166   struct rusage r1, r2;
167   pid_t ret;
168
169   if (time == NULL)
170     return waitpid (pid, status, 0);
171
172   getrusage (RUSAGE_CHILDREN, &r1);
173
174   ret = waitpid (pid, status, 0);
175   if (ret < 0)
176     return ret;
177
178   getrusage (RUSAGE_CHILDREN, &r2);
179
180   time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
181   time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
182   if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec)
183     {
184       --time->user_seconds;
185       time->user_microseconds += 1000000;
186     }
187
188   time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
189   time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
190   if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec)
191     {
192       --time->system_seconds;
193       time->system_microseconds += 1000000;
194     }
195
196   return ret;
197 }
198
199 #endif /* defined (HAVE_GETRUSAGE) */
200
201 #else /* ! defined (HAVE_WAITPID) */
202
203 struct status_list
204 {
205   struct status_list *next;
206   pid_t pid;
207   int status;
208   struct pex_time time;
209 };
210
211 static pid_t
212 pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time)
213 {
214   struct status_list **pp;
215
216   for (pp = (struct status_list **) &obj->sysdep;
217        *pp != NULL;
218        pp = &(*pp)->next)
219     {
220       if ((*pp)->pid == pid)
221         {
222           struct status_list *p;
223
224           p = *pp;
225           *status = p->status;
226           if (time != NULL)
227             *time = p->time;
228           *pp = p->next;
229           free (p);
230           return pid;
231         }
232     }
233
234   while (1)
235     {
236       pid_t cpid;
237       struct status_list *psl;
238       struct pex_time pt;
239 #ifdef HAVE_GETRUSAGE
240       struct rusage r1, r2;
241 #endif
242
243       if (time != NULL)
244         {
245 #ifdef HAVE_GETRUSAGE
246           getrusage (RUSAGE_CHILDREN, &r1);
247 #else
248           memset (&pt, 0, sizeof (struct pex_time));
249 #endif
250         }
251
252       cpid = wait (status);
253
254 #ifdef HAVE_GETRUSAGE
255       if (time != NULL && cpid >= 0)
256         {
257           getrusage (RUSAGE_CHILDREN, &r2);
258
259           pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec;
260           pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec;
261           if (pt.user_microseconds < 0)
262             {
263               --pt.user_seconds;
264               pt.user_microseconds += 1000000;
265             }
266
267           pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec;
268           pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec;
269           if (pt.system_microseconds < 0)
270             {
271               --pt.system_seconds;
272               pt.system_microseconds += 1000000;
273             }
274         }
275 #endif
276
277       if (cpid < 0 || cpid == pid)
278         {
279           if (time != NULL)
280             *time = pt;
281           return cpid;
282         }
283
284       psl = XNEW (struct status_list);
285       psl->pid = cpid;
286       psl->status = *status;
287       if (time != NULL)
288         psl->time = pt;
289       psl->next = (struct status_list *) obj->sysdep;
290       obj->sysdep = (void *) psl;
291     }
292 }
293
294 #endif /* ! defined (HAVE_WAITPID) */
295 #endif /* ! defined (HAVE_WAIT4) */
296
297 static void pex_child_error (struct pex_obj *, const char *, const char *, int)
298      ATTRIBUTE_NORETURN;
299 static int pex_unix_open_read (struct pex_obj *, const char *, int);
300 static int pex_unix_open_write (struct pex_obj *, const char *, int);
301 static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *,
302                                  char * const *, char * const *,
303                                  int, int, int, int,
304                                  const char **, int *);
305 static int pex_unix_close (struct pex_obj *, int);
306 static int pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *,
307                           int, const char **, int *);
308 static int pex_unix_pipe (struct pex_obj *, int *, int);
309 static FILE *pex_unix_fdopenr (struct pex_obj *, int, int);
310 static FILE *pex_unix_fdopenw (struct pex_obj *, int, int);
311 static void pex_unix_cleanup (struct pex_obj *);
312
313 /* The list of functions we pass to the common routines.  */
314
315 const struct pex_funcs funcs =
316 {
317   pex_unix_open_read,
318   pex_unix_open_write,
319   pex_unix_exec_child,
320   pex_unix_close,
321   pex_unix_wait,
322   pex_unix_pipe,
323   pex_unix_fdopenr,
324   pex_unix_fdopenw,
325   pex_unix_cleanup
326 };
327
328 /* Return a newly initialized pex_obj structure.  */
329
330 struct pex_obj *
331 pex_init (int flags, const char *pname, const char *tempbase)
332 {
333   return pex_init_common (flags, pname, tempbase, &funcs);
334 }
335
336 /* Open a file for reading.  */
337
338 static int
339 pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
340                     int binary ATTRIBUTE_UNUSED)
341 {
342   return open (name, O_RDONLY);
343 }
344
345 /* Open a file for writing.  */
346
347 static int
348 pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name,
349                      int binary ATTRIBUTE_UNUSED)
350 {
351   /* Note that we can't use O_EXCL here because gcc may have already
352      created the temporary file via make_temp_file.  */
353   return open (name, O_WRONLY | O_CREAT | O_TRUNC, PUBLIC_MODE);
354 }
355
356 /* Close a file.  */
357
358 static int
359 pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
360 {
361   return close (fd);
362 }
363
364 /* Report an error from a child process.  We don't use stdio routines,
365    because we might be here due to a vfork call.  */
366
367 static void
368 pex_child_error (struct pex_obj *obj, const char *executable,
369                  const char *errmsg, int err)
370 {
371   int retval = 0;
372 #define writeerr(s) retval |= (write (STDERR_FILE_NO, s, strlen (s)) < 0)
373   writeerr (obj->pname);
374   writeerr (": error trying to exec '");
375   writeerr (executable);
376   writeerr ("': ");
377   writeerr (errmsg);
378   writeerr (": ");
379   writeerr (xstrerror (err));
380   writeerr ("\n");
381 #undef writeerr
382   /* Exit with -2 if the error output failed, too.  */
383   _exit (retval == 0 ? -1 : -2);
384 }
385
386 /* Execute a child.  */
387
388 extern char **environ;
389
390 static pid_t
391 pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
392                      char * const * argv, char * const * env,
393                      int in, int out, int errdes,
394                      int toclose, const char **errmsg, int *err)
395 {
396   pid_t pid;
397
398   /* We declare these to be volatile to avoid warnings from gcc about
399      them being clobbered by vfork.  */
400   volatile int sleep_interval;
401   volatile int retries;
402
403   /* We vfork and then set environ in the child before calling execvp.
404      This clobbers the parent's environ so we need to restore it.
405      It would be nice to use one of the exec* functions that takes an
406      environment as a parameter, but that may have portability issues.  */
407   char **save_environ = environ;
408
409   sleep_interval = 1;
410   pid = -1;
411   for (retries = 0; retries < 4; ++retries)
412     {
413       pid = vfork ();
414       if (pid >= 0)
415         break;
416       sleep (sleep_interval);
417       sleep_interval *= 2;
418     }
419
420   switch (pid)
421     {
422     case -1:
423       *err = errno;
424       *errmsg = VFORK_STRING;
425       return (pid_t) -1;
426
427     case 0:
428       /* Child process.  */
429       if (in != STDIN_FILE_NO)
430         {
431           if (dup2 (in, STDIN_FILE_NO) < 0)
432             pex_child_error (obj, executable, "dup2", errno);
433           if (close (in) < 0)
434             pex_child_error (obj, executable, "close", errno);
435         }
436       if (out != STDOUT_FILE_NO)
437         {
438           if (dup2 (out, STDOUT_FILE_NO) < 0)
439             pex_child_error (obj, executable, "dup2", errno);
440           if (close (out) < 0)
441             pex_child_error (obj, executable, "close", errno);
442         }
443       if (errdes != STDERR_FILE_NO)
444         {
445           if (dup2 (errdes, STDERR_FILE_NO) < 0)
446             pex_child_error (obj, executable, "dup2", errno);
447           if (close (errdes) < 0)
448             pex_child_error (obj, executable, "close", errno);
449         }
450       if (toclose >= 0)
451         {
452           if (close (toclose) < 0)
453             pex_child_error (obj, executable, "close", errno);
454         }
455       if ((flags & PEX_STDERR_TO_STDOUT) != 0)
456         {
457           if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
458             pex_child_error (obj, executable, "dup2", errno);
459         }
460
461       if (env)
462         {
463           /* NOTE: In a standard vfork implementation this clobbers the
464              parent's copy of environ "too" (in reality there's only one copy).
465              This is ok as we restore it below.  */
466           environ = (char**) env;
467         }
468
469       if ((flags & PEX_SEARCH) != 0)
470         {
471           execvp (executable, to_ptr32 (argv));
472           pex_child_error (obj, executable, "execvp", errno);
473         }
474       else
475         {
476           execv (executable, to_ptr32 (argv));
477           pex_child_error (obj, executable, "execv", errno);
478         }
479
480       /* NOTREACHED */
481       return (pid_t) -1;
482
483     default:
484       /* Parent process.  */
485
486       /* Restore environ.
487          Note that the parent either doesn't run until the child execs/exits
488          (standard vfork behaviour), or if it does run then vfork is behaving
489          more like fork.  In either case we needn't worry about clobbering
490          the child's copy of environ.  */
491       environ = save_environ;
492
493       if (in != STDIN_FILE_NO)
494         {
495           if (close (in) < 0)
496             {
497               *err = errno;
498               *errmsg = "close";
499               return (pid_t) -1;
500             }
501         }
502       if (out != STDOUT_FILE_NO)
503         {
504           if (close (out) < 0)
505             {
506               *err = errno;
507               *errmsg = "close";
508               return (pid_t) -1;
509             }
510         }
511       if (errdes != STDERR_FILE_NO)
512         {
513           if (close (errdes) < 0)
514             {
515               *err = errno;
516               *errmsg = "close";
517               return (pid_t) -1;
518             }
519         }
520
521       return pid;
522     }
523 }
524
525 /* Wait for a child process to complete.  */
526
527 static int
528 pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status,
529                struct pex_time *time, int done, const char **errmsg,
530                int *err)
531 {
532   /* If we are cleaning up when the caller didn't retrieve process
533      status for some reason, encourage the process to go away.  */
534   if (done)
535     kill (pid, SIGTERM);
536
537   if (pex_wait (obj, pid, status, time) < 0)
538     {
539       *err = errno;
540       *errmsg = "wait";
541       return -1;
542     }
543
544   return 0;
545 }
546
547 /* Create a pipe.  */
548
549 static int
550 pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p,
551                int binary ATTRIBUTE_UNUSED)
552 {
553   return pipe (p);
554 }
555
556 /* Get a FILE pointer to read from a file descriptor.  */
557
558 static FILE *
559 pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
560                   int binary ATTRIBUTE_UNUSED)
561 {
562   return fdopen (fd, "r");
563 }
564
565 static FILE *
566 pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
567                   int binary ATTRIBUTE_UNUSED)
568 {
569   if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
570     return NULL;
571   return fdopen (fd, "w");
572 }
573
574 static void
575 pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED)
576 {
577 #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID)
578   while (obj->sysdep != NULL)
579     {
580       struct status_list *this;
581       struct status_list *next;
582
583       this = (struct status_list *) obj->sysdep;
584       next = this->next;
585       free (this);
586       obj->sysdep = (void *) next;
587     }
588 #endif
589 }