OSDN Git Service

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