Annotation of 43BSD/bin/sh/service.c, revision 1.1

1.1     ! root        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: }

unix.superglobalmegacorp.com

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