1 | /* Utilities to execute a program in a subprocess (possibly linked by pipes
|
---|
2 | with other subprocesses), and wait for it. MPW specialization.
|
---|
3 | Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
|
---|
4 | Free Software Foundation, Inc.
|
---|
5 |
|
---|
6 | This file is part of the libiberty library.
|
---|
7 | Libiberty is free software; you can redistribute it and/or
|
---|
8 | modify it under the terms of the GNU Library General Public
|
---|
9 | License as published by the Free Software Foundation; either
|
---|
10 | version 2 of the License, or (at your option) any later version.
|
---|
11 |
|
---|
12 | Libiberty is distributed in the hope that it will be useful,
|
---|
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
15 | Library General Public License for more details.
|
---|
16 |
|
---|
17 | You should have received a copy of the GNU Library General Public
|
---|
18 | License along with libiberty; see the file COPYING.LIB. If not,
|
---|
19 | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
---|
20 | Boston, MA 02111-1307, USA. */
|
---|
21 |
|
---|
22 | #include "pex-common.h"
|
---|
23 |
|
---|
24 | #include <stdio.h>
|
---|
25 | #ifdef HAVE_STRING_H
|
---|
26 | #include <string.h>
|
---|
27 | #endif
|
---|
28 |
|
---|
29 | /* MPW pexecute doesn't actually run anything; instead, it writes out
|
---|
30 | script commands that, when run, will do the actual executing.
|
---|
31 |
|
---|
32 | For example, in GCC's case, GCC will write out several script commands:
|
---|
33 |
|
---|
34 | cpp ...
|
---|
35 | cc1 ...
|
---|
36 | as ...
|
---|
37 | ld ...
|
---|
38 |
|
---|
39 | and then exit. None of the above programs will have run yet. The task
|
---|
40 | that called GCC will then execute the script and cause cpp,etc. to run.
|
---|
41 | The caller must invoke pfinish before calling exit. This adds
|
---|
42 | the finishing touches to the generated script. */
|
---|
43 |
|
---|
44 | static int first_time = 1;
|
---|
45 |
|
---|
46 | extern void mpwify_filename PARAMS ((const char *, char *));
|
---|
47 |
|
---|
48 | int
|
---|
49 | pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
|
---|
50 | const char *program;
|
---|
51 | char * const *argv;
|
---|
52 | const char *this_pname;
|
---|
53 | const char *temp_base;
|
---|
54 | char **errmsg_fmt, **errmsg_arg;
|
---|
55 | int flags;
|
---|
56 | {
|
---|
57 | char tmpprogram[255];
|
---|
58 | char *cp, *tmpname;
|
---|
59 | int i;
|
---|
60 |
|
---|
61 | mpwify_filename (program, tmpprogram);
|
---|
62 | if (first_time)
|
---|
63 | {
|
---|
64 | printf ("Set Failed 0\n");
|
---|
65 | first_time = 0;
|
---|
66 | }
|
---|
67 |
|
---|
68 | fputs ("If {Failed} == 0\n", stdout);
|
---|
69 | /* If being verbose, output a copy of the command. It should be
|
---|
70 | accurate enough and escaped enough to be "clickable". */
|
---|
71 | if (flags & PEXECUTE_VERBOSE)
|
---|
72 | {
|
---|
73 | fputs ("\tEcho ", stdout);
|
---|
74 | fputc ('\'', stdout);
|
---|
75 | fputs (tmpprogram, stdout);
|
---|
76 | fputc ('\'', stdout);
|
---|
77 | fputc (' ', stdout);
|
---|
78 | for (i=1; argv[i]; i++)
|
---|
79 | {
|
---|
80 | fputc ('\'', stdout);
|
---|
81 | /* See if we have an argument that needs fixing. */
|
---|
82 | if (strchr(argv[i], '/'))
|
---|
83 | {
|
---|
84 | tmpname = (char *) xmalloc (256);
|
---|
85 | mpwify_filename (argv[i], tmpname);
|
---|
86 | argv[i] = tmpname;
|
---|
87 | }
|
---|
88 | for (cp = argv[i]; *cp; cp++)
|
---|
89 | {
|
---|
90 | /* Write an Option-d escape char in front of special chars. */
|
---|
91 | if (strchr("'+", *cp))
|
---|
92 | fputc ('\266', stdout);
|
---|
93 | fputc (*cp, stdout);
|
---|
94 | }
|
---|
95 | fputc ('\'', stdout);
|
---|
96 | fputc (' ', stdout);
|
---|
97 | }
|
---|
98 | fputs ("\n", stdout);
|
---|
99 | }
|
---|
100 | fputs ("\t", stdout);
|
---|
101 | fputs (tmpprogram, stdout);
|
---|
102 | fputc (' ', stdout);
|
---|
103 |
|
---|
104 | for (i=1; argv[i]; i++)
|
---|
105 | {
|
---|
106 | /* See if we have an argument that needs fixing. */
|
---|
107 | if (strchr(argv[i], '/'))
|
---|
108 | {
|
---|
109 | tmpname = (char *) xmalloc (256);
|
---|
110 | mpwify_filename (argv[i], tmpname);
|
---|
111 | argv[i] = tmpname;
|
---|
112 | }
|
---|
113 | if (strchr (argv[i], ' '))
|
---|
114 | fputc ('\'', stdout);
|
---|
115 | for (cp = argv[i]; *cp; cp++)
|
---|
116 | {
|
---|
117 | /* Write an Option-d escape char in front of special chars. */
|
---|
118 | if (strchr("'+", *cp))
|
---|
119 | fputc ('\266', stdout);
|
---|
120 | fputc (*cp, stdout);
|
---|
121 | }
|
---|
122 | if (strchr (argv[i], ' '))
|
---|
123 | fputc ('\'', stdout);
|
---|
124 | fputc (' ', stdout);
|
---|
125 | }
|
---|
126 |
|
---|
127 | fputs ("\n", stdout);
|
---|
128 |
|
---|
129 | /* Output commands that arrange to clean up and exit if a failure occurs.
|
---|
130 | We have to be careful to collect the status from the program that was
|
---|
131 | run, rather than some other script command. Also, we don't exit
|
---|
132 | immediately, since necessary cleanups are at the end of the script. */
|
---|
133 | fputs ("\tSet TmpStatus {Status}\n", stdout);
|
---|
134 | fputs ("\tIf {TmpStatus} != 0\n", stdout);
|
---|
135 | fputs ("\t\tSet Failed {TmpStatus}\n", stdout);
|
---|
136 | fputs ("\tEnd\n", stdout);
|
---|
137 | fputs ("End\n", stdout);
|
---|
138 |
|
---|
139 | /* We're just composing a script, can't fail here. */
|
---|
140 | return 0;
|
---|
141 | }
|
---|
142 |
|
---|
143 | int
|
---|
144 | pwait (pid, status, flags)
|
---|
145 | int pid;
|
---|
146 | int *status;
|
---|
147 | int flags;
|
---|
148 | {
|
---|
149 | *status = 0;
|
---|
150 | return 0;
|
---|
151 | }
|
---|
152 |
|
---|
153 | /* Write out commands that will exit with the correct error code
|
---|
154 | if something in the script failed. */
|
---|
155 |
|
---|
156 | void
|
---|
157 | pfinish ()
|
---|
158 | {
|
---|
159 | printf ("\tExit \"{Failed}\"\n");
|
---|
160 | }
|
---|
161 |
|
---|