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 15 LOCAL INT parent; 16 17 SYSTAB commands; 18 19 20 21 /* ======== command execution ========*/ 22 23 24 execute(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 410 execexp(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 } 424