OSDN Git Service

* choose-temp.c: Don't check IN_GCC anymore.
[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   scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el);
160   rf = scmd + strlen(program) + 2 + el;
161   sprintf (scmd, "%s%s @%s.gp", program,
162            (flags & PEXECUTE_SEARCH ? ".exe" : ""), temp_base);
163   argfile = fopen (rf, "w");
164   if (argfile == 0)
165     {
166       int errno_save = errno;
167       free (scmd);
168       errno = errno_save;
169       *errmsg_fmt = "cannot open `%s.gp'";
170       *errmsg_arg = temp_base;
171       return -1;
172     }
173
174   for (i=1; argv[i]; i++)
175     {
176       char *cp;
177       for (cp = argv[i]; *cp; cp++)
178         {
179           if (*cp == '"' || *cp == '\'' || *cp == '\\' || ISSPACE (*cp))
180             fputc ('\\', argfile);
181           fputc (*cp, argfile);
182         }
183       fputc ('\n', argfile);
184     }
185   fclose (argfile);
186
187   rc = system (scmd);
188
189   {
190     int errno_save = errno;
191     remove (rf);
192     free (scmd);
193     errno = errno_save;
194   }
195 #endif
196
197   if (rc == -1)
198     {
199       *errmsg_fmt = install_error_msg;
200       *errmsg_arg = program;
201       return -1;
202     }
203
204   /* Tuck the status away for pwait, and return a "pid".  */
205   last_status = rc << 8;
206   return last_pid;
207 }
208
209 int
210 pwait (pid, status, flags)
211      int pid;
212      int *status;
213      int flags;
214 {
215   /* On MSDOS each pexecute must be followed by it's associated pwait.  */
216   if (pid != last_pid
217       /* Called twice for the same child?  */
218       || pid == last_reaped)
219     {
220       /* ??? ECHILD would be a better choice.  Can we use it here?  */
221       errno = EINVAL;
222       return -1;
223     }
224   /* ??? Here's an opportunity to canonicalize the values in STATUS.
225      Needed?  */
226   *status = last_status;
227   last_reaped = last_pid;
228   return last_pid;
229 }
230
231 #endif /* MSDOS */
232
233 #if defined (_WIN32)
234
235 #include <process.h>
236
237 #ifdef __CYGWIN32__
238
239 #define fix_argv(argvec) (argvec)
240
241 extern int _spawnv ();
242 extern int _spawnvp ();
243
244 #else /* ! __CYGWIN32__ */
245
246 /* This is a kludge to get around the Microsoft C spawn functions' propensity
247    to remove the outermost set of double quotes from all arguments.  */
248
249 const char * const *
250 fix_argv (argvec)
251      char **argvec;
252 {
253   int i;
254
255   for (i = 1; argvec[i] != 0; i++)
256     {
257       int len, j;
258       char *temp, *newtemp;
259
260       temp = argvec[i];
261       len = strlen (temp);
262       for (j = 0; j < len; j++)
263         {
264           if (temp[j] == '"')
265             {
266               newtemp = xmalloc (len + 2);
267               strncpy (newtemp, temp, j);
268               newtemp [j] = '\\';
269               strncpy (&newtemp [j+1], &temp [j], len-j);
270               newtemp [len+1] = 0;
271               temp = newtemp;
272               len++;
273               j++;
274             }
275         }
276
277         argvec[i] = temp;
278       }
279
280   return (const char * const *) argvec;
281 }
282 #endif /* __CYGWIN32__ */
283
284 #include <io.h>
285 #include <fcntl.h>
286 #include <signal.h>
287
288 /* mingw32 headers may not define the following.  */
289
290 #ifndef _P_WAIT
291 #  define _P_WAIT       0
292 #  define _P_NOWAIT     1
293 #  define _P_OVERLAY    2
294 #  define _P_NOWAITO    3
295 #  define _P_DETACH     4
296
297 #  define WAIT_CHILD    0
298 #  define WAIT_GRANDCHILD       1
299 #endif
300
301 /* Win32 supports pipes */
302 int
303 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
304      const char *program;
305      char * const *argv;
306      const char *this_pname;
307      const char *temp_base;
308      char **errmsg_fmt, **errmsg_arg;
309      int flags;
310 {
311   int pid;
312   int pdes[2], org_stdin, org_stdout;
313   int input_desc, output_desc;
314   int retries, sleep_interval;
315
316   /* Pipe waiting from last process, to be used as input for the next one.
317      Value is STDIN_FILE_NO if no pipe is waiting
318      (i.e. the next command is the first of a group).  */
319   static int last_pipe_input;
320
321   /* If this is the first process, initialize.  */
322   if (flags & PEXECUTE_FIRST)
323     last_pipe_input = STDIN_FILE_NO;
324
325   input_desc = last_pipe_input;
326
327   /* If this isn't the last process, make a pipe for its output,
328      and record it as waiting to be the input to the next process.  */
329   if (! (flags & PEXECUTE_LAST))
330     {
331       if (_pipe (pdes, 256, O_BINARY) < 0)
332         {
333           *errmsg_fmt = "pipe";
334           *errmsg_arg = NULL;
335           return -1;
336         }
337       output_desc = pdes[WRITE_PORT];
338       last_pipe_input = pdes[READ_PORT];
339     }
340   else
341     {
342       /* Last process.  */
343       output_desc = STDOUT_FILE_NO;
344       last_pipe_input = STDIN_FILE_NO;
345     }
346
347   if (input_desc != STDIN_FILE_NO)
348     {
349       org_stdin = dup (STDIN_FILE_NO);
350       dup2 (input_desc, STDIN_FILE_NO);
351       close (input_desc); 
352     }
353
354   if (output_desc != STDOUT_FILE_NO)
355     {
356       org_stdout = dup (STDOUT_FILE_NO);
357       dup2 (output_desc, STDOUT_FILE_NO);
358       close (output_desc);
359     }
360
361   pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
362     (_P_NOWAIT, program, fix_argv(argv));
363
364   if (input_desc != STDIN_FILE_NO)
365     {
366       dup2 (org_stdin, STDIN_FILE_NO);
367       close (org_stdin);
368     }
369
370   if (output_desc != STDOUT_FILE_NO)
371     {
372       dup2 (org_stdout, STDOUT_FILE_NO);
373       close (org_stdout);
374     }
375
376   if (pid == -1)
377     {
378       *errmsg_fmt = install_error_msg;
379       *errmsg_arg = program;
380       return -1;
381     }
382
383   return pid;
384 }
385
386 /* MS CRTDLL doesn't return enough information in status to decide if the
387    child exited due to a signal or not, rather it simply returns an
388    integer with the exit code of the child; eg., if the child exited with 
389    an abort() call and didn't have a handler for SIGABRT, it simply returns
390    with status = 3. We fix the status code to conform to the usual WIF*
391    macros. Note that WIFSIGNALED will never be true under CRTDLL. */
392
393 int
394 pwait (pid, status, flags)
395      int pid;
396      int *status;
397      int flags;
398 {
399 #ifdef __CYGWIN32__
400   return wait (status);
401 #else
402   int termstat;
403
404   pid = _cwait (&termstat, pid, WAIT_CHILD);
405
406   /* ??? Here's an opportunity to canonicalize the values in STATUS.
407      Needed?  */
408
409   /* cwait returns the child process exit code in termstat.
410      A value of 3 indicates that the child caught a signal, but not
411      which one.  Since only SIGABRT, SIGFPE and SIGINT do anything, we
412      report SIGABRT.  */
413   if (termstat == 3)
414     *status = SIGABRT;
415   else
416     *status = (((termstat) & 0xff) << 8);
417
418   return pid;
419 #endif /* __CYGWIN32__ */
420 }
421
422 #endif /* _WIN32 */
423
424 #ifdef OS2
425
426 /* ??? Does OS2 have process.h?  */
427 extern int spawnv ();
428 extern int spawnvp ();
429
430 int
431 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
432      const char *program;
433      char * const *argv;
434      const char *this_pname;
435      const char *temp_base;
436      char **errmsg_fmt, **errmsg_arg;
437      int flags;
438 {
439   int pid;
440
441   if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
442     abort ();
443   /* ??? Presumably 1 == _P_NOWAIT.  */
444   pid = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
445   if (pid == -1)
446     {
447       *errmsg_fmt = install_error_msg;
448       *errmsg_arg = program;
449       return -1;
450     }
451   return pid;
452 }
453
454 int
455 pwait (pid, status, flags)
456      int pid;
457      int *status;
458      int flags;
459 {
460   /* ??? Here's an opportunity to canonicalize the values in STATUS.
461      Needed?  */
462   int pid = wait (status);
463   return pid;
464 }
465
466 #endif /* OS2 */
467
468 #ifdef MPW
469
470 /* MPW pexecute doesn't actually run anything; instead, it writes out
471    script commands that, when run, will do the actual executing.
472
473    For example, in GCC's case, GCC will write out several script commands:
474
475    cpp ...
476    cc1 ...
477    as ...
478    ld ...
479
480    and then exit.  None of the above programs will have run yet.  The task
481    that called GCC will then execute the script and cause cpp,etc. to run.
482    The caller must invoke pfinish before calling exit.  This adds
483    the finishing touches to the generated script.  */
484
485 static int first_time = 1;
486
487 int
488 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
489      const char *program;
490      char * const *argv;
491      const char *this_pname;
492      const char *temp_base;
493      char **errmsg_fmt, **errmsg_arg;
494      int flags;
495 {
496   char tmpprogram[255];
497   char *cp, *tmpname;
498   int i;
499
500   mpwify_filename (program, tmpprogram);
501   if (first_time)
502     {
503       printf ("Set Failed 0\n");
504       first_time = 0;
505     }
506
507   fputs ("If {Failed} == 0\n", stdout);
508   /* If being verbose, output a copy of the command.  It should be
509      accurate enough and escaped enough to be "clickable".  */
510   if (flags & PEXECUTE_VERBOSE)
511     {
512       fputs ("\tEcho ", stdout);
513       fputc ('\'', stdout);
514       fputs (tmpprogram, stdout);
515       fputc ('\'', stdout);
516       fputc (' ', stdout);
517       for (i=1; argv[i]; i++)
518         {
519           fputc ('\'', stdout);
520           /* See if we have an argument that needs fixing.  */
521           if (strchr(argv[i], '/'))
522             {
523               tmpname = (char *) xmalloc (256);
524               mpwify_filename (argv[i], tmpname);
525               argv[i] = tmpname;
526             }
527           for (cp = argv[i]; *cp; cp++)
528             {
529               /* Write an Option-d escape char in front of special chars.  */
530               if (strchr("'+", *cp))
531                 fputc ('\266', stdout);
532               fputc (*cp, stdout);
533             }
534           fputc ('\'', stdout);
535           fputc (' ', stdout);
536         }
537       fputs ("\n", stdout);
538     }
539   fputs ("\t", stdout);
540   fputs (tmpprogram, stdout);
541   fputc (' ', stdout);
542
543   for (i=1; argv[i]; i++)
544     {
545       /* See if we have an argument that needs fixing.  */
546       if (strchr(argv[i], '/'))
547         {
548           tmpname = (char *) xmalloc (256);
549           mpwify_filename (argv[i], tmpname);
550           argv[i] = tmpname;
551         }
552       if (strchr (argv[i], ' '))
553         fputc ('\'', stdout);
554       for (cp = argv[i]; *cp; cp++)
555         {
556           /* Write an Option-d escape char in front of special chars.  */
557           if (strchr("'+", *cp))
558             fputc ('\266', stdout);
559           fputc (*cp, stdout);
560         }
561       if (strchr (argv[i], ' '))
562         fputc ('\'', stdout);
563       fputc (' ', stdout);
564     }
565
566   fputs ("\n", stdout);
567
568   /* Output commands that arrange to clean up and exit if a failure occurs.
569      We have to be careful to collect the status from the program that was
570      run, rather than some other script command.  Also, we don't exit
571      immediately, since necessary cleanups are at the end of the script.  */
572   fputs ("\tSet TmpStatus {Status}\n", stdout);
573   fputs ("\tIf {TmpStatus} != 0\n", stdout);
574   fputs ("\t\tSet Failed {TmpStatus}\n", stdout);
575   fputs ("\tEnd\n", stdout);
576   fputs ("End\n", stdout);
577
578   /* We're just composing a script, can't fail here.  */
579   return 0;
580 }
581
582 int
583 pwait (pid, status, flags)
584      int pid;
585      int *status;
586      int flags;
587 {
588   *status = 0;
589   return 0;
590 }
591
592 /* Write out commands that will exit with the correct error code
593    if something in the script failed.  */
594
595 void
596 pfinish ()
597 {
598   printf ("\tExit \"{Failed}\"\n");
599 }
600
601 #endif /* MPW */
602
603 /* include for Unix-like environments but not for Dos-like environments */
604 #if ! defined (__MSDOS__) && ! defined (OS2) && ! defined (MPW) \
605     && ! defined (_WIN32)
606
607 extern int execv ();
608 extern int execvp ();
609
610 int
611 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
612      const char *program;
613      char * const *argv;
614      const char *this_pname;
615      const char *temp_base;
616      char **errmsg_fmt, **errmsg_arg;
617      int flags;
618 {
619   int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
620   int pid;
621   int pdes[2];
622   int input_desc, output_desc;
623   int retries, sleep_interval;
624   /* Pipe waiting from last process, to be used as input for the next one.
625      Value is STDIN_FILE_NO if no pipe is waiting
626      (i.e. the next command is the first of a group).  */
627   static int last_pipe_input;
628
629   /* If this is the first process, initialize.  */
630   if (flags & PEXECUTE_FIRST)
631     last_pipe_input = STDIN_FILE_NO;
632
633   input_desc = last_pipe_input;
634
635   /* If this isn't the last process, make a pipe for its output,
636      and record it as waiting to be the input to the next process.  */
637   if (! (flags & PEXECUTE_LAST))
638     {
639       if (pipe (pdes) < 0)
640         {
641           *errmsg_fmt = "pipe";
642           *errmsg_arg = NULL;
643           return -1;
644         }
645       output_desc = pdes[WRITE_PORT];
646       last_pipe_input = pdes[READ_PORT];
647     }
648   else
649     {
650       /* Last process.  */
651       output_desc = STDOUT_FILE_NO;
652       last_pipe_input = STDIN_FILE_NO;
653     }
654
655   /* Fork a subprocess; wait and retry if it fails.  */
656   sleep_interval = 1;
657   for (retries = 0; retries < 4; retries++)
658     {
659       pid = vfork ();
660       if (pid >= 0)
661         break;
662       sleep (sleep_interval);
663       sleep_interval *= 2;
664     }
665
666   switch (pid)
667     {
668     case -1:
669       {
670         *errmsg_fmt = VFORK_STRING;
671         *errmsg_arg = NULL;
672         return -1;
673       }
674
675     case 0: /* child */
676       /* Move the input and output pipes into place, if necessary.  */
677       if (input_desc != STDIN_FILE_NO)
678         {
679           close (STDIN_FILE_NO);
680           dup (input_desc);
681           close (input_desc);
682         }
683       if (output_desc != STDOUT_FILE_NO)
684         {
685           close (STDOUT_FILE_NO);
686           dup (output_desc);
687           close (output_desc);
688         }
689
690       /* Close the parent's descs that aren't wanted here.  */
691       if (last_pipe_input != STDIN_FILE_NO)
692         close (last_pipe_input);
693
694       /* Exec the program.  */
695       (*func) (program, argv);
696
697       /* Note: Calling fprintf and exit here doesn't seem right for vfork.  */
698       fprintf (stderr, "%s: ", this_pname);
699       fprintf (stderr, install_error_msg, program);
700       fprintf (stderr, ": %s\n", xstrerror (errno));
701       exit (-1);
702       /* NOTREACHED */
703       return 0;
704
705     default:
706       /* In the parent, after forking.
707          Close the descriptors that we made for this child.  */
708       if (input_desc != STDIN_FILE_NO)
709         close (input_desc);
710       if (output_desc != STDOUT_FILE_NO)
711         close (output_desc);
712
713       /* Return child's process number.  */
714       return pid;
715     }
716 }
717
718 int
719 pwait (pid, status, flags)
720      int pid;
721      int *status;
722      int flags;
723 {
724   /* ??? Here's an opportunity to canonicalize the values in STATUS.
725      Needed?  */
726 #ifdef VMS
727   pid = waitpid (-1, status, 0);
728 #else
729   pid = wait (status);
730 #endif
731   return pid;
732 }
733
734 #endif /* ! __MSDOS__ && ! OS2 && ! MPW && ! _WIN32 */