|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)service.c 4.4 3/19/85"; ! 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: ! 16: ! 17: PROC VOID gsort(); ! 18: ! 19: #define ARGMK 01 ! 20: ! 21: INT errno; ! 22: STRING sysmsg[]; ! 23: INT num_sysmsg; ! 24: ! 25: /* fault handling */ ! 26: #define ENOMEM 12 ! 27: #define ENOEXEC 8 ! 28: #define E2BIG 7 ! 29: #define ENOENT 2 ! 30: #define ETXTBSY 26 ! 31: ! 32: ! 33: ! 34: /* service routines for `execute' */ ! 35: ! 36: VOID initio(iop) ! 37: IOPTR iop; ! 38: { ! 39: REG STRING ion; ! 40: REG INT iof, fd; ! 41: ! 42: IF iop ! 43: THEN iof=iop->iofile; ! 44: ion=mactrim(iop->ioname); ! 45: IF *ion ANDF (flags&noexec)==0 ! 46: THEN IF iof&IODOC ! 47: THEN subst(chkopen(ion),(fd=tmpfil())); ! 48: close(fd); fd=chkopen(tmpout); unlink(tmpout); ! 49: ELIF iof&IOMOV ! 50: THEN IF eq(minus,ion) ! 51: THEN fd = -1; ! 52: close(iof&IOUFD); ! 53: ELIF (fd=stoi(ion))>=USERIO ! 54: THEN failed(ion,badfile); ! 55: ELSE fd=dup(fd); ! 56: FI ! 57: ELIF (iof&IOPUT)==0 ! 58: THEN fd=chkopen(ion); ! 59: ELIF flags&rshflg ! 60: THEN failed(ion,restricted); ! 61: ELIF iof&IOAPP ANDF (fd=open(ion,1))>=0 ! 62: THEN lseek(fd, 0L, 2); ! 63: ELSE fd=create(ion); ! 64: FI ! 65: IF fd>=0 ! 66: THEN rename(fd,iof&IOUFD); ! 67: FI ! 68: FI ! 69: initio(iop->ionxt); ! 70: FI ! 71: } ! 72: ! 73: STRING getpath(s) ! 74: STRING s; ! 75: { ! 76: REG STRING path; ! 77: IF any('/',s) ! 78: THEN IF flags&rshflg ! 79: THEN failed(s, restricted); ! 80: ELSE return(nullstr); ! 81: FI ! 82: ELIF (path = pathnod.namval)==0 ! 83: THEN return(defpath); ! 84: ELSE return(cpystak(path)); ! 85: FI ! 86: } ! 87: ! 88: INT pathopen(path, name) ! 89: REG STRING path, name; ! 90: { ! 91: REG UFD f; ! 92: ! 93: REP path=catpath(path,name); ! 94: PER (f=open(curstak(),0))<0 ANDF path DONE ! 95: return(f); ! 96: } ! 97: ! 98: STRING catpath(path,name) ! 99: REG STRING path; ! 100: STRING name; ! 101: { ! 102: /* leaves result on top of stack */ ! 103: REG STRING scanp = path, ! 104: argp = locstak(); ! 105: ! 106: WHILE *scanp ANDF *scanp!=COLON DO *argp++ = *scanp++ OD ! 107: IF scanp!=path THEN *argp++='/' FI ! 108: IF *scanp==COLON THEN scanp++ FI ! 109: path=(*scanp ? scanp : 0); scanp=name; ! 110: WHILE (*argp++ = *scanp++) DONE ! 111: return(path); ! 112: } ! 113: ! 114: LOCAL STRING xecmsg; ! 115: LOCAL STRING *xecenv; ! 116: ! 117: VOID execa(at) ! 118: STRING at[]; ! 119: { ! 120: REG STRING path; ! 121: REG STRING *t = at; ! 122: ! 123: IF (flags&noexec)==0 ! 124: THEN xecmsg=notfound; path=getpath(*t); ! 125: namscan(exname); ! 126: xecenv=setenv(); ! 127: WHILE path=execs(path,t) DONE ! 128: failed(*t,xecmsg); ! 129: FI ! 130: } ! 131: ! 132: LOCAL STRING execs(ap,t) ! 133: STRING ap; ! 134: REG STRING t[]; ! 135: { ! 136: REG STRING p, prefix; ! 137: ! 138: prefix=catpath(ap,t[0]); ! 139: trim(p=curstak()); ! 140: ! 141: sigchk(); ! 142: execve(p, &t[0] ,xecenv); ! 143: SWITCH errno IN ! 144: ! 145: case ENOEXEC: ! 146: flags=0; ! 147: comdiv=0; ioset=0; ! 148: clearup(); /* remove open files and for loop junk */ ! 149: IF input THEN close(input) FI ! 150: close(output); output=2; ! 151: input=chkopen(p); ! 152: ! 153: /* band aid to get csh... 2/26/79 */ ! 154: { ! 155: char c; ! 156: if (!isatty(input)) { ! 157: read(input, &c, 1); ! 158: if (c == '#') ! 159: gocsh(t, p, xecenv); ! 160: lseek(input, (long) 0, 0); ! 161: } ! 162: } ! 163: ! 164: /* set up new args */ ! 165: setargs(t); ! 166: longjmp(subshell,1); ! 167: ! 168: case ENOMEM: ! 169: failed(p,toobig); ! 170: ! 171: case E2BIG: ! 172: failed(p,arglist); ! 173: ! 174: case ETXTBSY: ! 175: failed(p,txtbsy); ! 176: ! 177: default: ! 178: xecmsg=badexec; ! 179: case ENOENT: ! 180: return(prefix); ! 181: ENDSW ! 182: } ! 183: ! 184: gocsh(t, cp, xecenv) ! 185: register char **t, *cp, **xecenv; ! 186: { ! 187: char **newt[1000]; ! 188: register char **p; ! 189: register int i; ! 190: ! 191: for (i = 0; t[i]; i++) ! 192: newt[i+1] = t[i]; ! 193: newt[i+1] = 0; ! 194: newt[0] = "/bin/csh"; ! 195: newt[1] = cp; ! 196: execve("/bin/csh", newt, xecenv); ! 197: } ! 198: ! 199: /* for processes to be waited for */ ! 200: #define MAXP 20 ! 201: LOCAL INT pwlist[MAXP]; ! 202: LOCAL INT pwc; ! 203: ! 204: postclr() ! 205: { ! 206: REG INT *pw = pwlist; ! 207: ! 208: WHILE pw <= &pwlist[pwc] ! 209: DO *pw++ = 0 OD ! 210: pwc=0; ! 211: } ! 212: ! 213: VOID post(pcsid) ! 214: INT pcsid; ! 215: { ! 216: REG INT *pw = pwlist; ! 217: ! 218: IF pcsid ! 219: THEN WHILE *pw DO pw++ OD ! 220: IF pwc >= MAXP-1 ! 221: THEN pw--; ! 222: ELSE pwc++; ! 223: FI ! 224: *pw = pcsid; ! 225: FI ! 226: } ! 227: ! 228: VOID await(i) ! 229: INT i; ! 230: { ! 231: INT rc=0, wx=0; ! 232: INT w; ! 233: INT ipwc = pwc; ! 234: ! 235: post(i); ! 236: WHILE pwc ! 237: DO REG INT p; ! 238: REG INT sig; ! 239: INT w_hi; ! 240: ! 241: BEGIN ! 242: REG INT *pw=pwlist; ! 243: IF setjmp(INTbuf) == 0 ! 244: THEN trapjmp[INTR] = 1; p=wait(&w); ! 245: ELSE p = -1; ! 246: FI ! 247: trapjmp[INTR] = 0; ! 248: WHILE pw <= &pwlist[ipwc] ! 249: DO IF *pw==p ! 250: THEN *pw=0; pwc--; ! 251: ELSE pw++; ! 252: FI ! 253: OD ! 254: END ! 255: ! 256: IF p == -1 THEN continue FI ! 257: ! 258: w_hi = (w>>8)&LOBYTE; ! 259: ! 260: IF sig = w&0177 ! 261: THEN IF sig == 0177 /* ptrace! return */ ! 262: THEN prs("ptrace: "); ! 263: sig = w_hi; ! 264: FI ! 265: IF sig < num_sysmsg ANDF sysmsg[sig] ! 266: THEN IF i!=p ORF (flags&prompt)==0 ! 267: THEN prp(); prn(p); blank() ! 268: FI ! 269: prs(sysmsg[sig]); ! 270: IF w&0200 THEN prs(coredump) FI ! 271: FI ! 272: newline(); ! 273: FI ! 274: ! 275: IF rc==0 ! 276: THEN rc = (sig ? sig|SIGFLG : w_hi); ! 277: FI ! 278: wx |= w; ! 279: OD ! 280: ! 281: IF wx ANDF flags&errflg ! 282: THEN exitsh(rc); ! 283: FI ! 284: exitval=rc; exitset(); ! 285: } ! 286: ! 287: BOOL nosubst; ! 288: ! 289: trim(at) ! 290: STRING at; ! 291: { ! 292: REG STRING p; ! 293: REG CHAR c; ! 294: REG CHAR q=0; ! 295: ! 296: IF p=at ! 297: THEN WHILE c = *p ! 298: DO *p++=c&STRIP; q |= c OD ! 299: FI ! 300: nosubst=q"E; ! 301: } ! 302: ! 303: STRING mactrim(s) ! 304: STRING s; ! 305: { ! 306: REG STRING t=macro(s); ! 307: trim(t); ! 308: return(t); ! 309: } ! 310: ! 311: STRING *scan(argn) ! 312: INT argn; ! 313: { ! 314: REG ARGPTR argp = Rcheat(gchain)&~ARGMK; ! 315: REG STRING *comargn, *comargm; ! 316: ! 317: comargn=getstak(BYTESPERWORD*argn+BYTESPERWORD); comargm = comargn += argn; *comargn = ENDARGS; ! 318: ! 319: WHILE argp ! 320: DO *--comargn = argp->argval; ! 321: IF argp = argp->argnxt ! 322: THEN trim(*comargn); ! 323: FI ! 324: IF argp==0 ORF Rcheat(argp)&ARGMK ! 325: THEN gsort(comargn,comargm); ! 326: comargm = comargn; ! 327: FI ! 328: /* Lcheat(argp) &= ~ARGMK; */ ! 329: argp = Rcheat(argp)&~ARGMK; ! 330: OD ! 331: return(comargn); ! 332: } ! 333: ! 334: LOCAL VOID gsort(from,to) ! 335: STRING from[], to[]; ! 336: { ! 337: INT k, m, n; ! 338: REG INT i, j; ! 339: ! 340: IF (n=to-from)<=1 THEN return FI ! 341: ! 342: FOR j=1; j<=n; j*=2 DONE ! 343: ! 344: FOR m=2*j-1; m/=2; ! 345: DO k=n-m; ! 346: FOR j=0; j<k; j++ ! 347: DO FOR i=j; i>=0; i-=m ! 348: DO REG STRING *fromi; fromi = &from[i]; ! 349: IF cf(fromi[m],fromi[0])>0 ! 350: THEN break; ! 351: ELSE STRING s; s=fromi[m]; fromi[m]=fromi[0]; fromi[0]=s; ! 352: FI ! 353: OD ! 354: OD ! 355: OD ! 356: } ! 357: ! 358: /* Argument list generation */ ! 359: ! 360: INT getarg(ac) ! 361: COMPTR ac; ! 362: { ! 363: REG ARGPTR argp; ! 364: REG INT count=0; ! 365: REG COMPTR c; ! 366: ! 367: IF c=ac ! 368: THEN argp=c->comarg; ! 369: WHILE argp ! 370: DO count += split(macro(argp->argval)); ! 371: argp=argp->argnxt; ! 372: OD ! 373: FI ! 374: return(count); ! 375: } ! 376: ! 377: LOCAL INT split(s) ! 378: REG STRING s; ! 379: { ! 380: REG STRING argp; ! 381: REG INT c; ! 382: INT count=0; ! 383: ! 384: LOOP sigchk(); argp=locstak()+BYTESPERWORD; ! 385: WHILE (c = *s++, !any(c,ifsnod.namval) && c) ! 386: DO *argp++ = c OD ! 387: IF argp==staktop+BYTESPERWORD ! 388: THEN IF c ! 389: THEN continue; ! 390: ELSE return(count); ! 391: FI ! 392: ELIF c==0 ! 393: THEN s--; ! 394: FI ! 395: IF c=expand((argp=endstak(argp))->argval,0) ! 396: THEN count += c; ! 397: ELSE /* assign(&fngnod, argp->argval); */ ! 398: makearg(argp); count++; ! 399: FI ! 400: Lcheat(gchain) |= ARGMK; ! 401: POOL ! 402: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.