Annotation of coherent/a/usr/bob/korn/c_sh.c, revision 1.1.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.