hack workaround hy problem
[unix-history] / usr / src / old / sh / xec.c
CommitLineData
f6227721
SL
1#ifndef lint
2static char sccsid[] = "@(#)xec.c 4.3 %G%";
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;
51 IOPTR io=t->treio;
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))
f8e636e7
KM
58 THEN setlist(t->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->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==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);
295 IF type!=TCOM
296 THEN execute(t->forktre,1);
297 ELIF com[0]!=ENDARGS
298 THEN setlist(t->comset,N_EXPORT);
299 execa(com);
300 FI
301 done();
302 FI
303
304 case TPAR:
305 rename(dup(2),output);
306 execute(t->partre,execflg);
307 done();
308
309 case TFIL:
310 BEGIN
311 INT pv[2]; chkpipe(pv);
312 IF execute(t->lstlef, 0, pf1, pv)==0
313 THEN execute(t->lstrit, execflg, pv, pf2);
314 ELSE closepipe(pv);
315 FI
316 END
317 break;
318
319 case TLST:
320 execute(t->lstlef,0);
321 execute(t->lstrit,execflg);
322 break;
323
324 case TAND:
325 IF execute(t->lstlef,0)==0
326 THEN execute(t->lstrit,execflg);
327 FI
328 break;
329
330 case TORF:
331 IF execute(t->lstlef,0)!=0
332 THEN execute(t->lstrit,execflg);
333 FI
334 break;
335
336 case TFOR:
337 BEGIN
338 NAMPTR n = lookup(t->fornam);
339 STRING *args;
340 DOLPTR argsav=0;
341
342 IF t->forlst==0
343 THEN args=dolv+1;
344 argsav=useargs();
345 ELSE ARGPTR schain=gchain;
346 gchain=0;
347 trim((args=scan(getarg(t->forlst)))[0]);
348 gchain=schain;
349 FI
350 loopcnt++;
351 WHILE *args!=ENDARGS ANDF execbrk==0
352 DO assign(n,*args++);
353 execute(t->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;
366
367 loopcnt++;
368 WHILE execbrk==0 ANDF (execute(t->whtre,0)==0)==(type==TWH)
369 DO i=execute(t->dotre,0);
370 IF execbrk<0 THEN execbrk=0 FI
371 OD
372 IF breakcnt THEN breakcnt-- FI
373 execbrk=breakcnt; loopcnt--; exitval=i;
374 END
375 break;
376
377 case TIF:
378 IF execute(t->iftre,0)==0
379 THEN execute(t->thtre,execflg);
380 ELSE execute(t->eltre,execflg);
381 FI
382 break;
383
384 case TSW:
385 BEGIN
386 REG STRING r = mactrim(t->swarg);
387 t=t->swlst;
388 WHILE t
389 DO ARGPTR rex=t->regptr;
390 WHILE rex
391 DO REG STRING s;
392 IF gmatch(r,s=macro(rex->argval)) ORF (trim(s), eq(r,s))
393 THEN execute(t->regcom,0);
394 t=0; break;
395 ELSE rex=rex->argnxt;
396 FI
397 OD
398 IF t THEN t=t->regnxt FI
399 OD
400 END
401 break;
402 ENDSW
403 exitset();
404 FI
405
406 sigchk();
407 tdystak(sav);
408 return(exitval);
409}
410
411
412execexp(s,f)
413 STRING s;
414 UFD f;
415{
416 FILEBLK fb;
417 push(&fb);
418 IF s
419 THEN estabf(s); fb.feval=f;
420 ELIF f>=0
421 THEN initf(f);
422 FI
423 execute(cmd(NL, NLFLG|MTFLG),0);
424 pop();
425}