1 #ifndef lint 2 static char sccsid[] = "@(#)xec.c 4.5 09/16/87"; 3 #endif 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 17 LOCAL INT parent; 18 19 SYSTAB commands; 20 21 22 23 /* ======== command execution ========*/ 24 25 26 execute(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 57 IF argn==0 ORF (internal=syslook(com[0],commands)) 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, saveflg; 366 367 saveflg = flags&errflg; 368 loopcnt++; 369 WHILE execbrk==0 370 DO flags &= ~errflg; 371 i=execute(t->whtre,0); 372 flags |= saveflg; 373 IF (i==0)!=(type==TWH) THEN break FI 374 i=execute(t->dotre,0); 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: 383 BEGIN 384 INT i, saveflg; 385 386 saveflg = flags&errflg; 387 flags &= ~errflg; 388 i=execute(t->iftre,0); 389 flags |= saveflg; 390 IF i==0 391 THEN execute(t->thtre,execflg); 392 ELSE execute(t->eltre,execflg); 393 FI 394 END 395 break; 396 397 case TSW: 398 BEGIN 399 REG STRING r = mactrim(t->swarg); 400 t=t->swlst; 401 WHILE t 402 DO ARGPTR rex=t->regptr; 403 WHILE rex 404 DO REG STRING s; 405 IF gmatch(r,s=macro(rex->argval)) ORF (trim(s), eq(r,s)) 406 THEN execute(t->regcom,0); 407 t=0; break; 408 ELSE rex=rex->argnxt; 409 FI 410 OD 411 IF t THEN t=t->regnxt FI 412 OD 413 END 414 break; 415 ENDSW 416 exitset(); 417 FI 418 419 sigchk(); 420 tdystak(sav); 421 return(exitval); 422 } 423 424 425 execexp(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 } 439