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