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

Defined functions

await defined in line 197; used 4 times
catpath defined in line 93; used 3 times
execa defined in line 112; used 2 times
execs defined in line 127; used 2 times
getarg defined in line 323; used 2 times
getpath defined in line 68; used 3 times
gsort defined in line 297; used 2 times
initio defined in line 31; used 3 times
mactrim defined in line 266; used 5 times
pathopen defined in line 83; used 2 times
post defined in line 182; used 3 times
postclr defined in line 173; used 1 times
scan defined in line 274; used 3 times
split defined in line 340; used 1 times
trim defined in line 252; used 6 times

Defined macros

ARGMK defined in line 15; used 4 times
E2BIG defined in line 23; never used
ENOENT defined in line 24; never used
ENOEXEC defined in line 22; never used
ENOMEM defined in line 21; never used
ETXTBSY defined in line 25; never used
MAXP defined in line 169; used 2 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1392
Valid CSS Valid XHTML 1.0 Strict