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