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

unix.superglobalmegacorp.com

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