have to leave instrs.adb around, kernel uses it for kdb
[unix-history] / usr / src / old / sh / xec.c
CommitLineData
f6227721 1#ifndef lint
3cc4dafe 2static char sccsid[] = "@(#)xec.c 4.6 %G%";
f6227721 3#endif
f8e636e7
KM
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
17LOCAL INT parent;
18
19SYSTAB commands;
20
21
22
23/* ======== command execution ========*/
24
25
26execute(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;
3cc4dafe 51 IOPTR io=t->treio.treio;
f8e636e7
KM
52 gchain=0;
53 argn = getarg(t);
54 com=scan(argn);
55 a1=com[1]; gchain=schain;
56
eb594574 57 IF argn==0 ORF (internal=syslook(com[0],commands))
3cc4dafe 58 THEN setlist(t->comnod.comset, 0);
f8e636e7
KM
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
3cc4dafe 182 ELIF t->comnod.comset==0
f8e636e7
KM
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) {
399372bb 209 int c, i;
f8e636e7
KM
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
3cc4dafe 235 ELIF t->treio.treio==0
f8e636e7
KM
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 */
3cc4dafe 294 initio(t->treio.treio);
f8e636e7 295 IF type!=TCOM
3cc4dafe 296 THEN execute(t->forknod.forktre,1);
f8e636e7 297 ELIF com[0]!=ENDARGS
3cc4dafe 298 THEN setlist(t->comnod.comset,N_EXPORT);
f8e636e7
KM
299 execa(com);
300 FI
301 done();
302 FI
303
304 case TPAR:
305 rename(dup(2),output);
3cc4dafe 306 execute(t->parnod.partre,execflg);
f8e636e7
KM
307 done();
308
309 case TFIL:
310 BEGIN
311 INT pv[2]; chkpipe(pv);
3cc4dafe
KB
312 IF execute(t->lstnod.lstlef, 0, pf1, pv)==0
313 THEN execute(t->lstnod.lstrit, execflg, pv, pf2);
f8e636e7
KM
314 ELSE closepipe(pv);
315 FI
316 END
317 break;
318
319 case TLST:
3cc4dafe
KB
320 execute(t->lstnod.lstlef,0);
321 execute(t->lstnod.lstrit,execflg);
f8e636e7
KM
322 break;
323
324 case TAND:
3cc4dafe
KB
325 IF execute(t->lstnod.lstlef,0)==0
326 THEN execute(t->lstnod.lstrit,execflg);
f8e636e7
KM
327 FI
328 break;
329
330 case TORF:
3cc4dafe
KB
331 IF execute(t->lstnod.lstlef,0)!=0
332 THEN execute(t->lstnod.lstrit,execflg);
f8e636e7
KM
333 FI
334 break;
335
336 case TFOR:
337 BEGIN
3cc4dafe 338 NAMPTR n = lookup(t->fornod.fornam);
f8e636e7
KM
339 STRING *args;
340 DOLPTR argsav=0;
341
3cc4dafe 342 IF t->fornod.forlst==0
f8e636e7
KM
343 THEN args=dolv+1;
344 argsav=useargs();
345 ELSE ARGPTR schain=gchain;
346 gchain=0;
3cc4dafe 347 trim((args=scan(getarg(t->fornod.forlst)))[0]);
f8e636e7
KM
348 gchain=schain;
349 FI
350 loopcnt++;
351 WHILE *args!=ENDARGS ANDF execbrk==0
352 DO assign(n,*args++);
3cc4dafe 353 execute(t->fornod.fortre,0);
f8e636e7
KM
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
7d79bd40 365 INT i=0, saveflg;
f8e636e7 366
7d79bd40 367 saveflg = flags&errflg;
f8e636e7 368 loopcnt++;
7d79bd40
KB
369 WHILE execbrk==0
370 DO flags &= ~errflg;
3cc4dafe 371 i=execute(t->whnod.whtre,0);
7d79bd40
KB
372 flags |= saveflg;
373 IF (i==0)!=(type==TWH) THEN break FI
3cc4dafe 374 i=execute(t->whnod.dotre,0);
f8e636e7
KM
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:
7d79bd40
KB
383 BEGIN
384 INT i, saveflg;
385
386 saveflg = flags&errflg;
387 flags &= ~errflg;
3cc4dafe 388 i=execute(t->ifnod.iftre,0);
7d79bd40
KB
389 flags |= saveflg;
390 IF i==0
3cc4dafe
KB
391 THEN execute(t->ifnod.thtre,execflg);
392 ELSE execute(t->ifnod.eltre,execflg);
7d79bd40
KB
393 FI
394 END
f8e636e7
KM
395 break;
396
397 case TSW:
398 BEGIN
3cc4dafe
KB
399 REG STRING r = mactrim(t->swnod.swarg);
400 REG REGPTR eg = t->swnod.swlst;
401 WHILE eg
402 DO ARGPTR rex=eg->regptr;
f8e636e7
KM
403 WHILE rex
404 DO REG STRING s;
405 IF gmatch(r,s=macro(rex->argval)) ORF (trim(s), eq(r,s))
3cc4dafe
KB
406 THEN execute(eg->regcom,0);
407 eg=0; break;
f8e636e7
KM
408 ELSE rex=rex->argnxt;
409 FI
410 OD
3cc4dafe 411 IF eg THEN eg=eg->regnxt FI
f8e636e7
KM
412 OD
413 END
414 break;
415 ENDSW
416 exitset();
417 FI
418
419 sigchk();
420 tdystak(sav);
421 return(exitval);
422}
423
424
425execexp(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}