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