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