|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)xec.c 4.7 5/8/89";
3: #endif
4:
5: #
6: /*
7: * UNIX shell
8: *
9: * S. R. Bourne
10: * Bell Telephone Laboratories
11: *
12: */
13:
14: #include "defs.h"
15: #include "sym.h"
16: #include "pathnames.h"
17:
18: LOCAL INT parent;
19:
20: SYSTAB commands;
21:
22:
23:
24: /* ======== command execution ========*/
25:
26:
27: execute(argt, execflg, pf1, pf2)
28: TREPTR argt;
29: INT *pf1, *pf2;
30: {
31: /* `stakbot' is preserved by this routine */
32: REG TREPTR t;
33: STKPTR sav=savstak();
34:
35: sigchk();
36:
37: IF (t=argt) ANDF execbrk==0
38: THEN REG INT treeflgs;
39: INT oldexit, type;
40: REG STRING *com;
41:
42: treeflgs = t->tretyp; type = treeflgs&COMMSK;
43: oldexit=exitval; exitval=0;
44:
45: SWITCH type IN
46:
47: case TCOM:
48: BEGIN
49: STRING a1;
50: INT argn, internal;
51: ARGPTR schain=gchain;
52: IOPTR io=t->treio.treio;
53: gchain=0;
54: argn = getarg(t);
55: com=scan(argn);
56: a1=com[1]; gchain=schain;
57:
58: IF argn==0 ORF (internal=syslook(com[0],commands))
59: THEN setlist(t->comnod.comset, 0);
60: FI
61:
62: IF argn ANDF (flags&noexec)==0
63: THEN /* print command if execpr */
64: IF flags&execpr
65: THEN argn=0; prs(execpmsg);
66: WHILE com[argn]!=ENDARGS
67: DO prs(com[argn++]); blank() OD
68: newline();
69: FI
70:
71: SWITCH internal IN
72:
73: case SYSDOT:
74: IF a1
75: THEN REG INT f;
76:
77: IF (f=pathopen(getpath(a1), a1)) < 0
78: THEN failed(a1,notfound);
79: ELSE execexp(0,f);
80: FI
81: FI
82: break;
83:
84: case SYSTIMES:
85: {
86: L_INT t[4]; times(t);
87: prt(t[2]); blank(); prt(t[3]); newline();
88: }
89: break;
90:
91: case SYSEXIT:
92: exitsh(a1?stoi(a1):oldexit);
93:
94: case SYSNULL:
95: io=0;
96: break;
97:
98: case SYSCONT:
99: execbrk = -loopcnt; break;
100:
101: case SYSBREAK:
102: IF (execbrk=loopcnt) ANDF a1
103: THEN breakcnt=stoi(a1);
104: FI
105: break;
106:
107: case SYSTRAP:
108: IF a1
109: THEN BOOL clear;
110: IF (clear=digit(*a1))==0
111: THEN ++com;
112: FI
113: WHILE *++com
114: DO INT i;
115: IF (i=stoi(*com))>=MAXTRAP ORF i<MINTRAP
116: THEN failed(*com,badtrap);
117: ELIF clear
118: THEN clrsig(i);
119: ELSE replace(&trapcom[i],a1);
120: IF *a1
121: THEN getsig(i);
122: ELSE ignsig(i);
123: FI
124: FI
125: OD
126: ELSE /* print out current traps */
127: INT i;
128:
129: FOR i=0; i<MAXTRAP; i++
130: DO IF trapcom[i]
131: THEN prn(i); prs(colon); prs(trapcom[i]); newline();
132: FI
133: OD
134: FI
135: break;
136:
137: case SYSEXEC:
138: com++;
139: initio(io); ioset=0; io=0;
140: IF a1==0 THEN break FI
141:
142: case SYSLOGIN:
143: flags |= forked;
144: oldsigs(); execa(com); done();
145:
146: case SYSCD:
147: IF flags&rshflg
148: THEN failed(com[0],restricted);
149: ELIF (a1==0 ANDF (a1=homenod.namval)==0) ORF chdir(a1)<0
150: THEN failed(a1,baddir);
151: FI
152: break;
153:
154: case SYSSHFT:
155: IF dolc<1
156: THEN error(badshift);
157: ELSE dolv++; dolc--;
158: FI
159: assnum(&dolladr, dolc);
160: break;
161:
162: case SYSWAIT:
163: await(-1);
164: break;
165:
166: case SYSREAD:
167: exitval=readvar(&com[1]);
168: break;
169:
170: /*
171: case SYSTST:
172: exitval=testcmd(com);
173: break;
174: */
175:
176: case SYSSET:
177: IF a1
178: THEN INT argc;
179: argc = options(argn,com);
180: IF argc>1
181: THEN setargs(com+argn-argc);
182: FI
183: ELIF t->comnod.comset==0
184: THEN /*scan name chain and print*/
185: namscan(printnam);
186: FI
187: break;
188:
189: case SYSRDONLY:
190: exitval=N_RDONLY;
191: case SYSXPORT:
192: IF exitval==0 THEN exitval=N_EXPORT; FI
193:
194: IF a1
195: THEN WHILE *++com
196: DO attrib(lookup(*com), exitval) OD
197: ELSE namscan(printflg);
198: FI
199: exitval=0;
200: break;
201:
202: case SYSEVAL:
203: IF a1
204: THEN execexp(a1,&com[2]);
205: FI
206: break;
207:
208: case SYSUMASK:
209: if (a1) {
210: int c, i;
211: i = 0;
212: while ((c = *a1++) >= '0' &&
213: c <= '7')
214: i = (i << 3) + c - '0';
215: umask(i);
216: } else {
217: int i, j;
218: umask(i = umask(0));
219: prc('0');
220: for (j = 6; j >= 0; j -= 3)
221: prc(((i>>j)&07) + '0');
222: newline();
223: }
224: break;
225:
226: default:
227: internal=builtin(argn,com);
228:
229: ENDSW
230:
231: IF internal
232: THEN IF io THEN error(illegal) FI
233: chktrap();
234: break;
235: FI
236: ELIF t->treio.treio==0
237: THEN break;
238: FI
239: END
240:
241: case TFORK:
242: IF execflg ANDF (treeflgs&(FAMP|FPOU))==0
243: THEN parent=0;
244: ELSE WHILE (parent=fork()) == -1
245: DO sigchk(); alarm(10); pause() OD
246: FI
247:
248: IF parent
249: THEN /* This is the parent branch of fork; */
250: /* it may or may not wait for the child. */
251: IF treeflgs&FPRS ANDF flags&ttyflg
252: THEN prn(parent); newline();
253: FI
254: IF treeflgs&FPCL THEN closepipe(pf1) FI
255: IF (treeflgs&(FAMP|FPOU))==0
256: THEN await(parent);
257: ELIF (treeflgs&FAMP)==0
258: THEN post(parent);
259: ELSE assnum(&pcsadr, parent);
260: FI
261:
262: chktrap();
263: break;
264:
265:
266: ELSE /* this is the forked branch (child) of execute */
267: flags |= forked; iotemp=0;
268: postclr();
269: settmp();
270:
271: /* Turn off INTR and QUIT if `FINT' */
272: /* Reset ramaining signals to parent */
273: /* except for those `lost' by trap */
274: oldsigs();
275: IF treeflgs&FINT
276: THEN signal(INTR,1); signal(QUIT,1);
277: FI
278:
279: /* pipe in or out */
280: IF treeflgs&FPIN
281: THEN rename(pf1[INPIPE],0);
282: close(pf1[OTPIPE]);
283: FI
284: IF treeflgs&FPOU
285: THEN rename(pf2[OTPIPE],1);
286: close(pf2[INPIPE]);
287: FI
288:
289: /* default std input for & */
290: IF treeflgs&FINT ANDF ioset==0
291: THEN rename(chkopen(_PATH_DEVNULL),0);
292: FI
293:
294: /* io redirection */
295: initio(t->treio.treio);
296: IF type!=TCOM
297: THEN execute(t->forknod.forktre,1);
298: ELIF com[0]!=ENDARGS
299: THEN setlist(t->comnod.comset,N_EXPORT);
300: execa(com);
301: FI
302: done();
303: FI
304:
305: case TPAR:
306: rename(dup(2),output);
307: execute(t->parnod.partre,execflg);
308: done();
309:
310: case TFIL:
311: BEGIN
312: INT pv[2]; chkpipe(pv);
313: IF execute(t->lstnod.lstlef, 0, pf1, pv)==0
314: THEN execute(t->lstnod.lstrit, execflg, pv, pf2);
315: ELSE closepipe(pv);
316: FI
317: END
318: break;
319:
320: case TLST:
321: execute(t->lstnod.lstlef,0);
322: execute(t->lstnod.lstrit,execflg);
323: break;
324:
325: case TAND:
326: IF execute(t->lstnod.lstlef,0)==0
327: THEN execute(t->lstnod.lstrit,execflg);
328: FI
329: break;
330:
331: case TORF:
332: IF execute(t->lstnod.lstlef,0)!=0
333: THEN execute(t->lstnod.lstrit,execflg);
334: FI
335: break;
336:
337: case TFOR:
338: BEGIN
339: NAMPTR n = lookup(t->fornod.fornam);
340: STRING *args;
341: DOLPTR argsav=0;
342:
343: IF t->fornod.forlst==0
344: THEN args=dolv+1;
345: argsav=useargs();
346: ELSE ARGPTR schain=gchain;
347: gchain=0;
348: trim((args=scan(getarg(t->fornod.forlst)))[0]);
349: gchain=schain;
350: FI
351: loopcnt++;
352: WHILE *args!=ENDARGS ANDF execbrk==0
353: DO assign(n,*args++);
354: execute(t->fornod.fortre,0);
355: IF execbrk<0 THEN execbrk=0 FI
356: OD
357: IF breakcnt THEN breakcnt-- FI
358: execbrk=breakcnt; loopcnt--;
359: argfor=freeargs(argsav);
360: END
361: break;
362:
363: case TWH:
364: case TUN:
365: BEGIN
366: INT i=0, saveflg;
367:
368: saveflg = flags&errflg;
369: loopcnt++;
370: WHILE execbrk==0
371: DO flags &= ~errflg;
372: i=execute(t->whnod.whtre,0);
373: flags |= saveflg;
374: IF (i==0)!=(type==TWH) THEN break FI
375: i=execute(t->whnod.dotre,0);
376: IF execbrk<0 THEN execbrk=0 FI
377: OD
378: IF breakcnt THEN breakcnt-- FI
379: execbrk=breakcnt; loopcnt--; exitval=i;
380: END
381: break;
382:
383: case TIF:
384: BEGIN
385: INT i, saveflg;
386:
387: saveflg = flags&errflg;
388: flags &= ~errflg;
389: i=execute(t->ifnod.iftre,0);
390: flags |= saveflg;
391: IF i==0
392: THEN execute(t->ifnod.thtre,execflg);
393: ELSE execute(t->ifnod.eltre,execflg);
394: FI
395: END
396: break;
397:
398: case TSW:
399: BEGIN
400: REG STRING r = mactrim(t->swnod.swarg);
401: REG REGPTR eg = t->swnod.swlst;
402: WHILE eg
403: DO ARGPTR rex=eg->regptr;
404: WHILE rex
405: DO REG STRING s;
406: IF gmatch(r,s=macro(rex->argval)) ORF (trim(s), eq(r,s))
407: THEN execute(eg->regcom,0);
408: eg=0; break;
409: ELSE rex=rex->argnxt;
410: FI
411: OD
412: IF eg THEN eg=eg->regnxt FI
413: OD
414: END
415: break;
416: ENDSW
417: exitset();
418: FI
419:
420: sigchk();
421: tdystak(sav);
422: return(exitval);
423: }
424:
425:
426: execexp(s,f)
427: STRING s;
428: UFD f;
429: {
430: FILEBLK fb;
431: push(&fb);
432: IF s
433: THEN estabf(s); fb.feval=f;
434: ELIF f>=0
435: THEN initf(f);
436: FI
437: execute(cmd(NL, NLFLG|MTFLG),0);
438: pop();
439: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.