Bell 32V development
[unix-history] / usr / src / cmd / sh / xec.c
CommitLineData
862515b8
TL
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
13LOCAL INT parent;
14
15SYSTAB commands;
16
17
18
19/* ======== command execution ========*/
20
21
22execute(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
408execexp(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}