Annotation of researchv10dc/cmd/osh/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), 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, 0);
                     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: 
                    192:        if ((flags & noexec) == 0)
                    193:        {
                    194:                xecmsg = notfound;
                    195:                path = getpath(*t);
                    196:                xecenv = setenv();
                    197: 
                    198:                while (path = execs(path,t))
                    199:                        ;
                    200:                failed(*t, xecmsg, 1);
                    201:        }
                    202: }
                    203: 
                    204: char *
                    205: execs(ap, t)
                    206: char   *ap;
                    207: register char  *t[];
                    208: {
                    209:        register char *p, *prefix;
                    210: 
                    211:        prefix = catpath(ap, t[0]);
                    212:        trim(p = curstak());
                    213:        sigchk();
                    214:        
                    215:        execve(p, &t[0] ,xecenv);
                    216:        switch (errno)
                    217:        {
                    218:        case ENOEXEC:           /* could be a shell script */
                    219:                funcnt = 0;
                    220:                flags = 0;
                    221:                *flagadr = 0;
                    222:                comdiv = 0;
                    223:                ioset = 0;
                    224:                clearup();      /* remove open files and for loop junk */
                    225:                if (input)
                    226:                        close(input);
                    227:                input = chkopen(p);
                    228:        
                    229: #ifdef ACCT
                    230:                preacct(p);     /* reset accounting */
                    231: #endif
                    232: 
                    233:                /*
                    234:                 * set up new args
                    235:                 */
                    236:                
                    237:                setargs(t);
                    238:                longjmp(subshell, 1);
                    239: 
                    240:        case ENOMEM:
                    241:        case E2BIG:
                    242:        case ETXTBSY:
                    243:                failed(p, NIL, 1);
                    244: 
                    245:        default:
                    246:                xecmsg = badexec;
                    247:        case ENOENT:
                    248:                return(prefix);
                    249:        }
                    250: }
                    251: 
                    252: 
                    253: /*
                    254:  * for processes to be waited for
                    255:  */
                    256: #define MAXP 20
                    257: static int     pwlist[MAXP];
                    258: static int     pwc;
                    259: 
                    260: postclr()
                    261: {
                    262:        register int    *pw = pwlist;
                    263: 
                    264:        while (pw <= &pwlist[pwc])
                    265:                *pw++ = 0;
                    266:        pwc = 0;
                    267: }
                    268: 
                    269: post(pcsid)
                    270: int    pcsid;
                    271: {
                    272:        register int    *pw = pwlist;
                    273: 
                    274:        if (pcsid)
                    275:        {
                    276:                while (*pw)
                    277:                        pw++;
                    278:                if (pwc >= MAXP - 1)
                    279:                        pw--;
                    280:                else
                    281:                        pwc++;
                    282:                *pw = pcsid;
                    283:        }
                    284: }
                    285: 
                    286: await(i, bckg)
                    287: int    i, bckg;
                    288: {
                    289:        int     rc = 0, wx = 0;
                    290:        int     w;
                    291:        int     ipwc = pwc;
                    292: 
                    293:        post(i);
                    294:        while (pwc)
                    295:        {
                    296:                register int    p;
                    297:                register int    sig;
                    298:                int             w_hi;
                    299:                int     found = 0;
                    300: 
                    301:                {
                    302:                        register int    *pw = pwlist;
                    303: 
                    304:                        p = wait(&w);
                    305:                        if (wasintr)
                    306:                        {
                    307:                                wasintr = 0;
                    308:                                if (bckg)
                    309:                                {
                    310:                                        break;
                    311:                                }
                    312:                        }
                    313:                        while (pw <= &pwlist[ipwc])
                    314:                        {
                    315:                                if (*pw == p)
                    316:                                {
                    317:                                        *pw = 0;
                    318:                                        pwc--;
                    319:                                        found++;
                    320:                                }
                    321:                                else
                    322:                                        pw++;
                    323:                        }
                    324:                }
                    325:                if (p == -1)
                    326:                {
                    327:                        if (bckg)
                    328:                        {
                    329:                                register int *pw = pwlist;
                    330: 
                    331:                                while (pw <= &pwlist[ipwc] && i != *pw)
                    332:                                        pw++;
                    333:                                if (i == *pw)
                    334:                                {
                    335:                                        *pw = 0;
                    336:                                        pwc--;
                    337:                                }
                    338:                        }
                    339:                        continue;
                    340:                }
                    341:                w_hi = (w >> 8) & LOBYTE;
                    342:                if (sig = w & 0177)
                    343:                {
                    344:                        if (sig == 0177)        /* ptrace! return */
                    345:                        {
                    346:                                prs("ptrace: ");
                    347:                                sig = w_hi;
                    348:                        }
                    349:                        if (sysmsg[sig])
                    350:                        {
                    351:                                if (i != p || (flags & prompt) == 0)
                    352:                                {
                    353:                                        prp();
                    354:                                        prn(p);
                    355:                                        blank();
                    356:                                }
                    357:                                prs(sysmsg[sig]);
                    358:                                if (w & 0200)
                    359:                                        prs(coredump);
                    360:                        }
                    361:                        newline();
                    362:                }
                    363:                if (rc == 0 && found != 0)
                    364:                        rc = (sig ? sig | SIGFLG : w_hi);
                    365:                wx |= w;
                    366:                if (p == i)
                    367:                {
                    368:                        break;
                    369:                }
                    370:        }
                    371:        if (wx && flags & errflg)
                    372:                exitsh(rc);
                    373:        flags |= eflag;
                    374:        exitval = rc;
                    375:        exitset();
                    376: }
                    377: 
                    378: BOOL           nosubst;
                    379: 
                    380: trim(at)
                    381: char   *at;
                    382: {
                    383:        register char   *p;
                    384:        register char   *ptr;
                    385:        register char   c;
                    386:        register char   q = 0;
                    387: 
                    388:        if (p = at)
                    389:        {
                    390:                ptr = p;
                    391:                while (c = *p++)
                    392:                {
                    393:                        if (*ptr = c & STRIP)
                    394:                                ++ptr;
                    395:                        q |= c;
                    396:                }
                    397: 
                    398:                *ptr = 0;
                    399:        }
                    400:        nosubst = q & QUOTE;
                    401: }
                    402: 
                    403: char *
                    404: mactrim(s)
                    405: char   *s;
                    406: {
                    407:        register char   *t = macro(s);
                    408: 
                    409:        trim(t);
                    410:        return(t);
                    411: }
                    412: 
                    413: char **
                    414: scan(argn)
                    415: int    argn;
                    416: {
                    417:        register struct argnod *argp = (struct argnod *)(Rcheat(gchain) & ~ARGMK);
                    418:        register char **comargn, **comargm;
                    419: 
                    420:        comargn = (char **)getstak(BYTESPERWORD * argn + BYTESPERWORD);
                    421:        comargm = comargn += argn;
                    422:        *comargn = ENDARGS;
                    423:        while (argp)
                    424:        {
                    425:                *--comargn = argp->argval;
                    426: 
                    427:                trim(*comargn);
                    428:                argp = argp->argnxt;
                    429: 
                    430:                if (argp == 0 || Rcheat(argp) & ARGMK)
                    431:                {
                    432:                        gsort(comargn, comargm);
                    433:                        comargm = comargn;
                    434:                }
                    435:                /* Lcheat(argp) &= ~ARGMK; */
                    436:                argp = (struct argnod *)(Rcheat(argp) & ~ARGMK);
                    437:        }
                    438:        return(comargn);
                    439: }
                    440: 
                    441: static int
                    442: gsort(from, to)
                    443: char   *from[], *to[];
                    444: {
                    445:        int     k, m, n;
                    446:        register int    i, j;
                    447: 
                    448:        if ((n = to - from) <= 1)
                    449:                return;
                    450:        for (j = 1; j <= n; j *= 2)
                    451:                ;
                    452:        for (m = 2 * j - 1; m /= 2; )
                    453:        {
                    454:                k = n - m;
                    455:                for (j = 0; j < k; j++)
                    456:                {
                    457:                        for (i = j; i >= 0; i -= m)
                    458:                        {
                    459:                                register char **fromi;
                    460: 
                    461:                                fromi = &from[i];
                    462:                                if (cf(fromi[m], fromi[0]) > 0)
                    463:                                {
                    464:                                        break;
                    465:                                }
                    466:                                else
                    467:                                {
                    468:                                        char *s;
                    469: 
                    470:                                        s = fromi[m];
                    471:                                        fromi[m] = fromi[0];
                    472:                                        fromi[0] = s;
                    473:                                }
                    474:                        }
                    475:                }
                    476:        }
                    477: }
                    478: 
                    479: /*
                    480:  * Argument list generation
                    481:  */
                    482: getarg(ac)
                    483: struct comnod  *ac;
                    484: {
                    485:        register struct argnod  *argp;
                    486:        register int            count = 0;
                    487:        register struct comnod  *c;
                    488: 
                    489:        if (c = ac)
                    490:        {
                    491:                argp = c->comarg;
                    492:                while (argp)
                    493:                {
                    494:                        count += split(macro(argp->argval));
                    495:                        argp = argp->argnxt;
                    496:                }
                    497:        }
                    498:        return(count);
                    499: }
                    500: 
                    501: static int
                    502: split(s)               /* blank interpretation routine */
                    503: register char  *s;
                    504: {
                    505:        register char   *argp;
                    506:        register int    c;
                    507:        int             count = 0;
                    508: 
                    509:        for (;;)
                    510:        {
                    511:                sigchk();
                    512:                staktop = argp = locstak() + BYTESPERWORD;
                    513:                while ((c = *s++, !any(c, ifsnod.namval.val) && c))
                    514:                        pushstak(c);
                    515:                if (argp == staktop)
                    516:                {
                    517:                        if (c)
                    518:                        {
                    519:                                continue;
                    520:                        }
                    521:                        else
                    522:                        {
                    523:                                staktop = stakbot;
                    524:                                return(count);
                    525:                        }
                    526:                }
                    527:                else if (c == 0)
                    528:                        s--;
                    529:                /*
                    530:                 * file name generation
                    531:                 */
                    532: 
                    533:                argp = fixstak();
                    534: 
                    535:                if ((flags & nofngflg) == 0 && 
                    536:                        (c = expand(((struct argnod *)argp)->argval, 0)))
                    537:                        count += c;
                    538:                else
                    539:                {
                    540:                        makearg((struct argnod *)argp);
                    541:                        count++;
                    542:                }
                    543:                gchain = (struct argnod *)((int)gchain | ARGMK);
                    544:        }
                    545: }
                    546: 
                    547: #ifdef ACCT
                    548: #include       <sys/types.h>
                    549: #include       "acctdef.h"
                    550: #include       <sys/acct.h>
                    551: #include       <sys/times.h>
                    552: 
                    553: struct acct sabuf;
                    554: struct tms buffer;
                    555: extern long times();
                    556: static long before;
                    557: static int shaccton;   /* 0 implies do not write record on exit
                    558:                           1 implies write acct record on exit
                    559:                        */
                    560: 
                    561: 
                    562: /*
                    563:  *     suspend accounting until turned on by preacct()
                    564:  */
                    565: 
                    566: suspacct()
                    567: {
                    568:        shaccton = 0;
                    569: }
                    570: 
                    571: preacct(cmdadr)
                    572:        char *cmdadr;
                    573: {
                    574:        char *simple();
                    575: 
                    576:        if (acctnod.namval.val && *acctnod.namval.val)
                    577:        {
                    578:                sabuf.ac_btime = time((long *)0);
                    579:                before = times(&buffer);
                    580:                sabuf.ac_uid = getuid();
                    581:                sabuf.ac_gid = getgid();
                    582:                movstrn(simple(cmdadr), sabuf.ac_comm, sizeof(sabuf.ac_comm));
                    583:                shaccton = 1;
                    584:        }
                    585: }
                    586: 
                    587: #include       <fcntl.h>
                    588: 
                    589: doacct()
                    590: {
                    591:        int fd;
                    592:        long int after;
                    593: 
                    594:        if (shaccton)
                    595:        {
                    596:                after = times(&buffer);
                    597:                sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
                    598:                sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
                    599:                sabuf.ac_etime = compress(after - before);
                    600: 
                    601:                if ((fd = open(acctnod.namval.val, O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1)
                    602:                {
                    603:                        write(fd, &sabuf, sizeof(sabuf));
                    604:                        close(fd);
                    605:                }
                    606:        }
                    607: }
                    608: 
                    609: /*
                    610:  *     Produce a pseudo-floating point representation
                    611:  *     with 3 bits base-8 exponent, 13 bits fraction
                    612:  */
                    613: 
                    614: compress(t)
                    615:        register time_t t;
                    616: {
                    617:        register exp = 0;
                    618:        register rund = 0;
                    619: 
                    620:        while (t >= 8192)
                    621:        {
                    622:                exp++;
                    623:                rund = t & 04;
                    624:                t >>= 3;
                    625:        }
                    626: 
                    627:        if (rund)
                    628:        {
                    629:                t++;
                    630:                if (t >= 8192)
                    631:                {
                    632:                        t >>= 3;
                    633:                        exp++;
                    634:                }
                    635:        }
                    636: 
                    637:        return((exp << 13) + t);
                    638: }
                    639: #endif

unix.superglobalmegacorp.com

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