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