Annotation of 40BSD/cmd/sh/service.c, revision 1.1.1.1

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: 
                     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:                /* band aid to get csh... 2/26/79 */
                    149:                {
                    150:                        char c;
                    151:                        if (!isatty(input)) {
                    152:                                read(input, &c, 1);
                    153:                                if (c == '#')
                    154:                                        gocsh(t, p, xecenv);
                    155:                                lseek(input, (long) 0, 0);
                    156:                        }
                    157:                }
                    158: 
                    159:                /* set up new args */
                    160:                setargs(t);
                    161:                longjmp(subshell,1);
                    162: 
                    163:            case ENOMEM:
                    164:                failed(p,toobig);
                    165: 
                    166:            case E2BIG:
                    167:                failed(p,arglist);
                    168: 
                    169:            case ETXTBSY:
                    170:                failed(p,txtbsy);
                    171: 
                    172:            default:
                    173:                xecmsg=badexec;
                    174:            case ENOENT:
                    175:                return(prefix);
                    176:        ENDSW
                    177: }
                    178: 
                    179: gocsh(t, cp, xecenv)
                    180:        register char **t, *cp, **xecenv;
                    181: {
                    182:        char **newt[1000];
                    183:        register char **p;
                    184:        register int i;
                    185: 
                    186:        for (i = 0; t[i]; i++)
                    187:                newt[i+1] = t[i];
                    188:        newt[i+1] = 0;
                    189:        newt[0] = "/bin/csh";
                    190:        newt[1] = cp;
                    191:        execve("/bin/csh", newt, xecenv);
                    192: }
                    193: 
                    194: /* for processes to be waited for */
                    195: #define MAXP 20
                    196: LOCAL INT      pwlist[MAXP];
                    197: LOCAL INT      pwc;
                    198: 
                    199: postclr()
                    200: {
                    201:        REG INT         *pw = pwlist;
                    202: 
                    203:        WHILE pw <= &pwlist[pwc]
                    204:        DO *pw++ = 0 OD
                    205:        pwc=0;
                    206: }
                    207: 
                    208: VOID   post(pcsid)
                    209:        INT             pcsid;
                    210: {
                    211:        REG INT         *pw = pwlist;
                    212: 
                    213:        IF pcsid
                    214:        THEN    WHILE *pw DO pw++ OD
                    215:                IF pwc >= MAXP-1
                    216:                THEN    pw--;
                    217:                ELSE    pwc++;
                    218:                FI
                    219:                *pw = pcsid;
                    220:        FI
                    221: }
                    222: 
                    223: VOID   await(i)
                    224:        INT             i;
                    225: {
                    226:        INT             rc=0, wx=0;
                    227:        INT             w;
                    228:        INT             ipwc = pwc;
                    229: 
                    230:        post(i);
                    231:        WHILE pwc
                    232:        DO      REG INT         p;
                    233:                REG INT         sig;
                    234:                INT             w_hi;
                    235: 
                    236:                BEGIN
                    237:                   REG INT      *pw=pwlist;
                    238:                   p=wait(&w);
                    239:                   WHILE pw <= &pwlist[ipwc]
                    240:                   DO IF *pw==p
                    241:                      THEN *pw=0; pwc--;
                    242:                      ELSE pw++;
                    243:                      FI
                    244:                   OD
                    245:                END
                    246: 
                    247:                IF p == -1 THEN continue FI
                    248: 
                    249:                w_hi = (w>>8)&LOBYTE;
                    250: 
                    251:                IF sig = w&0177
                    252:                THEN    IF sig == 0177  /* ptrace! return */
                    253:                        THEN    prs("ptrace: ");
                    254:                                sig = w_hi;
                    255:                        FI
                    256:                        IF sysmsg[sig]
                    257:                        THEN    IF i!=p ORF (flags&prompt)==0 THEN prp(); prn(p); blank() FI
                    258:                                prs(sysmsg[sig]);
                    259:                                IF w&0200 THEN prs(coredump) FI
                    260:                        FI
                    261:                        newline();
                    262:                FI
                    263: 
                    264:                IF rc==0
                    265:                THEN    rc = (sig ? sig|SIGFLG : w_hi);
                    266:                FI
                    267:                wx |= w;
                    268:        OD
                    269: 
                    270:        IF wx ANDF flags&errflg
                    271:        THEN    exitsh(rc);
                    272:        FI
                    273:        exitval=rc; exitset();
                    274: }
                    275: 
                    276: BOOL           nosubst;
                    277: 
                    278: trim(at)
                    279:        STRING          at;
                    280: {
                    281:        REG STRING      p;
                    282:        REG CHAR        c;
                    283:        REG CHAR        q=0;
                    284: 
                    285:        IF p=at
                    286:        THEN    WHILE c = *p
                    287:                DO *p++=c&STRIP; q |= c OD
                    288:        FI
                    289:        nosubst=q&QUOTE;
                    290: }
                    291: 
                    292: STRING mactrim(s)
                    293:        STRING          s;
                    294: {
                    295:        REG STRING      t=macro(s);
                    296:        trim(t);
                    297:        return(t);
                    298: }
                    299: 
                    300: STRING *scan(argn)
                    301:        INT             argn;
                    302: {
                    303:        REG ARGPTR      argp = Rcheat(gchain)&~ARGMK;
                    304:        REG STRING      *comargn, *comargm;
                    305: 
                    306:        comargn=getstak(BYTESPERWORD*argn+BYTESPERWORD); comargm = comargn += argn; *comargn = ENDARGS;
                    307: 
                    308:        WHILE argp
                    309:        DO      *--comargn = argp->argval;
                    310:                IF argp = argp->argnxt
                    311:                THEN trim(*comargn);
                    312:                FI
                    313:                IF argp==0 ORF Rcheat(argp)&ARGMK
                    314:                THEN    gsort(comargn,comargm);
                    315:                        comargm = comargn;
                    316:                FI
                    317:                /* Lcheat(argp) &= ~ARGMK; */
                    318:                argp = Rcheat(argp)&~ARGMK;
                    319:        OD
                    320:        return(comargn);
                    321: }
                    322: 
                    323: LOCAL VOID     gsort(from,to)
                    324:        STRING          from[], to[];
                    325: {
                    326:        INT             k, m, n;
                    327:        REG INT         i, j;
                    328: 
                    329:        IF (n=to-from)<=1 THEN return FI
                    330: 
                    331:        FOR j=1; j<=n; j*=2 DONE
                    332: 
                    333:        FOR m=2*j-1; m/=2;
                    334:        DO  k=n-m;
                    335:            FOR j=0; j<k; j++
                    336:            DO  FOR i=j; i>=0; i-=m
                    337:                DO  REG STRING *fromi; fromi = &from[i];
                    338:                    IF cf(fromi[m],fromi[0])>0
                    339:                    THEN break;
                    340:                    ELSE STRING s; s=fromi[m]; fromi[m]=fromi[0]; fromi[0]=s;
                    341:                    FI
                    342:                OD
                    343:            OD
                    344:        OD
                    345: }
                    346: 
                    347: /* Argument list generation */
                    348: 
                    349: INT    getarg(ac)
                    350:        COMPTR          ac;
                    351: {
                    352:        REG ARGPTR      argp;
                    353:        REG INT         count=0;
                    354:        REG COMPTR      c;
                    355: 
                    356:        IF c=ac
                    357:        THEN    argp=c->comarg;
                    358:                WHILE argp
                    359:                DO      count += split(macro(argp->argval));
                    360:                        argp=argp->argnxt;
                    361:                OD
                    362:        FI
                    363:        return(count);
                    364: }
                    365: 
                    366: LOCAL INT      split(s)
                    367:        REG STRING      s;
                    368: {
                    369:        REG STRING      argp;
                    370:        REG INT         c;
                    371:        INT             count=0;
                    372: 
                    373:        LOOP    sigchk(); argp=locstak()+BYTESPERWORD;
                    374:                WHILE (c = *s++, !any(c,ifsnod.namval) && c)
                    375:                DO *argp++ = c OD
                    376:                IF argp==staktop+BYTESPERWORD
                    377:                THEN    IF c
                    378:                        THEN    continue;
                    379:                        ELSE    return(count);
                    380:                        FI
                    381:                ELIF c==0
                    382:                THEN    s--;
                    383:                FI
                    384:                IF c=expand((argp=endstak(argp))->argval,0)
                    385:                THEN    count += c;
                    386:                ELSE    /* assign(&fngnod, argp->argval); */
                    387:                        makearg(argp); count++;
                    388:                FI
                    389:                Lcheat(gchain) |= ARGMK;
                    390:        POOL
                    391: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.