Major cutover to using system.h:
[gcc.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();
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 */