Blame


1 76193d7c 2003-09-30 devnull #include "mk.h"
2 76193d7c 2003-09-30 devnull #include <sys/wait.h>
3 76193d7c 2003-09-30 devnull #include <signal.h>
4 76193d7c 2003-09-30 devnull #include <sys/stat.h>
5 76193d7c 2003-09-30 devnull #include <sys/time.h>
6 76193d7c 2003-09-30 devnull
7 76193d7c 2003-09-30 devnull char *shell = "/bin/sh";
8 76193d7c 2003-09-30 devnull char *shellname = "sh";
9 76193d7c 2003-09-30 devnull
10 76193d7c 2003-09-30 devnull extern char **environ;
11 76193d7c 2003-09-30 devnull
12 76193d7c 2003-09-30 devnull static void
13 76193d7c 2003-09-30 devnull mkperror(char *s)
14 76193d7c 2003-09-30 devnull {
15 76193d7c 2003-09-30 devnull fprint(2, "%s: %r\n", s);
16 76193d7c 2003-09-30 devnull }
17 76193d7c 2003-09-30 devnull
18 76193d7c 2003-09-30 devnull void
19 76193d7c 2003-09-30 devnull readenv(void)
20 76193d7c 2003-09-30 devnull {
21 76193d7c 2003-09-30 devnull char **p, *s;
22 76193d7c 2003-09-30 devnull Word *w;
23 76193d7c 2003-09-30 devnull
24 76193d7c 2003-09-30 devnull for(p = environ; *p; p++){
25 76193d7c 2003-09-30 devnull s = shname(*p);
26 76193d7c 2003-09-30 devnull if(*s == '=') {
27 76193d7c 2003-09-30 devnull *s = 0;
28 76193d7c 2003-09-30 devnull w = newword(s+1);
29 76193d7c 2003-09-30 devnull } else
30 76193d7c 2003-09-30 devnull w = newword("");
31 76193d7c 2003-09-30 devnull if (symlook(*p, S_INTERNAL, 0))
32 76193d7c 2003-09-30 devnull continue;
33 76193d7c 2003-09-30 devnull s = strdup(*p);
34 76193d7c 2003-09-30 devnull setvar(s, (void *)w);
35 76193d7c 2003-09-30 devnull symlook(s, S_EXPORTED, (void*)"")->value = (void*)"";
36 76193d7c 2003-09-30 devnull }
37 76193d7c 2003-09-30 devnull }
38 76193d7c 2003-09-30 devnull
39 76193d7c 2003-09-30 devnull /*
40 76193d7c 2003-09-30 devnull * done on child side of fork, so parent's env is not affected
41 76193d7c 2003-09-30 devnull * and we don't care about freeing memory because we're going
42 76193d7c 2003-09-30 devnull * to exec immediately after this.
43 76193d7c 2003-09-30 devnull */
44 76193d7c 2003-09-30 devnull void
45 76193d7c 2003-09-30 devnull exportenv(Envy *e)
46 76193d7c 2003-09-30 devnull {
47 76193d7c 2003-09-30 devnull int i;
48 76193d7c 2003-09-30 devnull char **p;
49 76193d7c 2003-09-30 devnull char buf[4096];
50 76193d7c 2003-09-30 devnull
51 76193d7c 2003-09-30 devnull p = 0;
52 76193d7c 2003-09-30 devnull for(i = 0; e->name; e++, i++) {
53 76193d7c 2003-09-30 devnull p = (char**) Realloc(p, (i+2)*sizeof(char*));
54 76193d7c 2003-09-30 devnull if(e->values)
55 76193d7c 2003-09-30 devnull sprint(buf, "%s=%s", e->name, wtos(e->values, IWS));
56 76193d7c 2003-09-30 devnull else
57 76193d7c 2003-09-30 devnull sprint(buf, "%s=", e->name);
58 76193d7c 2003-09-30 devnull p[i] = strdup(buf);
59 76193d7c 2003-09-30 devnull }
60 76193d7c 2003-09-30 devnull p[i] = 0;
61 76193d7c 2003-09-30 devnull environ = p;
62 76193d7c 2003-09-30 devnull }
63 76193d7c 2003-09-30 devnull
64 76193d7c 2003-09-30 devnull int
65 76193d7c 2003-09-30 devnull waitfor(char *msg)
66 76193d7c 2003-09-30 devnull {
67 76193d7c 2003-09-30 devnull int status;
68 76193d7c 2003-09-30 devnull int pid;
69 76193d7c 2003-09-30 devnull
70 76193d7c 2003-09-30 devnull *msg = 0;
71 76193d7c 2003-09-30 devnull pid = wait(&status);
72 76193d7c 2003-09-30 devnull if(pid > 0) {
73 76193d7c 2003-09-30 devnull if(status&0x7f) {
74 76193d7c 2003-09-30 devnull if(status&0x80)
75 76193d7c 2003-09-30 devnull snprint(msg, ERRMAX, "signal %d, core dumped", status&0x7f);
76 76193d7c 2003-09-30 devnull else
77 76193d7c 2003-09-30 devnull snprint(msg, ERRMAX, "signal %d", status&0x7f);
78 76193d7c 2003-09-30 devnull } else if(status&0xff00)
79 76193d7c 2003-09-30 devnull snprint(msg, ERRMAX, "exit(%d)", (status>>8)&0xff);
80 76193d7c 2003-09-30 devnull }
81 76193d7c 2003-09-30 devnull return pid;
82 76193d7c 2003-09-30 devnull }
83 76193d7c 2003-09-30 devnull
84 76193d7c 2003-09-30 devnull void
85 76193d7c 2003-09-30 devnull expunge(int pid, char *msg)
86 76193d7c 2003-09-30 devnull {
87 76193d7c 2003-09-30 devnull if(strcmp(msg, "interrupt"))
88 76193d7c 2003-09-30 devnull kill(pid, SIGINT);
89 76193d7c 2003-09-30 devnull else
90 76193d7c 2003-09-30 devnull kill(pid, SIGHUP);
91 76193d7c 2003-09-30 devnull }
92 76193d7c 2003-09-30 devnull
93 76193d7c 2003-09-30 devnull int
94 76193d7c 2003-09-30 devnull execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
95 76193d7c 2003-09-30 devnull {
96 76193d7c 2003-09-30 devnull char *p;
97 76193d7c 2003-09-30 devnull int tot, n, pid, in[2], out[2];
98 76193d7c 2003-09-30 devnull
99 76193d7c 2003-09-30 devnull if(buf && pipe(out) < 0){
100 76193d7c 2003-09-30 devnull mkperror("pipe");
101 76193d7c 2003-09-30 devnull Exit();
102 76193d7c 2003-09-30 devnull }
103 76193d7c 2003-09-30 devnull pid = fork();
104 76193d7c 2003-09-30 devnull if(pid < 0){
105 76193d7c 2003-09-30 devnull mkperror("mk fork");
106 76193d7c 2003-09-30 devnull Exit();
107 76193d7c 2003-09-30 devnull }
108 76193d7c 2003-09-30 devnull if(pid == 0){
109 76193d7c 2003-09-30 devnull if(buf)
110 76193d7c 2003-09-30 devnull close(out[0]);
111 76193d7c 2003-09-30 devnull if(pipe(in) < 0){
112 76193d7c 2003-09-30 devnull mkperror("pipe");
113 76193d7c 2003-09-30 devnull Exit();
114 76193d7c 2003-09-30 devnull }
115 76193d7c 2003-09-30 devnull pid = fork();
116 76193d7c 2003-09-30 devnull if(pid < 0){
117 76193d7c 2003-09-30 devnull mkperror("mk fork");
118 76193d7c 2003-09-30 devnull Exit();
119 76193d7c 2003-09-30 devnull }
120 76193d7c 2003-09-30 devnull if(pid != 0){
121 76193d7c 2003-09-30 devnull dup2(in[0], 0);
122 76193d7c 2003-09-30 devnull if(buf){
123 76193d7c 2003-09-30 devnull dup2(out[1], 1);
124 76193d7c 2003-09-30 devnull close(out[1]);
125 76193d7c 2003-09-30 devnull }
126 76193d7c 2003-09-30 devnull close(in[0]);
127 76193d7c 2003-09-30 devnull close(in[1]);
128 76193d7c 2003-09-30 devnull if (e)
129 76193d7c 2003-09-30 devnull exportenv(e);
130 76193d7c 2003-09-30 devnull if(shflags)
131 76193d7c 2003-09-30 devnull execl(shell, shellname, shflags, args, 0);
132 76193d7c 2003-09-30 devnull else
133 76193d7c 2003-09-30 devnull execl(shell, shellname, args, 0);
134 76193d7c 2003-09-30 devnull mkperror(shell);
135 76193d7c 2003-09-30 devnull _exit(1);
136 76193d7c 2003-09-30 devnull }
137 76193d7c 2003-09-30 devnull close(out[1]);
138 76193d7c 2003-09-30 devnull close(in[0]);
139 76193d7c 2003-09-30 devnull if(DEBUG(D_EXEC))
140 76193d7c 2003-09-30 devnull fprint(1, "starting: %s\n", cmd);
141 76193d7c 2003-09-30 devnull p = cmd+strlen(cmd);
142 76193d7c 2003-09-30 devnull while(cmd < p){
143 76193d7c 2003-09-30 devnull n = write(in[1], cmd, p-cmd);
144 76193d7c 2003-09-30 devnull if(n < 0)
145 76193d7c 2003-09-30 devnull break;
146 76193d7c 2003-09-30 devnull cmd += n;
147 76193d7c 2003-09-30 devnull }
148 76193d7c 2003-09-30 devnull close(in[1]);
149 76193d7c 2003-09-30 devnull _exit(0);
150 76193d7c 2003-09-30 devnull }
151 76193d7c 2003-09-30 devnull if(buf){
152 76193d7c 2003-09-30 devnull close(out[1]);
153 76193d7c 2003-09-30 devnull tot = 0;
154 76193d7c 2003-09-30 devnull for(;;){
155 76193d7c 2003-09-30 devnull if (buf->current >= buf->end)
156 76193d7c 2003-09-30 devnull growbuf(buf);
157 76193d7c 2003-09-30 devnull n = read(out[0], buf->current, buf->end-buf->current);
158 76193d7c 2003-09-30 devnull if(n <= 0)
159 76193d7c 2003-09-30 devnull break;
160 76193d7c 2003-09-30 devnull buf->current += n;
161 76193d7c 2003-09-30 devnull tot += n;
162 76193d7c 2003-09-30 devnull }
163 76193d7c 2003-09-30 devnull if (tot && buf->current[-1] == '\n')
164 76193d7c 2003-09-30 devnull buf->current--;
165 76193d7c 2003-09-30 devnull close(out[0]);
166 76193d7c 2003-09-30 devnull }
167 76193d7c 2003-09-30 devnull return pid;
168 76193d7c 2003-09-30 devnull }
169 76193d7c 2003-09-30 devnull
170 76193d7c 2003-09-30 devnull int
171 76193d7c 2003-09-30 devnull pipecmd(char *cmd, Envy *e, int *fd)
172 76193d7c 2003-09-30 devnull {
173 76193d7c 2003-09-30 devnull int pid, pfd[2];
174 76193d7c 2003-09-30 devnull
175 76193d7c 2003-09-30 devnull if(DEBUG(D_EXEC))
176 76193d7c 2003-09-30 devnull fprint(1, "pipecmd='%s'\n", cmd);/**/
177 76193d7c 2003-09-30 devnull
178 76193d7c 2003-09-30 devnull if(fd && pipe(pfd) < 0){
179 76193d7c 2003-09-30 devnull mkperror("pipe");
180 76193d7c 2003-09-30 devnull Exit();
181 76193d7c 2003-09-30 devnull }
182 76193d7c 2003-09-30 devnull pid = fork();
183 76193d7c 2003-09-30 devnull if(pid < 0){
184 76193d7c 2003-09-30 devnull mkperror("mk fork");
185 76193d7c 2003-09-30 devnull Exit();
186 76193d7c 2003-09-30 devnull }
187 76193d7c 2003-09-30 devnull if(pid == 0){
188 76193d7c 2003-09-30 devnull if(fd){
189 76193d7c 2003-09-30 devnull close(pfd[0]);
190 76193d7c 2003-09-30 devnull dup2(pfd[1], 1);
191 76193d7c 2003-09-30 devnull close(pfd[1]);
192 76193d7c 2003-09-30 devnull }
193 76193d7c 2003-09-30 devnull if(e)
194 76193d7c 2003-09-30 devnull exportenv(e);
195 76193d7c 2003-09-30 devnull if(shflags)
196 76193d7c 2003-09-30 devnull execl(shell, shellname, shflags, "-c", cmd, 0);
197 76193d7c 2003-09-30 devnull else
198 76193d7c 2003-09-30 devnull execl(shell, shellname, "-c", cmd, 0);
199 76193d7c 2003-09-30 devnull mkperror(shell);
200 76193d7c 2003-09-30 devnull _exit(1);
201 76193d7c 2003-09-30 devnull }
202 76193d7c 2003-09-30 devnull if(fd){
203 76193d7c 2003-09-30 devnull close(pfd[1]);
204 76193d7c 2003-09-30 devnull *fd = pfd[0];
205 76193d7c 2003-09-30 devnull }
206 76193d7c 2003-09-30 devnull return pid;
207 76193d7c 2003-09-30 devnull }
208 76193d7c 2003-09-30 devnull
209 76193d7c 2003-09-30 devnull void
210 76193d7c 2003-09-30 devnull Exit(void)
211 76193d7c 2003-09-30 devnull {
212 76193d7c 2003-09-30 devnull while(wait(0) >= 0)
213 76193d7c 2003-09-30 devnull ;
214 76193d7c 2003-09-30 devnull exits("error");
215 76193d7c 2003-09-30 devnull }
216 76193d7c 2003-09-30 devnull
217 76193d7c 2003-09-30 devnull static struct
218 76193d7c 2003-09-30 devnull {
219 76193d7c 2003-09-30 devnull int sig;
220 76193d7c 2003-09-30 devnull char *msg;
221 76193d7c 2003-09-30 devnull } sigmsgs[] =
222 76193d7c 2003-09-30 devnull {
223 76193d7c 2003-09-30 devnull SIGALRM, "alarm",
224 76193d7c 2003-09-30 devnull SIGFPE, "sys: fp: fptrap",
225 76193d7c 2003-09-30 devnull SIGPIPE, "sys: write on closed pipe",
226 76193d7c 2003-09-30 devnull SIGILL, "sys: trap: illegal instruction",
227 76193d7c 2003-09-30 devnull SIGSEGV, "sys: segmentation violation",
228 76193d7c 2003-09-30 devnull 0, 0
229 76193d7c 2003-09-30 devnull };
230 76193d7c 2003-09-30 devnull
231 76193d7c 2003-09-30 devnull static void
232 76193d7c 2003-09-30 devnull notifyf(int sig)
233 76193d7c 2003-09-30 devnull {
234 76193d7c 2003-09-30 devnull int i;
235 76193d7c 2003-09-30 devnull
236 76193d7c 2003-09-30 devnull for(i = 0; sigmsgs[i].msg; i++)
237 76193d7c 2003-09-30 devnull if(sigmsgs[i].sig == sig)
238 76193d7c 2003-09-30 devnull killchildren(sigmsgs[i].msg);
239 76193d7c 2003-09-30 devnull
240 76193d7c 2003-09-30 devnull /* should never happen */
241 76193d7c 2003-09-30 devnull signal(sig, SIG_DFL);
242 76193d7c 2003-09-30 devnull kill(getpid(), sig);
243 76193d7c 2003-09-30 devnull }
244 76193d7c 2003-09-30 devnull
245 76193d7c 2003-09-30 devnull void
246 76193d7c 2003-09-30 devnull catchnotes()
247 76193d7c 2003-09-30 devnull {
248 76193d7c 2003-09-30 devnull int i;
249 76193d7c 2003-09-30 devnull
250 76193d7c 2003-09-30 devnull for(i = 0; sigmsgs[i].msg; i++)
251 76193d7c 2003-09-30 devnull signal(sigmsgs[i].sig, notifyf);
252 76193d7c 2003-09-30 devnull }
253 76193d7c 2003-09-30 devnull
254 76193d7c 2003-09-30 devnull char*
255 76193d7c 2003-09-30 devnull maketmp(int *pfd)
256 76193d7c 2003-09-30 devnull {
257 76193d7c 2003-09-30 devnull static char temp[] = "/tmp/mkargXXXXXX";
258 76193d7c 2003-09-30 devnull static char buf[100];
259 76193d7c 2003-09-30 devnull int fd;
260 76193d7c 2003-09-30 devnull
261 76193d7c 2003-09-30 devnull strcpy(buf, temp);
262 76193d7c 2003-09-30 devnull fd = mkstemp(buf);
263 76193d7c 2003-09-30 devnull if(fd < 0)
264 76193d7c 2003-09-30 devnull return 0;
265 76193d7c 2003-09-30 devnull *pfd = fd;
266 76193d7c 2003-09-30 devnull return buf;
267 76193d7c 2003-09-30 devnull }
268 76193d7c 2003-09-30 devnull
269 76193d7c 2003-09-30 devnull int
270 76193d7c 2003-09-30 devnull chgtime(char *name)
271 76193d7c 2003-09-30 devnull {
272 76193d7c 2003-09-30 devnull if(access(name, 0) >= 0)
273 76193d7c 2003-09-30 devnull return utimes(name, 0);
274 76193d7c 2003-09-30 devnull return close(creat(name, 0666));
275 76193d7c 2003-09-30 devnull }
276 76193d7c 2003-09-30 devnull
277 76193d7c 2003-09-30 devnull void
278 76193d7c 2003-09-30 devnull rcopy(char **to, Resub *match, int n)
279 76193d7c 2003-09-30 devnull {
280 76193d7c 2003-09-30 devnull int c;
281 76193d7c 2003-09-30 devnull char *p;
282 76193d7c 2003-09-30 devnull
283 76193d7c 2003-09-30 devnull *to = match->s.sp; /* stem0 matches complete target */
284 76193d7c 2003-09-30 devnull for(to++, match++; --n > 0; to++, match++){
285 76193d7c 2003-09-30 devnull if(match->s.sp && match->e.ep){
286 76193d7c 2003-09-30 devnull p = match->e.ep;
287 76193d7c 2003-09-30 devnull c = *p;
288 76193d7c 2003-09-30 devnull *p = 0;
289 76193d7c 2003-09-30 devnull *to = strdup(match->s.sp);
290 76193d7c 2003-09-30 devnull *p = c;
291 76193d7c 2003-09-30 devnull }
292 76193d7c 2003-09-30 devnull else
293 76193d7c 2003-09-30 devnull *to = 0;
294 76193d7c 2003-09-30 devnull }
295 76193d7c 2003-09-30 devnull }
296 76193d7c 2003-09-30 devnull
297 76193d7c 2003-09-30 devnull ulong
298 76193d7c 2003-09-30 devnull mkmtime(char *name)
299 76193d7c 2003-09-30 devnull {
300 76193d7c 2003-09-30 devnull struct stat st;
301 76193d7c 2003-09-30 devnull
302 76193d7c 2003-09-30 devnull if(stat(name, &st) < 0)
303 76193d7c 2003-09-30 devnull return 0;
304 76193d7c 2003-09-30 devnull
305 76193d7c 2003-09-30 devnull return st.st_mtime;
306 76193d7c 2003-09-30 devnull }