OSDN Git Service

* pexecute.c (pexecute): Fill in temp_base when needed.
[pf3gnuchains/gcc-fork.git] / libiberty / pexecute.c
1 /* Utilities to execute a program in a subprocess (possibly linked by pipes
2    with other subprocesses), and wait for it.
3    Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
4
5 This file is part of the libiberty library.
6 Libiberty is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 Libiberty is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with libiberty; see the file COPYING.LIB.  If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* This file exports two functions: pexecute and pwait.  */
22
23 /* This file lives in at least two places: libiberty and gcc.
24    Don't change one without the other.  */
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <stdio.h>
31 #include <errno.h>
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 #define ISSPACE (x) isspace(x)
36 #ifdef HAVE_SYS_WAIT_H
37 #include <sys/wait.h>
38 #endif
39
40 #ifdef vfork /* Autoconf may define this to fork for us. */
41 # define VFORK_STRING "fork"
42 #else
43 # define VFORK_STRING "vfork"
44 #endif
45 #ifdef HAVE_VFORK_H
46 #include <vfork.h>
47 #endif
48 #ifdef VMS
49 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
50                lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
51 #endif /* VMS */
52
53 #include "libiberty.h"
54
55 /* stdin file number.  */
56 #define STDIN_FILE_NO 0
57
58 /* stdout file number.  */
59 #define STDOUT_FILE_NO 1
60
61 /* value of `pipe': port index for reading.  */
62 #define READ_PORT 0
63
64 /* value of `pipe': port index for writing.  */
65 #define WRITE_PORT 1
66
67 static char *install_error_msg = "installation problem, cannot exec `%s'";
68
69 /* pexecute: execute a program.
70
71    PROGRAM and ARGV are the arguments to execv/execvp.
72
73    THIS_PNAME is name of the calling program (i.e. argv[0]).
74
75    TEMP_BASE is the path name, sans suffix, of a temporary file to use
76    if needed.  This is currently only needed for MSDOS ports that don't use
77    GO32 (do any still exist?).  Ports that don't need it can pass NULL.
78
79    (FLAGS & PEXECUTE_SEARCH) is non-zero if $PATH should be searched
80    (??? It's not clear that GCC passes this flag correctly).
81    (FLAGS & PEXECUTE_FIRST) is nonzero for the first process in chain.
82    (FLAGS & PEXECUTE_FIRST) is nonzero for the last process in chain.
83    FIRST_LAST could be simplified to only mark the last of a chain of processes
84    but that requires the caller to always mark the last one (and not give up
85    early if some error occurs).  It's more robust to require the caller to
86    mark both ends of the chain.
87
88    The result is the pid on systems like Unix where we fork/exec and on systems
89    like WIN32 and OS2 where we use spawn.  It is up to the caller to wait for
90    the child.
91
92    The result is the WEXITSTATUS on systems like MSDOS where we spawn and wait
93    for the child here.
94
95    Upon failure, ERRMSG_FMT and ERRMSG_ARG are set to the text of the error
96    message with an optional argument (if not needed, ERRMSG_ARG is set to
97    NULL), and -1 is returned.  `errno' is available to the caller to use.
98
99    pwait: cover function for wait.
100
101    PID is the process id of the task to wait for.
102    STATUS is the `status' argument to wait.
103    FLAGS is currently unused (allows future enhancement without breaking
104    upward compatibility).  Pass 0 for now.
105
106    The result is the pid of the child reaped,
107    or -1 for failure (errno says why).
108
109    On systems that don't support waiting for a particular child, PID is
110    ignored.  On systems like MSDOS that don't really multitask pwait
111    is just a mechanism to provide a consistent interface for the caller.
112
113    pfinish: finish generation of script
114
115    pfinish is necessary for systems like MPW where a script is generated that
116    runs the requested programs.
117 */
118
119 #ifdef __MSDOS__
120
121 /* MSDOS doesn't multitask, but for the sake of a consistent interface
122    the code behaves like it does.  pexecute runs the program, tucks the
123    exit code away, and returns a "pid".  pwait must be called to fetch the
124    exit code.  */
125
126 #include <process.h>
127
128 /* For communicating information from pexecute to pwait.  */
129 static int last_pid = 0;
130 static int last_status = 0;
131 static int last_reaped = 0;
132
133 int
134 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
135      const char *program;
136      char * const *argv;
137      const char *this_pname;
138      const char *temp_base;
139      char **errmsg_fmt, **errmsg_arg;
140      int flags;
141 {
142   int rc;
143
144   last_pid++;
145   if (last_pid < 0)
146     last_pid = 1;
147
148   if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
149     abort ();
150
151 #ifdef __GO32__
152   /* ??? What are the possible return values from spawnv?  */
153   rc = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
154 #else
155   char *scmd, *rf;
156   FILE *argfile;
157   int i, el = flags & PEXECUTE_SEARCH ? 4 : 0;
158
159   if (temp_base == 0)
160     temp_base = choose_temp_base ();
161   scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el);
162   rf = scmd + strlen(program) + 2 + el;
163   sprintf (scmd, "%s%s @%s.gp", program,
164            (flags & PEXECUTE_SEARCH ? ".exe" : ""), temp_base);
165   argfile = fopen (rf, "w");
166   if (argfile == 0)
167     {
168       int errno_save = errno;
169       free (scmd);
170       errno = errno_save;
171       *errmsg_fmt = "cannot open `%s.gp'";
172       *errmsg_arg = temp_base;
173       return -1;
174     }
175
176   for (i=1; argv[i]; i++)
177     {
178       char *cp;
179       for (cp = argv[i]; *cp; cp++)
180         {
181           if (*cp == '"' || *cp == '\'' || *cp == '\\' || ISSPACE (*cp))
182             fputc ('\\', argfile);
183           fputc (*cp, argfile);
184         }
185       fputc ('\n', argfile);
186     }
187   fclose (argfile);
188
189   rc = system (scmd);
190
191   {
192     int errno_save = errno;
193     remove (rf);
194     free (scmd);
195     errno = errno_save;
196   }
197 #endif
198
199   if (rc == -1)
200     {
201       *errmsg_fmt = install_error_msg;
202       *errmsg_arg = program;
203       return -1;
204     }
205
206   /* Tuck the status away for pwait, and return a "pid".  */
207   last_status = rc << 8;
208   return last_pid;
209 }
210
211 int
212 pwait (pid, status, flags)
213      int pid;
214      int *status;
215      int flags;
216 {
217   /* On MSDOS each pexecute must be followed by it's associated pwait.  */
218   if (pid != last_pid
219       /* Called twice for the same child?  */
220       || pid == last_reaped)
221     {
222       /* ??? ECHILD would be a better choice.  Can we use it here?  */
223       errno = EINVAL;
224       return -1;
225     }
226   /* ??? Here's an opportunity to canonicalize the values in STATUS.
227      Needed?  */
228   *status = last_status;
229   last_reaped = last_pid;
230   return last_pid;
231 }
232
233 #endif /* MSDOS */
234
235 #if defined (_WIN32) && ! defined (_UWIN)
236
237 #include <process.h>
238
239 #ifdef __CYGWIN__
240
241 #define fix_argv(argvec) (argvec)
242
243 extern int _spawnv ();
244 extern int _spawnvp ();
245
246 #else /* ! __CYGWIN__ */
247
248 /* This is a kludge to get around the Microsoft C spawn functions' propensity
249    to remove the outermost set of double quotes from all arguments.  */
250
251 const char * const *
252 fix_argv (argvec)
253      char **argvec;
254 {
255   int i;
256
257   for (i = 1; argvec[i] != 0; i++)
258     {
259       int len, j;
260       char *temp, *newtemp;
261
262       temp = argvec[i];
263       len = strlen (temp);
264       for (j = 0; j < len; j++)
265         {
266           if (temp[j] == '"')
267             {
268               newtemp = xmalloc (len + 2);
269               strncpy (newtemp, temp, j);
270               newtemp [j] = '\\';
271               strncpy (&newtemp [j+1], &temp [j], len-j);
272               newtemp [len+1] = 0;
273               temp = newtemp;
274               len++;
275               j++;
276             }
277         }
278
279         argvec[i] = temp;
280       }
281
282   return (const char * const *) argvec;
283 }
284 #endif /* __CYGWIN__ */
285
286 #include <io.h>
287 #include <fcntl.h>
288 #include <signal.h>
289
290 /* mingw32 headers may not define the following.  */
291
292 #ifndef _P_WAIT
293 #  define _P_WAIT       0
294 #  define _P_NOWAIT     1
295 #  define _P_OVERLAY    2
296 #  define _P_NOWAITO    3
297 #  define _P_DETACH     4
298
299 #  define WAIT_CHILD    0
300 #  define WAIT_GRANDCHILD       1
301 #endif
302
303 /* Win32 supports pipes */
304 int
305 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
306      const char *program;
307      char * const *argv;
308      const char *this_pname;
309      const char *temp_base;
310      char **errmsg_fmt, **errmsg_arg;
311      int flags;
312 {
313   int pid;
314   int pdes[2], org_stdin, org_stdout;
315   int input_desc, output_desc;
316   int retries, sleep_interval;
317
318   /* Pipe waiting from last process, to be used as input for the next one.
319      Value is STDIN_FILE_NO if no pipe is waiting
320      (i.e. the next command is the first of a group).  */
321   static int last_pipe_input;
322
323   /* If this is the first process, initialize.  */
324   if (flags & PEXECUTE_FIRST)
325     last_pipe_input = STDIN_FILE_NO;
326
327   input_desc = last_pipe_input;
328
329   /* If this isn't the last process, make a pipe for its output,
330      and record it as waiting to be the input to the next process.  */
331   if (! (flags & PEXECUTE_LAST))
332     {
333       if (_pipe (pdes, 256, O_BINARY) < 0)
334         {
335           *errmsg_fmt = "pipe";
336           *errmsg_arg = NULL;
337           return -1;
338         }
339       output_desc = pdes[WRITE_PORT];
340       last_pipe_input = pdes[READ_PORT];
341     }
342   else
343     {
344       /* Last process.  */
345       output_desc = STDOUT_FILE_NO;
346       last_pipe_input = STDIN_FILE_NO;
347     }
348
349   if (input_desc != STDIN_FILE_NO)
350     {
351       org_stdin = dup (STDIN_FILE_NO);
352       dup2 (input_desc, STDIN_FILE_NO);
353       close (input_desc); 
354     }
355
356   if (output_desc != STDOUT_FILE_NO)
357     {
358       org_stdout = dup (STDOUT_FILE_NO);
359       dup2 (output_desc, STDOUT_FILE_NO);
360       close (output_desc);
361     }
362
363   pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
364     (_P_NOWAIT, program, fix_argv(argv));
365
366   if (input_desc != STDIN_FILE_NO)
367     {
368       dup2 (org_stdin, STDIN_FILE_NO);
369       close (org_stdin);
370     }
371
372   if (output_desc != STDOUT_FILE_NO)
373     {
374       dup2 (org_stdout, STDOUT_FILE_NO);
375       close (org_stdout);
376     }
377
378   if (pid == -1)
379     {
380       *errmsg_fmt = install_error_msg;
381       *errmsg_arg = program;
382       return -1;
383     }
384
385   return pid;
386 }
387
388 /* MS CRTDLL doesn't return enough information in status to decide if the
389    child exited due to a signal or not, rather it simply returns an
390    integer with the exit code of the child; eg., if the child exited with 
391    an abort() call and didn't have a handler for SIGABRT, it simply returns
392    with status = 3. We fix the status code to conform to the usual WIF*
393    macros. Note that WIFSIGNALED will never be true under CRTDLL. */
394
395 int
396 pwait (pid, status, flags)
397      int pid;
398      int *status;
399      int flags;
400 {
401 #ifdef __CYGWIN__
402   return wait (status);
403 #else
404   int termstat;
405
406   pid = _cwait (&termstat, pid, WAIT_CHILD);
407
408   /* ??? Here's an opportunity to canonicalize the values in STATUS.
409      Needed?  */
410
411   /* cwait returns the child process exit code in termstat.
412      A value of 3 indicates that the child caught a signal, but not
413      which one.  Since only SIGABRT, SIGFPE and SIGINT do anything, we
414      report SIGABRT.  */
415   if (termstat == 3)
416     *status = SIGABRT;
417   else
418     *status = (((termstat) & 0xff) << 8);
419
420   return pid;
421 #endif /* __CYGWIN__ */
422 }
423
424 #endif /* _WIN32 && ! _UWIN */
425
426 #ifdef OS2
427
428 /* ??? Does OS2 have process.h?  */
429 extern int spawnv ();
430 extern int spawnvp ();
431
432 int
433 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
434      const char *program;
435      char * const *argv;
436      const char *this_pname;
437      const char *temp_base;
438      char **errmsg_fmt, **errmsg_arg;
439      int flags;
440 {
441   int pid;
442
443   if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
444     abort ();
445   /* ??? Presumably 1 == _P_NOWAIT.  */
446   pid = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
447   if (pid == -1)
448     {
449       *errmsg_fmt = install_error_msg;
450       *errmsg_arg = program;
451       return -1;
452     }
453   return pid;
454 }
455
456 int
457 pwait (pid, status, flags)
458      int pid;
459      int *status;
460      int flags;
461 {
462   /* ??? Here's an opportunity to canonicalize the values in STATUS.
463      Needed?  */
464   int pid = wait (status);
465   return pid;
466 }
467
468 #endif /* OS2 */
469
470 #ifdef MPW
471
472 /* MPW pexecute doesn't actually run anything; instead, it writes out
473    script commands that, when run, will do the actual executing.
474
475    For example, in GCC's case, GCC will write out several script commands:
476
477    cpp ...
478    cc1 ...
479    as ...
480    ld ...
481
482    and then exit.  None of the above programs will have run yet.  The task
483    that called GCC will then execute the script and cause cpp,etc. to run.
484    The caller must invoke pfinish before calling exit.  This adds
485    the finishing touches to the generated script.  */
486
487 static int first_time = 1;
488
489 int
490 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
491      const char *program;
492      char * const *argv;
493      const char *this_pname;
494      const char *temp_base;
495      char **errmsg_fmt, **errmsg_arg;
496      int flags;
497 {
498   char tmpprogram[255];
499   char *cp, *tmpname;
500   int i;
501
502   mpwify_filename (program, tmpprogram);
503   if (first_time)
504     {
505       printf ("Set Failed 0\n");
506       first_time = 0;
507     }
508
509   fputs ("If {Failed} == 0\n", stdout);
510   /* If being verbose, output a copy of the command.  It should be
511      accurate enough and escaped enough to be "clickable".  */
512   if (flags & PEXECUTE_VERBOSE)
513     {
514       fputs ("\tEcho ", stdout);
515       fputc ('\'', stdout);
516       fputs (tmpprogram, stdout);
517       fputc ('\'', stdout);
518       fputc (' ', stdout);
519       for (i=1; argv[i]; i++)
520         {
521           fputc ('\'', stdout);
522           /* See if we have an argument that needs fixing.  */
523           if (strchr(argv[i], '/'))
524             {
525               tmpname = (char *) xmalloc (256);
526               mpwify_filename (argv[i], tmpname);
527               argv[i] = tmpname;
528             }
529           for (cp = argv[i]; *cp; cp++)
530             {
531               /* Write an Option-d escape char in front of special chars.  */
532               if (strchr("'+", *cp))
533                 fputc ('\266', stdout);
534               fputc (*cp, stdout);
535             }
536           fputc ('\'', stdout);
537           fputc (' ', stdout);
538         }
539       fputs ("\n", stdout);
540     }
541   fputs ("\t", stdout);
542   fputs (tmpprogram, stdout);
543   fputc (' ', stdout);
544
545   for (i=1; argv[i]; i++)
546     {
547       /* See if we have an argument that needs fixing.  */
548       if (strchr(argv[i], '/'))
549         {
550           tmpname = (char *) xmalloc (256);
551           mpwify_filename (argv[i], tmpname);
552           argv[i] = tmpname;
553         }
554       if (strchr (argv[i], ' '))
555         fputc ('\'', stdout);
556       for (cp = argv[i]; *cp; cp++)
557         {
558           /* Write an Option-d escape char in front of special chars.  */
559           if (strchr("'+", *cp))
560             fputc ('\266', stdout);
561           fputc (*cp, stdout);
562         }
563       if (strchr (argv[i], ' '))
564         fputc ('\'', stdout);
565       fputc (' ', stdout);
566     }
567
568   fputs ("\n", stdout);
569
570   /* Output commands that arrange to clean up and exit if a failure occurs.
571      We have to be careful to collect the status from the program that was
572      run, rather than some other script command.  Also, we don't exit
573      immediately, since necessary cleanups are at the end of the script.  */
574   fputs ("\tSet TmpStatus {Status}\n", stdout);
575   fputs ("\tIf {TmpStatus} != 0\n", stdout);
576   fputs ("\t\tSet Failed {TmpStatus}\n", stdout);
577   fputs ("\tEnd\n", stdout);
578   fputs ("End\n", stdout);
579
580   /* We're just composing a script, can't fail here.  */
581   return 0;
582 }
583
584 int
585 pwait (pid, status, flags)
586      int pid;
587      int *status;
588      int flags;
589 {
590   *status = 0;
591   return 0;
592 }
593
594 /* Write out commands that will exit with the correct error code
595    if something in the script failed.  */
596
597 void
598 pfinish ()
599 {
600   printf ("\tExit \"{Failed}\"\n");
601 }
602
603 #endif /* MPW */
604
605 /* include for Unix-like environments but not for Dos-like environments */
606 #if ! defined (__MSDOS__) && ! defined (OS2) && ! defined (MPW) \
607     && ! (defined (_WIN32) && ! defined (_UWIN))
608
609 extern int execv ();
610 extern int execvp ();
611
612 int
613 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
614      const char *program;
615      char * const *argv;
616      const char *this_pname;
617      const char *temp_base;
618      char **errmsg_fmt, **errmsg_arg;
619      int flags;
620 {
621   int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
622   int pid;
623   int pdes[2];
624   int input_desc, output_desc;
625   int retries, sleep_interval;
626   /* Pipe waiting from last process, to be used as input for the next one.
627      Value is STDIN_FILE_NO if no pipe is waiting
628      (i.e. the next command is the first of a group).  */
629   static int last_pipe_input;
630
631   /* If this is the first process, initialize.  */
632   if (flags & PEXECUTE_FIRST)
633     last_pipe_input = STDIN_FILE_NO;
634
635   input_desc = last_pipe_input;
636
637   /* If this isn't the last process, make a pipe for its output,
638      and record it as waiting to be the input to the next process.  */
639   if (! (flags & PEXECUTE_LAST))
640     {
641       if (pipe (pdes) < 0)
642         {
643           *errmsg_fmt = "pipe";
644           *errmsg_arg = NULL;
645           return -1;
646         }
647       output_desc = pdes[WRITE_PORT];
648       last_pipe_input = pdes[READ_PORT];
649     }
650   else
651     {
652       /* Last process.  */
653       output_desc = STDOUT_FILE_NO;
654       last_pipe_input = STDIN_FILE_NO;
655     }
656
657   /* Fork a subprocess; wait and retry if it fails.  */
658   sleep_interval = 1;
659   for (retries = 0; retries < 4; retries++)
660     {
661       pid = vfork ();
662       if (pid >= 0)
663         break;
664       sleep (sleep_interval);
665       sleep_interval *= 2;
666     }
667
668   switch (pid)
669     {
670     case -1:
671       {
672         *errmsg_fmt = VFORK_STRING;
673         *errmsg_arg = NULL;
674         return -1;
675       }
676
677     case 0: /* child */
678       /* Move the input and output pipes into place, if necessary.  */
679       if (input_desc != STDIN_FILE_NO)
680         {
681           close (STDIN_FILE_NO);
682           dup (input_desc);
683           close (input_desc);
684         }
685       if (output_desc != STDOUT_FILE_NO)
686         {
687           close (STDOUT_FILE_NO);
688           dup (output_desc);
689           close (output_desc);
690         }
691
692       /* Close the parent's descs that aren't wanted here.  */
693       if (last_pipe_input != STDIN_FILE_NO)
694         close (last_pipe_input);
695
696       /* Exec the program.  */
697       (*func) (program, argv);
698
699       /* Note: Calling fprintf and exit here doesn't seem right for vfork.  */
700       fprintf (stderr, "%s: ", this_pname);
701       fprintf (stderr, install_error_msg, program);
702       fprintf (stderr, ": %s\n", xstrerror (errno));
703       exit (-1);
704       /* NOTREACHED */
705       return 0;
706
707     default:
708       /* In the parent, after forking.
709          Close the descriptors that we made for this child.  */
710       if (input_desc != STDIN_FILE_NO)
711         close (input_desc);
712       if (output_desc != STDOUT_FILE_NO)
713         close (output_desc);
714
715       /* Return child's process number.  */
716       return pid;
717     }
718 }
719
720 int
721 pwait (pid, status, flags)
722      int pid;
723      int *status;
724      int flags;
725 {
726   /* ??? Here's an opportunity to canonicalize the values in STATUS.
727      Needed?  */
728 #ifdef VMS
729   pid = waitpid (-1, status, 0);
730 #else
731   pid = wait (status);
732 #endif
733   return pid;
734 }
735
736 #endif /* ! __MSDOS__ && ! OS2 && ! MPW && ! (_WIN32 && ! _UWIN) */