OSDN Git Service

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