Annotation of 42BSD/bin/sh/service.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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