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