Annotation of coherent/a/usr/bob/korn/c_sh.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * built-in Bourne commands
        !             3:  */
        !             4: 
        !             5: static char *RCSid = "$Header: c_sh.c,v 3.1 88/11/03 09:14:31 egisin Exp $";
        !             6: 
        !             7: #include <stddef.h>
        !             8: #include <stdlib.h>
        !             9: #include <stdio.h>
        !            10: #include <string.h>
        !            11: #include <errno.h>
        !            12: #include <signal.h>
        !            13: #include <setjmp.h>
        !            14: #include <sys/times.h>
        !            15: #include <unistd.h>            /* getcwd */
        !            16: #include "sh.h"
        !            17: #include "lex.h"
        !            18: #include "tree.h"
        !            19: #include "table.h"
        !            20: 
        !            21: static void putvlist();
        !            22: static char *clocktos();
        !            23: 
        !            24: int
        !            25: c_label(wp)
        !            26:        char **wp;
        !            27: {
        !            28:        return 0;
        !            29: }
        !            30: 
        !            31: /* todo: add symlink hacks */
        !            32: int
        !            33: c_cd(wp)
        !            34:        register char **wp;
        !            35: {
        !            36:        static char path[PATH];
        !            37:        register char *cp;
        !            38:        register struct tbl *vp;
        !            39: 
        !            40:        if ((cp = wp[1]) == NULL && (cp = strval(global("HOME"))) == NULL)
        !            41:                errorf("no home directory");
        !            42:        if (strcmp(cp, "-") == 0) {
        !            43:                cp = strval(global("OLDPWD"));
        !            44:                shellf("%s\n", cp);
        !            45:        }
        !            46:        if (chdir(cp) < 0)
        !            47:                errorf("%s: bad directory\n", cp);
        !            48:        flushcom(0);
        !            49: 
        !            50:        /* maintain $PWD and $OLDPWD */
        !            51:        vp = global("PWD");
        !            52:        cp = strval(vp);
        !            53:        if (cp != null)
        !            54:                setstr(global("OLDPWD"), cp);
        !            55:        cp = getcwd(path, (size_t)PATH);
        !            56:        if (cp == NULL)
        !            57:                unset(vp);
        !            58:        else
        !            59:                setstr(vp, cp);
        !            60: 
        !            61:        return 0;
        !            62: }
        !            63: 
        !            64: int
        !            65: c_shift(wp)
        !            66:        register char **wp;
        !            67: {
        !            68:        register struct block *l = e.loc;
        !            69:        register int n;
        !            70: 
        !            71:        n = wp[1] ? evaluate(wp[1]) : 1;
        !            72:        if (l->argc < n) {
        !            73:                errorf("nothing to shift\n");
        !            74:                return (1);
        !            75:        }
        !            76:        l->argv[n] = l->argv[0];
        !            77:        l->argv += n;
        !            78:        l->argc -= n;
        !            79:        return 0;
        !            80: }
        !            81: 
        !            82: int
        !            83: c_umask(wp)
        !            84:        register char **wp;
        !            85: {
        !            86:        register int i;
        !            87:        register char *cp;
        !            88: 
        !            89:        if ((cp = wp[1]) == NULL) {
        !            90:                i = umask(0);
        !            91:                umask(i);
        !            92:                printf("%03o\n", i);    /* should this be shell output? */
        !            93:        } else {
        !            94:                for (i = 0; *cp>='0' && *cp<='7'; cp++)
        !            95:                        i = i*8 + (*cp-'0');
        !            96:                umask(i);
        !            97:        }
        !            98:        return 0;
        !            99: }
        !           100: 
        !           101: int
        !           102: c_dot(wp)
        !           103:        char **wp;
        !           104: {
        !           105:        char *file, *cp;
        !           106: 
        !           107:        if ((cp = wp[1]) == NULL)
        !           108:                return 0;
        !           109:        file = search(cp, path, 0);
        !           110:        if (file == NULL)
        !           111:                errorf("%s: not found\n", cp);
        !           112:        if (include(file))
        !           113:                return exstat;
        !           114:        return -1;
        !           115: }
        !           116: 
        !           117: int
        !           118: c_wait(wp)
        !           119:        char **wp;
        !           120: {
        !           121:        register char *cp;
        !           122: 
        !           123:        wp++;
        !           124:        cp = *wp;
        !           125:        if (cp == NULL)
        !           126:                cp = "%";
        !           127:        /* todo: print status ? */
        !           128:        return waitfor(j_lookup(cp));
        !           129: }
        !           130: 
        !           131: int
        !           132: c_read(wp)
        !           133:        register char **wp;
        !           134: {
        !           135:        register int c = 0;
        !           136:        FILE *f = stdin;
        !           137:        int expand = 1;
        !           138:        register char *cp;
        !           139: 
        !           140:        for (wp++; (cp = *wp) != NULL && *cp++ == '-'; wp++) {
        !           141:                while (*cp) switch (*cp++) {
        !           142:                  case 'e':
        !           143:                        expand = 1;
        !           144:                        break;
        !           145:                  case 'r':
        !           146:                        expand = 0;
        !           147:                        break;
        !           148:                  case 'u':
        !           149:                        if (!digit(*cp) || (f = shf[*cp++-'0']) == NULL)
        !           150:                                errorf("bad -u argument\n");
        !           151:                        break;
        !           152:                }
        !           153:        }
        !           154: 
        !           155:        if (*wp == NULL)
        !           156:                errorf("missing name\n");
        !           157:        if ((cp = strchr(*wp, '?')) != NULL) {
        !           158:                *cp = 0;
        !           159:                if (flag[FTALKING]) {
        !           160:                        shellf("%s ", cp+1);
        !           161:                        fflush(shlout);
        !           162:                }
        !           163:        }
        !           164: 
        !           165:        for (; *wp != NULL; wp++) {
        !           166:                for (cp = line; cp <= line+LINE; ) {
        !           167:                        if (c == '\n')
        !           168:                                break;
        !           169:                        c = getc(f);
        !           170:                        if (c == EOF)
        !           171:                                return 1;
        !           172:                        if (expand && c == '\\') {
        !           173:                                c = getc(f);
        !           174:                                if (c == '\n')
        !           175:                                        c = 0;
        !           176:                                else
        !           177:                                        *cp++ = c;
        !           178:                                continue;
        !           179:                        }
        !           180:                        if (c == '\n' || wp[1] && ctype(c, C_IFS))
        !           181:                                break;
        !           182:                        *cp++ = c;
        !           183:                }
        !           184:                *cp = 0;
        !           185:                setstr(global(*wp), line);
        !           186:        }
        !           187:        return 0;
        !           188: }
        !           189: 
        !           190: int
        !           191: c_eval(wp)
        !           192:        register char **wp;
        !           193: {
        !           194:        register struct source *s;
        !           195: 
        !           196:        s = pushs(SWORDS);
        !           197:        s->u.strv = wp+1;
        !           198:        return shell(s);
        !           199: }
        !           200: 
        !           201: void setsig ARGS((struct trap *p, handler_t f));
        !           202: 
        !           203: int
        !           204: c_trap(wp)
        !           205:        register char **wp;
        !           206: {
        !           207:        int i;
        !           208:        char *s;
        !           209:        register struct trap *p;
        !           210: 
        !           211:        wp++;
        !           212:        if (*wp == NULL) {
        !           213:                for (p = sigtraps, i = SIGNALS; --i >= 0; p++) {
        !           214:                        if (p->trap != NULL)
        !           215:                                shellf("%s: %s\n", p->name, p->trap);
        !           216:                }
        !           217:                return 0;
        !           218:        }
        !           219: 
        !           220:        s = (gettrap(*wp) == NULL) ? *wp++ : NULL; /* get command */
        !           221:        if (s != NULL && s[0] == '-' && s[1] == '\0')
        !           222:                s = NULL;
        !           223: 
        !           224:        /* set/clear traps */
        !           225:        while (*wp != NULL) {
        !           226:                p = gettrap(*wp++);
        !           227:                if (p == NULL)
        !           228:                        errorf("trap: bad signal %s\n", wp[-1]);
        !           229:                if (p->trap != NULL)
        !           230:                        afree((Void*)p->trap, APERM);
        !           231:                p->trap = NULL;
        !           232:                if (s != NULL) {
        !           233:                        if (strlen(s) != 0) {
        !           234:                                p->trap = strsave(s, APERM);
        !           235:                                setsig(p, trapsig);
        !           236:                        } else
        !           237:                                setsig(p, (handler_t)SIG_IGN);
        !           238:                } else
        !           239:                        /* todo: restore to orginal value */
        !           240:                    setsig(p,
        !           241:                       (p->signal==SIGINT || p->signal==SIGQUIT) && flag[FTALKING]
        !           242:                           ? (handler_t)SIG_IGN : (handler_t)SIG_DFL);
        !           243:        }
        !           244:        return 0;
        !           245: }
        !           246: 
        !           247: void
        !           248: setsig(p, f)
        !           249:        register struct trap *p;
        !           250:        void (*f)();
        !           251: {
        !           252:        if (p->signal == 0)
        !           253:                return;
        !           254:        if (signal(p->signal, SIG_IGN) != SIG_IGN || p->ourtrap) {
        !           255:                p->ourtrap = 1;
        !           256:                signal(p->signal, f);
        !           257:        }
        !           258: }
        !           259: 
        !           260: int
        !           261: c_return(wp)
        !           262:        char **wp;
        !           263: {
        !           264:        wp++;
        !           265:        if (*wp != NULL)
        !           266:                exstat = getn(*wp);
        !           267:        quitenv();              /* pop E_TCOM */
        !           268:        while (e.type == E_LOOP || e.type == E_EXEC)
        !           269:                quitenv();
        !           270:        if (e.type == E_FUNC)
        !           271:                longjmp(e.jbuf, 1);
        !           272:        leave(exstat);
        !           273: }
        !           274: 
        !           275: int
        !           276: c_brkcont(wp)
        !           277:        register char **wp;
        !           278: {
        !           279:        int quit;
        !           280: 
        !           281:        quit = wp[1] == NULL ? 1 : getn(wp[1]);
        !           282:        quitenv();              /* pop E_TCOM */
        !           283:        while (e.type == E_LOOP || e.type == E_EXEC) {
        !           284:                if (e.type == E_LOOP && --quit <= 0)
        !           285:                        longjmp(e.jbuf, (*wp[0] == 'b') ? LBREAK : LCONTIN);
        !           286:                quitenv();
        !           287:        }
        !           288:        errorf("cannot %s\n", wp[0]);
        !           289: }
        !           290: 
        !           291: int
        !           292: c_exit(wp)
        !           293:        char **wp;
        !           294: {
        !           295:        register char *cp;
        !           296: 
        !           297:        e.oenv = NULL;
        !           298:        if ((cp = wp[1]) != NULL)
        !           299:                exstat = getn(cp);
        !           300: #if JOBS
        !           301:        if (flag[FMONITOR] && j_stopped()) /* todo: only once */
        !           302:                errorf("There are stopped jobs\n");
        !           303: #endif
        !           304:        leave(exstat);
        !           305: }
        !           306: 
        !           307: int
        !           308: c_exro(wp)
        !           309:        register char **wp;
        !           310: {
        !           311:        int flag = (**wp == 'e') ? EXPORT : RDONLY;
        !           312: 
        !           313:        if (*++wp != NULL) {
        !           314:                for (; *wp != NULL; wp++)
        !           315:                        if (typeset(*wp, flag, 0) == NULL)
        !           316:                                errorf("%s: bad identifier\n", *wp);
        !           317:        } else
        !           318:                putvlist(flag);
        !           319:        return 0;
        !           320: }
        !           321: 
        !           322: static void
        !           323: putvlist(flag)
        !           324:        register int flag;
        !           325: {
        !           326:        struct block *l = e.loc;
        !           327:        register struct tbl *vp, **p;
        !           328: 
        !           329:        flag |= ISSET;
        !           330:        for (l = e.loc; l != NULL; l = l->next)
        !           331:                for (p = tsort(&l->vars); (vp = *p++) != NULL; )
        !           332:                        if ((vp->flag&flag) == flag) {
        !           333:                                if (vp->flag & EXPORT)
        !           334:                                        printf("export ");
        !           335:                                if (vp->flag & RDONLY)
        !           336:                                        printf("readonly ");
        !           337:                                printf("%s\n", vp->name);
        !           338:                        }
        !           339: }
        !           340: 
        !           341: int
        !           342: c_set(wp)
        !           343:        register char **wp;
        !           344: {
        !           345:        struct block *l = e.loc;
        !           346:        register struct tbl *vp, **p;
        !           347:        register char **owp = wp;
        !           348:        register char *cp;
        !           349:        int old_fmonitor = flag[FMONITOR];
        !           350: 
        !           351:        if ((cp = *++wp) == NULL) {
        !           352:                static char * Const args [] = {"set", "-", NULL};
        !           353:                extern int c_typeset ARGS((char **args));
        !           354:                return c_typeset(args);
        !           355:        }
        !           356:        
        !           357:        for (; (cp = *wp) != NULL && (*cp == '-' || *cp == '+');) {
        !           358:                int i, n = *cp++ == '-'; /* set or clear flag */
        !           359:                wp++;
        !           360:                if (*cp == '\0') {
        !           361:                        if (n)
        !           362:                                flag[FXTRACE] = flag[FVERBOSE] = 0;
        !           363:                        break;
        !           364:                }
        !           365:                if (*cp == '-')
        !           366:                        goto setargs;
        !           367:                for (; *cp != '\0'; cp++)
        !           368:                        if (*cp == 'o') {
        !           369:                                if (*wp == NULL) {
        !           370:                                        printoptions();
        !           371:                                        return 0;
        !           372:                                }
        !           373:                                i = option(*wp++);
        !           374:                                if (i == 0)
        !           375:                                        shellf("%s: unknown option\n", *--wp);
        !           376:                                flag[i] = n;
        !           377:                        } else if (*cp>='a' && *cp<='z')
        !           378:                                flag[FLAG(*cp)] = n;
        !           379:                        else
        !           380:                                errorf("%c: bad flag\n", *cp);
        !           381:                if (flag[FTALKING])
        !           382:                        flag[FERREXIT] = 0;
        !           383:        }
        !           384: 
        !           385: #if JOBS
        !           386:        if (old_fmonitor != flag[FMONITOR])
        !           387:                j_change();
        !           388: #endif
        !           389: 
        !           390:        /* set $# and $* */
        !           391:        if (*wp != NULL) {
        !           392:          setargs:
        !           393:                owp = --wp;
        !           394:                wp[0] = l->argv[0]; /* save $0 */
        !           395:                while (*++wp != NULL)
        !           396:                        *wp = strsave(*wp, &l->area);
        !           397:                l->argc = wp - owp - 1;
        !           398:                l->argv = (char **) alloc(sizeofN(char *, l->argc+2), &l->area);
        !           399:                for (wp = l->argv; (*wp++ = *owp++) != NULL; )
        !           400:                        ;
        !           401:                resetopts();
        !           402:        }
        !           403:        return 0;
        !           404: }
        !           405: 
        !           406: int
        !           407: c_unset(wp)
        !           408:        register char **wp;
        !           409: {
        !           410:        register char *id;
        !           411:        int flagf = 0;
        !           412: 
        !           413:        for (wp++; (id = *wp) != NULL && *id == '-'; wp++)
        !           414:                if (*++id == 'f')
        !           415:                        flagf++;
        !           416:        for (; (id = *wp) != NULL; wp++)
        !           417:                if (!flagf) {   /* unset variable */
        !           418:                        unset(local(id));
        !           419:                } else {        /* unset function */
        !           420:                        register struct tbl *tp;
        !           421:                        tp = tsearch(&e.loc->funs, id, hash(id));
        !           422:                        if (tp != NULL)
        !           423:                                define(tp, (struct op *)NULL);
        !           424:                }
        !           425:        return 0;
        !           426: }
        !           427: 
        !           428: int
        !           429: c_ulimit(wp)
        !           430:        register char **wp;
        !           431: {
        !           432:        extern int do_ulimit();
        !           433: 
        !           434:        return do_ulimit(wp[1], wp[2]);
        !           435: }
        !           436: 
        !           437: int
        !           438: c_times(wp)
        !           439:        char **wp;
        !           440: {
        !           441:        struct tms all;
        !           442: 
        !           443:        (void) times(&all);
        !           444:        printf("Shell: ");
        !           445:        printf("%8s user ", clocktos(all.tms_utime));
        !           446:        printf("%8s system\n", clocktos(all.tms_stime));
        !           447:        printf("Kids:  ");
        !           448:        printf("%8s user ", clocktos(all.tms_cutime));
        !           449:        printf("%8s system\n", clocktos(all.tms_cstime));
        !           450: 
        !           451:        return 0;
        !           452: }
        !           453: 
        !           454: /*
        !           455:  * time pipeline (really a statement, not a built-in comman)
        !           456:  */
        !           457: int
        !           458: timex(t, f)
        !           459:        struct op *t;
        !           460:        int f;
        !           461: {
        !           462:        int rv;
        !           463:        struct tms t0, t1;
        !           464:        clock_t t0t, t1t, time();
        !           465:        extern clock_t j_utime, j_stime; /* computed by j_wait */
        !           466: 
        !           467:        j_utime = j_stime = 0;
        !           468: #if COHERENT
        !           469:        t0t = time((clock_t)NULL);
        !           470:        (void)times(&t0);
        !           471: #else
        !           472:        t0t = times(&t0);
        !           473: #endif
        !           474:        rv = execute(t->left, f);
        !           475: #if COHERENT
        !           476:        t1t = time((clock_t)NULL);
        !           477:        (void)times(&t1);
        !           478: #else
        !           479:        t1t = times(&t1);
        !           480: #endif
        !           481:        shellf("%8s real ", clocktos((t1t - t0t) * 100));
        !           482:        shellf("%8s user ",
        !           483:               clocktos(t1.tms_utime - t0.tms_utime + j_utime));
        !           484:        shellf("%8s system ",
        !           485:               clocktos(t1.tms_stime - t0.tms_stime + j_stime));
        !           486:        shellf("\n");
        !           487: 
        !           488:        return rv;
        !           489: }
        !           490: 
        !           491: static char *
        !           492: clocktos(t)
        !           493:        clock_t t;
        !           494: {
        !           495:        static char temp[20];
        !           496:        register int i;
        !           497:        register char *cp = temp + sizeof(temp);
        !           498: 
        !           499: #if !COHERENT
        !           500: #if CLK_TCK != 100             /* convert to 1/100'ths */
        !           501:        t = (t < 1000000000/CLK_TCK) ?
        !           502:                (t * 100) / CLK_TCK : (t / CLK_TCK) * 100;
        !           503: #endif
        !           504: #endif
        !           505:        *--cp = '\0';
        !           506:        *--cp = 's';
        !           507:        for (i = -2; i <= 0 || t > 0; i++) {
        !           508:                if (i == 0)
        !           509:                        *--cp = '.';
        !           510:                *--cp = '0' + (char)(t%10);
        !           511:                t /= 10;
        !           512:        }
        !           513:        return cp;
        !           514: }
        !           515: 
        !           516: /* dummy function, special case in comexec() */
        !           517: int
        !           518: c_exec(wp)
        !           519:        char ** wp;
        !           520: {
        !           521:        return 0;
        !           522: }
        !           523: 
        !           524: /* dummy function, special case in comexec() */
        !           525: int
        !           526: c_builtin(wp)
        !           527:        char ** wp;
        !           528: {
        !           529:        return 0;
        !           530: }
        !           531: 
        !           532: extern int c_test();           /* in test.c */
        !           533: 
        !           534: Const struct builtin shbuiltins [] = {
        !           535:        {"=:", c_label},
        !           536:        {"=.", c_dot},
        !           537:        {"[", c_test},
        !           538:        {"=cd", c_cd},
        !           539:        {"builtin", c_builtin},
        !           540:        {"=exec", c_exec},
        !           541:        {"=shift", c_shift},
        !           542:        {"wait", c_wait},
        !           543:        {"read", c_read},
        !           544:        {"=eval", c_eval},
        !           545:        {"trap", c_trap},
        !           546:        {"break", c_brkcont},
        !           547:        {"continue", c_brkcont},
        !           548:        {"exit", c_exit},
        !           549:        {"=export", c_exro},
        !           550:        {"=readonly", c_exro},
        !           551:        {"=return", c_return},
        !           552:        {"=set", c_set},
        !           553:        {"=unset", c_unset},
        !           554:        {"umask", c_umask},
        !           555:        {"test", c_test},
        !           556:        {"times", c_times},
        !           557:        {"ulimit", c_ulimit},
        !           558:        {NULL, NULL}
        !           559: };
        !           560: 

unix.superglobalmegacorp.com

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