Annotation of researchv9/cmd/sh/service.c, revision 1.1.1.1

1.1       root        1: /*     @(#)service.c   1.11    */
                      2: /*
                      3:  * UNIX shell
                      4:  *
                      5:  * Bell Telephone Laboratories
                      6:  *
                      7:  */
                      8: 
                      9: #include       "defs.h"
                     10: #include       <errno.h>
                     11: 
                     12: #ifdef CRAY
                     13: #define        ARGMK   040000000
                     14: #else
                     15: #define ARGMK  01
                     16: #endif
                     17: 
                     18: static int     gsort();
                     19: static int     split();
                     20: extern char    *sysmsg[];
                     21: extern short topfd;
                     22: 
                     23: 
                     24: 
                     25: /*
                     26:  * service routines for `execute'
                     27:  */
                     28: initio(iop, save)
                     29:        struct ionod    *iop;
                     30:        int             save;
                     31: {
                     32:        register char   *ion;
                     33:        register int    iof, fd;
                     34:        int             ioufd;
                     35:        short   lastfd;
                     36: 
                     37:        lastfd = topfd;
                     38:        while (iop)
                     39:        {
                     40:                iof = iop->iofile;
                     41:                ion = mactrim(iop->ioname);
                     42:                ioufd = iof & IOUFD;
                     43: 
                     44:                if (*ion && (flags&noexec) == 0)
                     45:                {
                     46:                        if (save)
                     47:                        {
                     48:                                fdmap[topfd].org_fd = ioufd;
                     49:                                fdmap[topfd++].dup_fd = savefd(ioufd);
                     50:                        }
                     51: 
                     52:                        if (iof & IODOC)
                     53:                        {
                     54:                                struct tempblk tb;
                     55: 
                     56:                                subst(chkopen(ion), (fd = tmpfil(&tb)));
                     57: 
                     58:                                poptemp();      /* pushed in tmpfil() --
                     59:                                                   bug fix for problem with
                     60:                                                   in-line scripts
                     61:                                                */
                     62: 
                     63:                                fd = chkopen(tmpout);
                     64:                                unlink(tmpout);
                     65:                        }
                     66:                        else if (iof & IOMOV)
                     67:                        {
                     68:                                if (eq(minus, ion))
                     69:                                {
                     70:                                        fd = -1;
                     71:                                        close(ioufd);
                     72:                                }
                     73:                                else if ((fd = stoi(ion)) >= USERIO)
                     74:                                        failed(ion, badfile);
                     75:                                else
                     76:                                        fd = dup(fd);
                     77:                        }
                     78:                        else if ((iof & IOPUT) == 0)
                     79:                                fd = chkopen(ion);
                     80:                        else if (iof & IOAPP && (fd = open(ion, 1)) >= 0)
                     81:                                lseek(fd, 0L, 2);
                     82:                        else
                     83:                                fd = create(ion);
                     84:                        if (fd >= 0)
                     85:                                rename(fd, ioufd);
                     86:                }
                     87: 
                     88:                iop = iop->ionxt;
                     89:        }
                     90:        if (histfd > 0) {
                     91:                close (histfd);
                     92:                histfd = 0;
                     93:        }
                     94:        return(lastfd);
                     95: }
                     96: 
                     97: char *
                     98: simple(s)
                     99: char   *s;
                    100: {
                    101:        char    *sname;
                    102: 
                    103:        sname = s;
                    104:        while (1)
                    105:        {
                    106:                if (any('/', sname))
                    107:                        while (*sname++ != '/')
                    108:                                ;
                    109:                else
                    110:                        return(sname);
                    111:        }
                    112: }
                    113: 
                    114: char *
                    115: getpath(s)
                    116:        char    *s;
                    117: {
                    118:        register char   *path;
                    119: 
                    120:        if (any('/', s) || any(('/' | QUOTE), s))
                    121:        {
                    122:                return(nullstr);
                    123:        }
                    124:        else if ((path = pathnod.namval.val) == 0)
                    125:                return(defpath);
                    126:        else
                    127:                return(cpystak(path));
                    128: }
                    129: 
                    130: pathopen(path, name)
                    131: register char *path, *name;
                    132: {
                    133:        register int    f;
                    134: 
                    135:        do
                    136:        {
                    137:                path = catpath(path, name);
                    138:        } while ((f = open(curstak(), 0)) < 0 && path);
                    139:        return(f);
                    140: }
                    141: 
                    142: char *
                    143: catpath(path, name)
                    144: register char  *path;
                    145: char   *name;
                    146: {
                    147:        /*
                    148:         * leaves result on top of stack
                    149:         */
                    150:        register char   *scanp = path;
                    151:        register char   *argp = locstak();
                    152: 
                    153:        while (*scanp && *scanp != COLON)
                    154:                pushstak(*scanp++);
                    155:        if (scanp != path)
                    156:                pushstak('/');
                    157:        if (*scanp == COLON)
                    158:                scanp++;
                    159:        path = (*scanp ? scanp : 0);
                    160:        scanp = name;
                    161:        do
                    162:                pushstak(*scanp);
                    163:        while(*scanp++);
                    164:        staktop=argp;
                    165:        return path;
                    166: }
                    167: 
                    168: char *
                    169: nextpath(path)
                    170:        register char   *path;
                    171: {
                    172:        register char   *scanp = path;
                    173: 
                    174:        while (*scanp && *scanp != COLON)
                    175:                scanp++;
                    176: 
                    177:        if (*scanp == COLON)
                    178:                scanp++;
                    179: 
                    180:        return(*scanp ? scanp : 0);
                    181: }
                    182: 
                    183: static char    *xecmsg;
                    184: static char    **xecenv;
                    185: 
                    186: int    execa(at)
                    187:        char    *at[];
                    188: {
                    189:        register char   *path;
                    190:        register char   **t = at;
                    191:        int             cnt;
                    192: 
                    193:        if ((flags & noexec) == 0)
                    194:        {
                    195:                xecmsg = notfound;
                    196:                path = getpath(*t);
                    197:                xecenv = setenv();
                    198: 
                    199:                while (path = execs(path,t))
                    200:                        ;
                    201:                failed(*t, xecmsg);
                    202:        }
                    203: }
                    204: 
                    205: char *
                    206: execs(ap, t)
                    207: char   *ap;
                    208: register char  *t[];
                    209: {
                    210:        register char *p, *prefix;
                    211: 
                    212:        prefix = catpath(ap, t[0]);
                    213:        trim(p = curstak());
                    214:        sigchk();
                    215:        
                    216:        execve(p, &t[0] ,xecenv);
                    217:        switch (errno)
                    218:        {
                    219:        case ENOEXEC:           /* could be a shell script */
                    220:                funcnt = 0;
                    221:                flags = 0;
                    222:                *flagadr = 0;
                    223:                comdiv = 0;
                    224:                ioset = 0;
                    225:                clearup();      /* remove open files and for loop junk */
                    226:                if (input)
                    227:                        close(input);
                    228:                input = chkopen(p);
                    229:        
                    230: #ifdef ACCT
                    231:                preacct(p);     /* reset accounting */
                    232: #endif
                    233: 
                    234:                /*
                    235:                 * set up new args
                    236:                 */
                    237:                
                    238:                setargs(t);
                    239:                longjmp(subshell, 1);
                    240: 
                    241:        case ENOMEM:
                    242:                failed(p, toobig);
                    243: 
                    244:        case E2BIG:
                    245:                failed(p, arglist);
                    246: 
                    247:        case ETXTBSY:
                    248:                failed(p, txtbsy);
                    249: 
                    250:        default:
                    251:                xecmsg = badexec;
                    252:        case ENOENT:
                    253:                return(prefix);
                    254:        }
                    255: }
                    256: 
                    257: 
                    258: /*
                    259:  * for processes to be waited for
                    260:  */
                    261: #define MAXP 20
                    262: static int     pwlist[MAXP];
                    263: static int     pwc;
                    264: 
                    265: postclr()
                    266: {
                    267:        register int    *pw = pwlist;
                    268: 
                    269:        while (pw <= &pwlist[pwc])
                    270:                *pw++ = 0;
                    271:        pwc = 0;
                    272: }
                    273: 
                    274: post(pcsid)
                    275: int    pcsid;
                    276: {
                    277:        register int    *pw = pwlist;
                    278: 
                    279:        if (pcsid)
                    280:        {
                    281:                while (*pw)
                    282:                        pw++;
                    283:                if (pwc >= MAXP - 1)
                    284:                        pw--;
                    285:                else
                    286:                        pwc++;
                    287:                *pw = pcsid;
                    288:        }
                    289: }
                    290: 
                    291: await(i, bckg)
                    292: int    i, bckg;
                    293: {
                    294:        int     rc = 0, wx = 0;
                    295:        int     w;
                    296:        int     ipwc = pwc;
                    297: 
                    298:        post(i);
                    299:        while (pwc)
                    300:        {
                    301:                register int    p;
                    302:                register int    sig;
                    303:                int             w_hi;
                    304:                int     found = 0;
                    305: 
                    306:                {
                    307:                        register int    *pw = pwlist;
                    308: 
                    309:                        p = wait(&w);
                    310:                        if (wasintr)
                    311:                        {
                    312:                                wasintr = 0;
                    313:                                if (bckg)
                    314:                                {
                    315:                                        break;
                    316:                                }
                    317:                        }
                    318:                        while (pw <= &pwlist[ipwc])
                    319:                        {
                    320:                                if (*pw == p)
                    321:                                {
                    322:                                        *pw = 0;
                    323:                                        pwc--;
                    324:                                        found++;
                    325:                                }
                    326:                                else
                    327:                                        pw++;
                    328:                        }
                    329:                }
                    330:                if (p == -1)
                    331:                {
                    332:                        if (bckg)
                    333:                        {
                    334:                                register int *pw = pwlist;
                    335: 
                    336:                                while (pw <= &pwlist[ipwc] && i != *pw)
                    337:                                        pw++;
                    338:                                if (i == *pw)
                    339:                                {
                    340:                                        *pw = 0;
                    341:                                        pwc--;
                    342:                                }
                    343:                        }
                    344:                        continue;
                    345:                }
                    346:                w_hi = (w >> 8) & LOBYTE;
                    347:                if (sig = w & 0177)
                    348:                {
                    349:                        if (sig == 0177)        /* ptrace! return */
                    350:                        {
                    351:                                prs("ptrace: ");
                    352:                                sig = w_hi;
                    353:                        }
                    354:                        if (sysmsg[sig])
                    355:                        {
                    356:                                if (i != p || (flags & prompt) == 0)
                    357:                                {
                    358:                                        prp();
                    359:                                        prn(p);
                    360:                                        blank();
                    361:                                }
                    362:                                prs(sysmsg[sig]);
                    363:                                if (w & 0200)
                    364:                                        prs(coredump);
                    365:                        }
                    366:                        newline();
                    367:                }
                    368:                if (rc == 0 && found != 0)
                    369:                        rc = (sig ? sig | SIGFLG : w_hi);
                    370:                wx |= w;
                    371:                if (p == i)
                    372:                {
                    373:                        break;
                    374:                }
                    375:        }
                    376:        if (wx && flags & errflg)
                    377:                exitsh(rc);
                    378:        flags |= eflag;
                    379:        exitval = rc;
                    380:        exitset();
                    381: }
                    382: 
                    383: BOOL           nosubst;
                    384: 
                    385: trim(at)
                    386: char   *at;
                    387: {
                    388:        register char   *p;
                    389:        register char   *ptr;
                    390:        register char   c;
                    391:        register char   q = 0;
                    392: 
                    393:        if (p = at)
                    394:        {
                    395:                ptr = p;
                    396:                while (c = *p++)
                    397:                {
                    398:                        if (*ptr = c & STRIP)
                    399:                                ++ptr;
                    400:                        q |= c;
                    401:                }
                    402: 
                    403:                *ptr = 0;
                    404:        }
                    405:        nosubst = q & QUOTE;
                    406: }
                    407: 
                    408: char *
                    409: mactrim(s)
                    410: char   *s;
                    411: {
                    412:        register char   *t = macro(s);
                    413: 
                    414:        trim(t);
                    415:        return(t);
                    416: }
                    417: 
                    418: char **
                    419: scan(argn)
                    420: int    argn;
                    421: {
                    422:        register struct argnod *argp = (struct argnod *)(Rcheat(gchain) & ~ARGMK);
                    423:        register char **comargn, **comargm;
                    424: 
                    425:        comargn = (char **)getstak(BYTESPERWORD * argn + BYTESPERWORD);
                    426:        comargm = comargn += argn;
                    427:        *comargn = ENDARGS;
                    428:        while (argp)
                    429:        {
                    430:                *--comargn = argp->argval;
                    431: 
                    432:                trim(*comargn);
                    433:                argp = argp->argnxt;
                    434: 
                    435:                if (argp == 0 || Rcheat(argp) & ARGMK)
                    436:                {
                    437:                        gsort(comargn, comargm);
                    438:                        comargm = comargn;
                    439:                }
                    440:                /* Lcheat(argp) &= ~ARGMK; */
                    441:                argp = (struct argnod *)(Rcheat(argp) & ~ARGMK);
                    442:        }
                    443:        return(comargn);
                    444: }
                    445: 
                    446: static int
                    447: gsort(from, to)
                    448: char   *from[], *to[];
                    449: {
                    450:        int     k, m, n;
                    451:        register int    i, j;
                    452: 
                    453:        if ((n = to - from) <= 1)
                    454:                return;
                    455:        for (j = 1; j <= n; j *= 2)
                    456:                ;
                    457:        for (m = 2 * j - 1; m /= 2; )
                    458:        {
                    459:                k = n - m;
                    460:                for (j = 0; j < k; j++)
                    461:                {
                    462:                        for (i = j; i >= 0; i -= m)
                    463:                        {
                    464:                                register char **fromi;
                    465: 
                    466:                                fromi = &from[i];
                    467:                                if (cf(fromi[m], fromi[0]) > 0)
                    468:                                {
                    469:                                        break;
                    470:                                }
                    471:                                else
                    472:                                {
                    473:                                        char *s;
                    474: 
                    475:                                        s = fromi[m];
                    476:                                        fromi[m] = fromi[0];
                    477:                                        fromi[0] = s;
                    478:                                }
                    479:                        }
                    480:                }
                    481:        }
                    482: }
                    483: 
                    484: /*
                    485:  * Argument list generation
                    486:  */
                    487: getarg(ac)
                    488: struct comnod  *ac;
                    489: {
                    490:        register struct argnod  *argp;
                    491:        register int            count = 0;
                    492:        register struct comnod  *c;
                    493: 
                    494:        if (c = ac)
                    495:        {
                    496:                argp = c->comarg;
                    497:                while (argp)
                    498:                {
                    499:                        count += split(macro(argp->argval));
                    500:                        argp = argp->argnxt;
                    501:                }
                    502:        }
                    503:        return(count);
                    504: }
                    505: 
                    506: static int
                    507: split(s)               /* blank interpretation routine */
                    508: register char  *s;
                    509: {
                    510:        register char   *argp;
                    511:        register int    c;
                    512:        int             count = 0;
                    513: 
                    514:        for (;;)
                    515:        {
                    516:                sigchk();
                    517:                staktop = argp = locstak() + BYTESPERWORD;
                    518:                while ((c = *s++, !any(c, ifsnod.namval.val) && c))
                    519:                        pushstak(c);
                    520:                if (argp == staktop)
                    521:                {
                    522:                        if (c)
                    523:                        {
                    524:                                continue;
                    525:                        }
                    526:                        else
                    527:                        {
                    528:                                staktop = stakbot;
                    529:                                return(count);
                    530:                        }
                    531:                }
                    532:                else if (c == 0)
                    533:                        s--;
                    534:                /*
                    535:                 * file name generation
                    536:                 */
                    537: 
                    538:                argp = fixstak();
                    539: 
                    540:                if ((flags & nofngflg) == 0 && 
                    541:                        (c = expand(((struct argnod *)argp)->argval, 0)))
                    542:                        count += c;
                    543:                else
                    544:                {
                    545:                        makearg(argp);
                    546:                        count++;
                    547:                }
                    548:                gchain = (struct argnod *)((int)gchain | ARGMK);
                    549:        }
                    550: }
                    551: 
                    552: #ifdef ACCT
                    553: #include       <sys/types.h>
                    554: #include       "acctdef.h"
                    555: #include       <sys/acct.h>
                    556: #include       <sys/times.h>
                    557: 
                    558: struct acct sabuf;
                    559: struct tms buffer;
                    560: extern long times();
                    561: static long before;
                    562: static int shaccton;   /* 0 implies do not write record on exit
                    563:                           1 implies write acct record on exit
                    564:                        */
                    565: 
                    566: 
                    567: /*
                    568:  *     suspend accounting until turned on by preacct()
                    569:  */
                    570: 
                    571: suspacct()
                    572: {
                    573:        shaccton = 0;
                    574: }
                    575: 
                    576: preacct(cmdadr)
                    577:        char *cmdadr;
                    578: {
                    579:        char *simple();
                    580: 
                    581:        if (acctnod.namval.val && *acctnod.namval.val)
                    582:        {
                    583:                sabuf.ac_btime = time((long *)0);
                    584:                before = times(&buffer);
                    585:                sabuf.ac_uid = getuid();
                    586:                sabuf.ac_gid = getgid();
                    587:                movstrn(simple(cmdadr), sabuf.ac_comm, sizeof(sabuf.ac_comm));
                    588:                shaccton = 1;
                    589:        }
                    590: }
                    591: 
                    592: #include       <fcntl.h>
                    593: 
                    594: doacct()
                    595: {
                    596:        int fd;
                    597:        long int after;
                    598: 
                    599:        if (shaccton)
                    600:        {
                    601:                after = times(&buffer);
                    602:                sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
                    603:                sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
                    604:                sabuf.ac_etime = compress(after - before);
                    605: 
                    606:                if ((fd = open(acctnod.namval.val, O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1)
                    607:                {
                    608:                        write(fd, &sabuf, sizeof(sabuf));
                    609:                        close(fd);
                    610:                }
                    611:        }
                    612: }
                    613: 
                    614: /*
                    615:  *     Produce a pseudo-floating point representation
                    616:  *     with 3 bits base-8 exponent, 13 bits fraction
                    617:  */
                    618: 
                    619: compress(t)
                    620:        register time_t t;
                    621: {
                    622:        register exp = 0;
                    623:        register rund = 0;
                    624: 
                    625:        while (t >= 8192)
                    626:        {
                    627:                exp++;
                    628:                rund = t & 04;
                    629:                t >>= 3;
                    630:        }
                    631: 
                    632:        if (rund)
                    633:        {
                    634:                t++;
                    635:                if (t >= 8192)
                    636:                {
                    637:                        t >>= 3;
                    638:                        exp++;
                    639:                }
                    640:        }
                    641: 
                    642:        return((exp << 13) + t);
                    643: }
                    644: #endif

unix.superglobalmegacorp.com

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