|
|
1.1 root 1: /*
2: * sh/exec1.c
3: * The Bourne shell.
4: * Shell part of execution.
5: */
6:
7: #include "sh.h"
8:
9: char *lastcmd = "";
10:
11: char *skipredir();
12:
13: /*
14: * Execute the given node, wait for completion, return status.
15: */
16: command(np)
17: register NODE *np;
18: {
19: register int f; /* Pid of command */
20: int mynllflag; /* Saved fork not forced flag */
21: CON con; /* Control link for break/continue */
22: char *innp, **inlp; /* for NFOR */
23: NODE *cnode; /* for NCASE */
24: char *cname; /* for NCASE */
25:
26: mynllflag = nllflag;
27: innp = inlp = NULL;
28: cnode = NULL;
29: f = 0;
30:
31: con.c_next = sesp->s_con;
32: con.c_node = np;
33: con.c_bpp = savebuf();
34: sesp->s_con = &con;
35:
36: switch (setjmp(con.c_envl)) {
37: case 0: /* initial setjmp */
38: break;
39: case 1: /* continue */
40: np = con.c_node;
41: break;
42: case 2: /* break */
43: goto break2;
44: default:
45: panic(1);
46: NOTREACHED;
47: }
48:
49: for ( ; np != NULL; np=np->n_next) {
50: recover(ICMD);
51: f = 0;
52: nllflag = mynllflag;
53:
54: switch (np->n_type) {
55: case NCOMS:
56: f = comscom(np->n_auxp);
57: break;
58: case NFOR:
59: if (innp == NULL) {
60: innp = np->n_strp;
61: nargc = 0;
62: nargv = makargl();
63: for (np = np->n_next->n_auxp; np; np = np->n_next)
64: eval(np->n_strp, EARGS);
65: inlp = nargv;
66: np = con.c_node;
67: }
68: continue;
69: case NFOR2:
70: /* do_done_list->n_next == this node */
71: if (*inlp == NULL || assnvar(innp, *inlp++) == NULL)
72: break;
73: continue;
74: case NWHILE:
75: /* do_done_list->n_next == this node */
76: nllflag = 0;
77: if (command(np->n_auxp))
78: break;
79: continue;
80: case NUNTIL:
81: /* do_done_list->n_next == this node */
82: nllflag = 0;
83: if ( ! command(np->n_auxp))
84: break;
85: continue;
86: case NBRAC:
87: command(np->n_auxp);
88: break;
89: case NPARN:
90: if (nllflag || (f=clone()) == 0) {
91: exit(command(np->n_auxp));
92: NOTREACHED;
93: }
94: break;
95: case NIF:
96: nllflag = 0;
97: if (!command(np->n_auxp->n_auxp))
98: np = np->n_auxp;
99: else if (np->n_next == NULL)
100: slret = 0; /* exit status 0 if no elsepart */
101: continue;
102: case NELSE:
103: command(np->n_auxp);
104: break;
105: case NCASE:
106: eval(np->n_strp, EWORD);
107: if (errflag)
108: break;
109: cname = duplstr(strt, 0);
110: continue;
111: case NCASE2:
112: cnode = np->n_auxp;
113: continue;
114: case NCASE3:
115: /* end of pattern list == next NCASE2 node */
116: eval(np->n_strp, EPATT);
117: if (errflag)
118: break;
119: if (match(strt, cname)) {
120: command(cnode);
121: break;
122: }
123: continue;
124: case NLIST:
125: nllflag = 0;
126: command(np->n_auxp);
127: continue;
128: case NANDF:
129: nllflag = 0;
130: if (command(np->n_auxp))
131: break;
132: continue;
133: case NORF:
134: nllflag = 0;
135: if ( ! command(np->n_auxp))
136: break;
137: continue;
138: case NBACK:
139: if ((f=clone()) == 0) {
140: static char *iov[] = { "0</dev/null", NULL };
141:
142: bckflag++;
143: dflttrp(IBACK);
144: redirect(iov);
145: exit(command(np->n_auxp));
146: NOTREACHED;
147: }
148: sback = f;
149: prints("%d\n", f);
150: f = 0;
151: continue;
152: case NPIPE:
153: f = pipecoms(np);
154: break;
155: default:
156: panic(2);
157: NOTREACHED;
158: }
159: break;
160:
161: }
162: break2:
163: nllflag = mynllflag;
164: if (sesp->s_con != NULL)
165: sesp->s_con = sesp->s_con->c_next;
166: if (f)
167: waitc(f);
168: if (slret)
169: assnvar("LASTERROR", lastcmd);
170: freebuf(con.c_bpp);
171: if (eflag && (slret || errflag)) {
172: reset(RUABORT);
173: NOTREACHED;
174: }
175: return slret;
176: }
177:
178: /*
179: * Run a simple command.
180: * Anything but.
181: */
182: #define FARGS 1
183: #define FIORS 2
184: #define FASSG 4
185:
186: comscom(np)
187: register NODE *np;
188: {
189: register int f;
190: register char **app, *s, *s1, *sp;
191: int nputs, nargs;
192:
193: nargc = 1;
194: nargv = makargl();
195: nargv = addargl(nargv, "sh");
196: niovp = makargl();
197: nenvp = makargl();
198: nctlp = NULL;
199: /*
200: * Scan for arguments.
201: * or a control node.
202: */
203: nputs = 0;
204: f = 0;
205: for ( ; np; np = np->n_next) {
206: switch (np->n_type) {
207: case NIORS:
208: f |= FIORS;
209: #if 0
210: /* Old code. */
211: eval(np->n_strp, EWORD);
212: niovp = addargl(niovp, duplstr(strt, 0));
213: if (xflag)
214: nputs += puta(nputs, strt);
215: #else
216: /*
217: * New code by steve 1/24/91.
218: * This allows globs in redirection args.
219: */
220: s = skipredir(np->n_strp);
221: nargs = nargc;
222: eval(s, EARGS); /* expand as arg */
223: for (s1 = np->n_strp, sp = strt; s1 < s; )
224: *sp++ = *s1++;
225: strcpy(sp, nargv[nargs]); /* build redir arg */
226: niovp = addargl(niovp, duplstr(strt, 0));
227: if (xflag)
228: nputs += puta(nputs, strt);
229: --nargc;
230: for (app = nargv+nargs; *app; app++) {
231: *app = *(app + 1); /* shift remaining args */
232: if (xflag && *app != NULL)
233: nputs += puta(nputs, *app);
234: }
235: #endif
236: continue;
237: case NARGS:
238: f |= FARGS;
239: nargs = nargc;
240: eval(np->n_strp, EARGS);
241: if (xflag)
242: for (app = nargv+nargs; *app; )
243: nputs += puta(nputs, *app++);
244: continue;
245: case NASSG:
246: if (kflag || (f&FARGS)==0) {
247: f |= FASSG;
248: eval(np->n_strp, EWORD);
249: nenvp = addargl(nenvp, duplstr(strt, 0));
250: if (xflag)
251: nputs += puta(nputs, strt);
252: } else {
253: nargs = nargc;
254: eval(np->n_strp, EARGS);
255: if (xflag)
256: for (app = nargv+nargs; *app; )
257: nputs += puta(nputs, *app++);
258: }
259: continue;
260: case NCTRL:
261: if (nctlp!=NULL) {
262: panic(3);
263: NOTREACHED;
264: }
265: f |= FARGS;
266: nctlp = np;
267: continue;
268: default:
269: panic(4);
270: NOTREACHED;
271: }
272: }
273: if (xflag && nputs)
274: prints("\n");
275: #ifdef VERBOSE
276: if (xflag) {
277: prints("\t<%o flag, %d put, %d arg, %o arv, %o env, %o iov>\n",
278: f, nputs, nargc-1, *(nargv+1), *nenvp, *niovp);
279: }
280: #endif
281:
282: nargv += 1; /* Skip over "sh" */
283: nargc -= 1;
284:
285: /* Last chance to quit */
286: #ifdef VERBOSE
287: if (xflag) prints("errflag = %o\n", errflag);
288: #endif
289: if (errflag || nflag)
290: return (0);
291:
292: /* And away we go */
293: sfree(lastcmd);
294: if (*nargv)
295: lastcmd = duplstr(*nargv, 1);
296: else
297: lastcmd = "";
298: switch (f) {
299: case 0:
300: return (0);
301: case FARGS:
302: if (nctlp) {
303: command(nctlp->n_auxp);
304: return (0);
305: }
306: case FARGS| FIORS:
307: case FARGS| FASSG:
308: case FARGS| FIORS| FASSG:
309: if (inline())
310: return (0);
311: break;
312: case FIORS:
313: break;
314: case FASSG:
315: case FIORS| FASSG:
316: for (app = nenvp; *app!=NULL; )
317: setsvar(*app++);
318: if ((f&~FASSG)==0) {
319: slret = 0;
320: return (0);
321: }
322: break;
323: default:
324: panic(5);
325: NOTREACHED;
326: }
327: if (nllflag || (f=clone()) == 0) {
328: if (redirect(niovp) < 0) {
329: slret = 1;
330: } else if (nargc) {
331: dflttrp(ICMD);
332: nenvp = envlvar(nenvp);
333: flexec();
334: slret = 1;
335: } else if (nctlp) {
336: command(nctlp->n_auxp);
337: }
338: exit(slret);
339: NOTREACHED;
340: }
341: return (f);
342: }
343:
344: puta(n, p)
345: char *p;
346: {
347: if (n)
348: prints(" ");
349: #ifdef VERBOSE
350: else
351: prints("<%d> ", getpid());
352: #endif
353: prints("%s", p);
354: return (1);
355: }
356:
357: /*
358: * Execute a pipe command.
359: * Fork, if necessary, a subshell to execute the pipe.
360: * Fork each segment off.
361: * Wait for last, save slret, wait for all, return slret from last.
362: */
363: pipecoms(np)
364: register NODE *np;
365: {
366: register int f;
367: register int p1st = 0;
368: int pipev[2];
369:
370: if ( ! nllflag && (f = clone()) != 0)
371: return (f);
372: while (np->n_type == NPIPE) {
373: if (f = pipeline(pipev)) {
374: /* Parent takes right hand side */
375: np = np->n_next;
376: if (p1st == 0)
377: p1st = f;
378: dup2(pipev[0], 0);
379: if (pipev[0] != 0)
380: close(pipev[0]);
381: close(pipev[1]);
382: } else {
383: /* Child takes left hand side */
384: np = np->n_auxp;
385: dup2(pipev[1], 1);
386: close(pipev[0]);
387: if (pipev[1] != 1)
388: close(pipev[1]);
389: exit(command(np));
390: NOTREACHED;
391: }
392: }
393: if (f = clone()) {
394: /* Parent waits out pipe line */
395: spipe = p1st;
396: close(0);
397: if (f = waitc(f))
398: waitc(p1st);
399: exit(f);
400: NOTREACHED;
401: } else {
402: /* Child takes the pipe tail */
403: exit(command(np));
404: NOTREACHED;
405: }
406: }
407:
408: /*
409: * Skip a redirection arg, return pointer to following nonspace.
410: */
411: char *
412: skipredir(s) register char *s;
413: {
414: if (*s >= '1' && *s <= '9')
415: ++s;
416: if (*s == '>' || *s == '<')
417: ++s;
418: if (*s == '>' || *s == '<')
419: ++s;
420: if (*s == '&')
421: ++s;
422: while (*s == ' ' || *s == '\t')
423: ++s;
424: return s;
425: }
426:
427: /* end of sh/exec1.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.