Annotation of 43BSDReno/bin/sh/service.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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