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&QUOTE;
 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: }

Defined functions

await defined in line 228; used 4 times
catpath defined in line 98; used 3 times
execa defined in line 117; used 2 times
execs defined in line 132; used 2 times
getarg defined in line 360; used 2 times
getpath defined in line 73; used 3 times
gocsh defined in line 184; used 1 times
gsort defined in line 334; used 2 times
initio defined in line 36; used 3 times
mactrim defined in line 303; used 5 times
pathopen defined in line 88; used 2 times
post defined in line 213; used 3 times
postclr defined in line 204; used 1 times
scan defined in line 311; used 3 times
split defined in line 377; used 1 times
trim defined in line 289; used 6 times

Defined variables

sccsid defined in line 2; never used

Defined macros

ARGMK defined in line 19; used 4 times
E2BIG defined in line 28; never used
ENOENT defined in line 29; never used
ENOEXEC defined in line 27; never used
ENOMEM defined in line 26; never used
ETXTBSY defined in line 30; never used
MAXP defined in line 200; used 2 times
Last modified: 1985-03-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1622
Valid CSS Valid XHTML 1.0 Strict