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 Free Software Foundation, Inc.
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.
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.
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. */
21 /* This file exports two functions: pexecute and pwait. */
23 /* This file lives in at least two places: libiberty and gcc.
24 Don't change one without the other. */
31 #include "gansidecl.h"
32 /* ??? Need to find a suitable header file. */
33 #define PEXECUTE_FIRST 1
34 #define PEXECUTE_LAST 2
35 #define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST)
36 #define PEXECUTE_SEARCH 4
38 #include "libiberty.h"
41 /* stdin file number. */
42 #define STDIN_FILE_NO 0
44 /* stdout file number. */
45 #define STDOUT_FILE_NO 1
47 /* value of `pipe': port index for reading. */
50 /* value of `pipe': port index for writing. */
53 static char *install_error_msg = "installation problem, cannot exec `%s'";
55 /* pexecute: execute a program.
57 PROGRAM and ARGV are the arguments to execv/execvp.
59 THIS_PNAME is name of the calling program (i.e. argv[0]).
61 TEMP_BASE is the path name, sans suffix, of a temporary file to use
62 if needed. This is currently only needed for MSDOS ports that don't use
63 GO32 (do any still exist?). Ports that don't need it can pass NULL.
65 (FLAGS & PEXECUTE_SEARCH) is non-zero if $PATH should be searched
66 (??? It's not clear that GCC passes this flag correctly).
67 (FLAGS & PEXECUTE_FIRST) is nonzero for the first process in chain.
68 (FLAGS & PEXECUTE_FIRST) is nonzero for the last process in chain.
69 FIRST_LAST could be simplified to only mark the last of a chain of processes
70 but that requires the caller to always mark the last one (and not give up
71 early if some error occurs). It's more robust to require the caller to
72 mark both ends of the chain.
74 The result is the pid on systems like Unix where we fork/exec and on systems
75 like WIN32 and OS2 where we use spawn. It is up to the caller to wait for
78 The result is the WEXITSTATUS on systems like MSDOS where we spawn and wait
81 Upon failure, ERRMSG_FMT and ERRMSG_ARG are set to the text of the error
82 message with an optional argument (if not needed, ERRMSG_ARG is set to
83 NULL), and -1 is returned. `errno' is available to the caller to use.
85 pwait: cover function for wait.
87 PID is the process id of the task to wait for.
88 STATUS is the `status' argument to wait.
89 FLAGS is currently unused (allows future enhancement without breaking
90 upward compatibility). Pass 0 for now.
92 The result is the pid of the child reaped,
93 or -1 for failure (errno says why).
95 On systems that don't support waiting for a particular child, PID is
96 ignored. On systems like MSDOS that don't really multitask pwait
97 is just a mechanism to provide a consistent interface for the caller.
99 pfinish: finish generation of script
101 pfinish is necessary for systems like MPW where a script is generated that
102 runs the requested programs.
107 /* MSDOS doesn't multitask, but for the sake of a consistent interface
108 the code behaves like it does. pexecute runs the program, tucks the
109 exit code away, and returns a "pid". pwait must be called to fetch the
114 /* For communicating information from pexecute to pwait. */
115 static int last_pid = 0;
116 static int last_status = 0;
117 static int last_reaped = 0;
120 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
123 const char *this_pname;
124 const char *temp_base;
125 char **errmsg_fmt, **errmsg_arg;
134 if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
138 /* ??? What are the possible return values from spawnv? */
139 rc = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
143 int i, el = flags & PEXECUTE_SEARCH ? 4 : 0;
145 scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el);
146 rf = scmd + strlen(program) + 2 + el;
147 sprintf (scmd, "%s%s @%s.gp", program,
148 (flags & PEXECUTE_SEARCH ? ".exe" : ""), temp_base);
149 argfile = fopen (rf, "w");
152 int errno_save = errno;
155 *errmsg_fmt = "cannot open `%s.gp'";
156 *errmsg_arg = temp_base;
160 for (i=1; argv[i]; i++)
163 for (cp = argv[i]; *cp; cp++)
165 if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
166 fputc ('\\', argfile);
167 fputc (*cp, argfile);
169 fputc ('\n', argfile);
176 int errno_save = errno;
185 *errmsg_fmt = install_error_msg;
186 *errmsg_arg = program;
190 /* Tuck the status away for pwait, and return a "pid". */
191 last_status = rc << 8;
196 pwait (pid, status, flags)
201 /* On MSDOS each pexecute must be followed by it's associated pwait. */
203 /* Called twice for the same child? */
204 || pid == last_reaped)
206 /* ??? ECHILD would be a better choice. Can we use it here? */
210 /* ??? Here's an opportunity to canonicalize the values in STATUS.
212 *status = last_status;
213 last_reaped = last_pid;
222 /* ??? Why are these __spawnv{,p} and not _spawnv{,p}? */
223 extern int __spawnv ();
224 extern int __spawnvp ();
227 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
230 const char *this_pname;
231 const char *temp_base;
232 char **errmsg_fmt, **errmsg_arg;
237 if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
239 pid = (flags & PEXECUTE_SEARCH ? __spawnvp : __spawnv) (_P_NOWAIT, program, argv);
242 *errmsg_fmt = install_error_msg;
243 *errmsg_arg = program;
250 pwait (pid, status, flags)
255 /* ??? Here's an opportunity to canonicalize the values in STATUS.
257 int pid = cwait (status, pid, WAIT_CHILD);
265 /* ??? Does OS2 have process.h? */
266 extern int spawnv ();
267 extern int spawnvp ();
270 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
273 const char *this_pname;
274 const char *temp_base;
275 char **errmsg_fmt, **errmsg_arg;
280 if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE)
282 /* ??? Presumably 1 == _P_NOWAIT. */
283 pid = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv);
286 *errmsg_fmt = install_error_msg;
287 *errmsg_arg = program;
294 pwait (pid, status, flags)
299 /* ??? Here's an opportunity to canonicalize the values in STATUS.
301 int pid = wait (status);
309 /* MPW pexecute doesn't actually run anything; instead, it writes out
310 script commands that, when run, will do the actual executing.
312 For example, in GCC's case, GCC will write out several script commands:
319 and then exit. None of the above programs will have run yet. The task
320 that called GCC will then execute the script and cause cpp,etc. to run.
321 The caller must invoke pfinish before calling exit. This adds
322 the finishing touches to the generated script. */
324 static int first_time = 1;
327 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
330 const char *this_pname;
331 const char *temp_base;
332 char **errmsg_fmt, **errmsg_arg;
335 char tmpprogram[255];
339 mpwify_filename (program, tmpprogram);
342 printf ("Set Failed 0\n");
346 fputs ("If {Failed} == 0\n", stdout);
347 /* If being verbose, output a copy of the command. It should be
348 accurate enough and escaped enough to be "clickable". */
351 fputs ("\tEcho ", stdout);
352 fputc ('\'', stdout);
353 fputs (tmpprogram, stdout);
354 fputc ('\'', stdout);
356 for (i=1; argv[i]; i++)
358 fputc ('\'', stdout);
359 /* See if we have an argument that needs fixing. */
360 if (strchr(argv[i], '/'))
362 tmpname = xmalloc (256);
363 mpwify_filename (argv[i], tmpname);
366 for (cp = argv[i]; *cp; cp++)
368 /* Write an Option-d escape char in front of special chars. */
369 if (strchr("'+", *cp))
370 fputc ('\266', stdout);
373 fputc ('\'', stdout);
376 fputs ("\n", stdout);
378 fputs ("\t", stdout);
379 fputs (tmpprogram, stdout);
382 for (i=1; argv[i]; i++)
384 /* See if we have an argument that needs fixing. */
385 if (strchr(argv[i], '/'))
387 tmpname = xmalloc (256);
388 mpwify_filename (argv[i], tmpname);
391 if (strchr (argv[i], ' '))
392 fputc ('\'', stdout);
393 for (cp = argv[i]; *cp; cp++)
395 /* Write an Option-d escape char in front of special chars. */
396 if (strchr("'+", *cp))
397 fputc ('\266', stdout);
400 if (strchr (argv[i], ' '))
401 fputc ('\'', stdout);
405 fputs ("\n", stdout);
407 /* Output commands that arrange to clean up and exit if a failure occurs.
408 We have to be careful to collect the status from the program that was
409 run, rather than some other script command. Also, we don't exit
410 immediately, since necessary cleanups are at the end of the script. */
411 fputs ("\tSet TmpStatus {Status}\n", stdout);
412 fputs ("\tIf {TmpStatus} != 0\n", stdout);
413 fputs ("\t\tSet Failed {TmpStatus}\n", stdout);
414 fputs ("\tEnd\n", stdout);
415 fputs ("End\n", stdout);
417 /* We're just composing a script, can't fail here. */
422 pwait (pid, status, flags)
431 /* Write out commands that will exit with the correct error code
432 if something in the script failed. */
437 printf ("\tExit \"{Failed}\"\n");
442 #if ! defined (__MSDOS__) && ! defined (_WIN32) && ! defined (OS2) \
450 extern int execvp ();
453 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
456 const char *this_pname;
457 const char *temp_base;
458 char **errmsg_fmt, **errmsg_arg;
461 int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
464 int input_desc, output_desc;
465 int retries, sleep_interval;
466 /* Pipe waiting from last process, to be used as input for the next one.
467 Value is STDIN_FILE_NO if no pipe is waiting
468 (i.e. the next command is the first of a group). */
469 static int last_pipe_input;
471 /* If this is the first process, initialize. */
472 if (flags & PEXECUTE_FIRST)
473 last_pipe_input = STDIN_FILE_NO;
475 input_desc = last_pipe_input;
477 /* If this isn't the last process, make a pipe for its output,
478 and record it as waiting to be the input to the next process. */
479 if (! (flags & PEXECUTE_LAST))
483 *errmsg_fmt = "pipe";
487 output_desc = pdes[WRITE_PORT];
488 last_pipe_input = pdes[READ_PORT];
493 output_desc = STDOUT_FILE_NO;
494 last_pipe_input = STDIN_FILE_NO;
497 /* Fork a subprocess; wait and retry if it fails. */
499 for (retries = 0; retries < 4; retries++)
504 sleep (sleep_interval);
513 *errmsg_fmt = "fork";
515 *errmsg_fmt = "vfork";
522 /* Move the input and output pipes into place, if necessary. */
523 if (input_desc != STDIN_FILE_NO)
525 close (STDIN_FILE_NO);
529 if (output_desc != STDOUT_FILE_NO)
531 close (STDOUT_FILE_NO);
536 /* Close the parent's descs that aren't wanted here. */
537 if (last_pipe_input != STDIN_FILE_NO)
538 close (last_pipe_input);
540 /* Exec the program. */
541 (*func) (program, argv);
543 /* Note: Calling fprintf and exit here doesn't seem right for vfork. */
544 fprintf (stderr, "%s: ", this_pname);
545 fprintf (stderr, install_error_msg, program);
547 fprintf (stderr, ": %s\n", my_strerror (errno));
549 fprintf (stderr, ": %s\n", xstrerror (errno));
556 /* In the parent, after forking.
557 Close the descriptors that we made for this child. */
558 if (input_desc != STDIN_FILE_NO)
560 if (output_desc != STDOUT_FILE_NO)
563 /* Return child's process number. */
569 pwait (pid, status, flags)
574 /* ??? Here's an opportunity to canonicalize the values in STATUS.
580 #endif /* !MSDOS && !WIN32 && !OS2 && !MPW */