Annotation of 3BSD/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, 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, xecenv)
                    180:        register char **t, **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:        execve("/bin/csh", 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:                   p=wait(&w);
                    238:                   WHILE pw <= &pwlist[ipwc]
                    239:                   DO IF *pw==p
                    240:                      THEN *pw=0; pwc--;
                    241:                      ELSE pw++;
                    242:                      FI
                    243:                   OD
                    244:                END
                    245: 
                    246:                IF p == -1 THEN continue FI
                    247: 
                    248:                w_hi = (w>>8)&LOBYTE;
                    249: 
                    250:                IF sig = w&0177
                    251:                THEN    IF sig == 0177  /* ptrace! return */
                    252:                        THEN    prs("ptrace: ");
                    253:                                sig = w_hi;
                    254:                        FI
                    255:                        IF sysmsg[sig]
                    256:                        THEN    IF i!=p ORF (flags&prompt)==0 THEN prp(); prn(p); blank() FI
                    257:                                prs(sysmsg[sig]);
                    258:                                IF w&0200 THEN prs(coredump) FI
                    259:                        FI
                    260:                        newline();
                    261:                FI
                    262: 
                    263:                IF rc==0
                    264:                THEN    rc = (sig ? sig|SIGFLG : w_hi);
                    265:                FI
                    266:                wx |= w;
                    267:        OD
                    268: 
                    269:        IF wx ANDF flags&errflg
                    270:        THEN    exitsh(rc);
                    271:        FI
                    272:        exitval=rc; exitset();
                    273: }
                    274: 
                    275: BOOL           nosubst;
                    276: 
                    277: trim(at)
                    278:        STRING          at;
                    279: {
                    280:        REG STRING      p;
                    281:        REG CHAR        c;
                    282:        REG CHAR        q=0;
                    283: 
                    284:        IF p=at
                    285:        THEN    WHILE c = *p
                    286:                DO *p++=c&STRIP; q |= c OD
                    287:        FI
                    288:        nosubst=q&QUOTE;
                    289: }
                    290: 
                    291: STRING mactrim(s)
                    292:        STRING          s;
                    293: {
                    294:        REG STRING      t=macro(s);
                    295:        trim(t);
                    296:        return(t);
                    297: }
                    298: 
                    299: STRING *scan(argn)
                    300:        INT             argn;
                    301: {
                    302:        REG ARGPTR      argp = Rcheat(gchain)&~ARGMK;
                    303:        REG STRING      *comargn, *comargm;
                    304: 
                    305:        comargn=getstak(BYTESPERWORD*argn+BYTESPERWORD); comargm = comargn += argn; *comargn = ENDARGS;
                    306: 
                    307:        WHILE argp
                    308:        DO      *--comargn = argp->argval;
                    309:                IF argp = argp->argnxt
                    310:                THEN trim(*comargn);
                    311:                FI
                    312:                IF argp==0 ORF Rcheat(argp)&ARGMK
                    313:                THEN    gsort(comargn,comargm);
                    314:                        comargm = comargn;
                    315:                FI
                    316:                /* Lcheat(argp) &= ~ARGMK; */
                    317:                argp = Rcheat(argp)&~ARGMK;
                    318:        OD
                    319:        return(comargn);
                    320: }
                    321: 
                    322: LOCAL VOID     gsort(from,to)
                    323:        STRING          from[], to[];
                    324: {
                    325:        INT             k, m, n;
                    326:        REG INT         i, j;
                    327: 
                    328:        IF (n=to-from)<=1 THEN return FI
                    329: 
                    330:        FOR j=1; j<=n; j*=2 DONE
                    331: 
                    332:        FOR m=2*j-1; m/=2;
                    333:        DO  k=n-m;
                    334:            FOR j=0; j<k; j++
                    335:            DO  FOR i=j; i>=0; i-=m
                    336:                DO  REG STRING *fromi; fromi = &from[i];
                    337:                    IF cf(fromi[m],fromi[0])>0
                    338:                    THEN break;
                    339:                    ELSE STRING s; s=fromi[m]; fromi[m]=fromi[0]; fromi[0]=s;
                    340:                    FI
                    341:                OD
                    342:            OD
                    343:        OD
                    344: }
                    345: 
                    346: /* Argument list generation */
                    347: 
                    348: INT    getarg(ac)
                    349:        COMPTR          ac;
                    350: {
                    351:        REG ARGPTR      argp;
                    352:        REG INT         count=0;
                    353:        REG COMPTR      c;
                    354: 
                    355:        IF c=ac
                    356:        THEN    argp=c->comarg;
                    357:                WHILE argp
                    358:                DO      count += split(macro(argp->argval));
                    359:                        argp=argp->argnxt;
                    360:                OD
                    361:        FI
                    362:        return(count);
                    363: }
                    364: 
                    365: LOCAL INT      split(s)
                    366:        REG STRING      s;
                    367: {
                    368:        REG STRING      argp;
                    369:        REG INT         c;
                    370:        INT             count=0;
                    371: 
                    372:        LOOP    sigchk(); argp=locstak()+BYTESPERWORD;
                    373:                WHILE (c = *s++, !any(c,ifsnod.namval) && c)
                    374:                DO *argp++ = c OD
                    375:                IF argp==staktop+BYTESPERWORD
                    376:                THEN    IF c
                    377:                        THEN    continue;
                    378:                        ELSE    return(count);
                    379:                        FI
                    380:                ELIF c==0
                    381:                THEN    s--;
                    382:                FI
                    383:                IF c=expand((argp=endstak(argp))->argval,0)
                    384:                THEN    count += c;
                    385:                ELSE    /* assign(&fngnod, argp->argval); */
                    386:                        makearg(argp); count++;
                    387:                FI
                    388:                Lcheat(gchain) |= ARGMK;
                    389:        POOL
                    390: }

unix.superglobalmegacorp.com

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