Annotation of coherent/b/bin/sh_B4_420/exec1.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * sh/exec1.c
                      3:  * The Bourne shell.
                      4:  * Shell part of execution.
                      5:  */
                      6: 
                      7: #include "sh.h"
                      8: 
                      9: char *lastcmd = "";
                     10: 
                     11: char *skipredir();
                     12: 
                     13: /*
                     14:  * Execute the given node, wait for completion, return status.
                     15:  */
                     16: command(np)
                     17: register NODE *np;
                     18: {
                     19:        register int f;         /* Pid of command */
                     20:        int mynllflag;          /* Saved fork not forced flag */
                     21:        CON con;                /* Control link for break/continue */
                     22:        char *innp, **inlp;     /* for NFOR */
                     23:        NODE *cnode;            /* for NCASE */
                     24:        char *cname;            /* for NCASE */
                     25: 
                     26:        if (ret_done)
                     27:                return;
                     28:        mynllflag = nllflag;
                     29:        innp = inlp = NULL;
                     30:        cnode = NULL;
                     31:        f = 0;
                     32: 
                     33:        con.c_next = sesp->s_con;
                     34:        con.c_node = np;
                     35:        con.c_bpp = savebuf();
                     36:        sesp->s_con = &con;
                     37: 
                     38:        switch (setjmp(con.c_envl)) {
                     39:        case 0:         /* initial setjmp */
                     40:                break;
                     41:        case 1:         /* continue */
                     42:                np = con.c_node;
                     43:                break;
                     44:        case 2:         /* break */
                     45:                goto break2;
                     46:        default:
                     47:                panic(1);
                     48:                NOTREACHED;
                     49:        }
                     50: 
                     51:        for ( ; np != NULL; np=np->n_next) {
                     52:        if (ret_done)
                     53:                break;          /* "return" interrupts control flow */
                     54:        recover(ICMD);
                     55:        f = 0;
                     56:        nllflag = mynllflag;
                     57: 
                     58:        switch (np->n_type) {
                     59:        case NCOMS:
                     60:                f = comscom(np->n_auxp);
                     61:                break;
                     62:        case NFOR:
                     63:                if (innp == NULL) {
                     64:                        innp = np->n_strp;
                     65:                        nargc = 0;
                     66:                        nargv = makargl();
                     67:                        for (np = np->n_next->n_auxp; np; np = np->n_next)
                     68:                                eval(np->n_strp, EARGS);
                     69:                        inlp = nargv;
                     70:                        np = con.c_node;
                     71:                }
                     72:                continue;
                     73:        case NFOR2:
                     74:                /* do_done_list->n_next == this node */
                     75:                if (*inlp == NULL || assnvar(innp, *inlp++) == NULL)
                     76:                        break;
                     77:                continue;
                     78:        case NWHILE:
                     79:                /* do_done_list->n_next == this node */
                     80:                nllflag = 0;
                     81:                if (command(np->n_auxp))
                     82:                        break;
                     83:                continue;
                     84:        case NUNTIL:
                     85:                /* do_done_list->n_next == this node */
                     86:                nllflag = 0;
                     87:                if ( ! command(np->n_auxp))
                     88:                        break;
                     89:                continue;
                     90:        case NBRAC:
                     91:                command(np->n_auxp);
                     92:                break;
                     93:        case NPARN:
                     94:                if (nllflag || (f=clone()) == 0) {
                     95:                        exit(command(np->n_auxp));
                     96:                        NOTREACHED;
                     97:                }
                     98:                break;
                     99:        case NIF:
                    100:                nllflag = 0;
                    101:                if (!command(np->n_auxp->n_auxp))
                    102:                        np = np->n_auxp;
                    103:                else if (np->n_next == NULL)
                    104:                        slret = 0;              /* exit status 0 if no elsepart */
                    105:                continue;
                    106:        case NELSE:
                    107:                command(np->n_auxp);
                    108:                break;
                    109:        case NCASE:
                    110:                eval(np->n_strp, EWORD);
                    111:                if (errflag)
                    112:                        break;
                    113:                cname = duplstr(strt, 0);
                    114:                continue;
                    115:        case NCASE2:
                    116:                cnode = np->n_auxp;
                    117:                continue;
                    118:        case NCASE3:
                    119:                /* end of pattern list == next NCASE2 node */
                    120:                eval(np->n_strp, EPATT);
                    121:                if (errflag)
                    122:                        break;
                    123:                if (match(strt, cname)) {
                    124:                        command(cnode);
                    125:                        break;
                    126:                }
                    127:                continue;
                    128:        case NLIST:
                    129:                nllflag = 0;
                    130:                command(np->n_auxp);
                    131:                continue;
                    132:        case NANDF:
                    133:                nllflag = 0;
                    134:                if (command(np->n_auxp))
                    135:                        break;
                    136:                continue;
                    137:        case NORF:
                    138:                nllflag = 0;
                    139:                if ( ! command(np->n_auxp))
                    140:                        break;
                    141:                continue;
                    142:        case NBACK:
                    143:                if ((f=clone()) == 0) {
                    144:                        static char *iov[] = { "0</dev/null", NULL };
                    145: 
                    146:                        bckflag++;
                    147:                        dflttrp(IBACK);
                    148:                        redirect(iov, NULL);
                    149:                        exit(command(np->n_auxp));
                    150:                        NOTREACHED;
                    151:                }
                    152:                sback = f;
                    153:                prints("%d\n", f);
                    154:                f = 0;
                    155:                continue;
                    156:        case NPIPE:
                    157:                f = pipecoms(np);
                    158:                break;
                    159:        case NFUNC:
                    160:                def_shell_fn(np);
                    161:                break;
                    162:        case NRET:
                    163:                if (in_sh_fn == 0) {
                    164:                        printe("return not inside shell function");
                    165:                        break;
                    166:                }
                    167:                ret_done++;             /* to interrupt control flow */
                    168:                if (np->n_strp[0] != '\0') {
                    169:                        eval(np->n_strp, EARGS);
                    170:                        slret = atoi(strt);
                    171:                }
                    172:                return slret;
                    173:        default:
                    174:                panic(2);
                    175:                NOTREACHED;
                    176:        }
                    177:        break;
                    178: 
                    179:        }
                    180: break2:
                    181:        nllflag = mynllflag;
                    182:        if (sesp->s_con != NULL)
                    183:                sesp->s_con = sesp->s_con->c_next;
                    184:        if (f)
                    185:                waitc(f);
                    186:        if (slret)
                    187:                assnvar("LASTERROR", lastcmd);
                    188:        freebuf(con.c_bpp);
                    189:        if (eflag && (slret || errflag)) {
                    190:                reset(RUABORT);
                    191:                NOTREACHED;
                    192:        }
                    193:        return slret;
                    194: }
                    195: 
                    196: /*
                    197:  * Run a simple command.
                    198:  *     Anything but.
                    199:  */
                    200: #define        FARGS   1
                    201: #define        FIORS   2
                    202: #define        FASSG   4
                    203: 
                    204: comscom(np)
                    205: register NODE *np;
                    206: {
                    207:        register int f;
                    208:        register char **app, *s, *s1, *sp;
                    209:        int nputs, nargs;
                    210: 
                    211:        nargc = 1;
                    212:        nargv = makargl();
                    213:        nargv = addargl(nargv, "sh");
                    214:        niovp = makargl();
                    215:        nenvp = makargl();
                    216:        nctlp = NULL;
                    217:        /*
                    218:         * Scan for arguments.
                    219:         * or a control node.
                    220:         */
                    221:        nputs = 0;
                    222:        f = 0;
                    223:        for ( ; np; np = np->n_next) {
                    224:                switch (np->n_type) {
                    225:                case NIORS:
                    226:                        f |= FIORS;
                    227: #if    0
                    228:                        /* Old code. */
                    229:                        eval(np->n_strp, EWORD);
                    230:                        niovp = addargl(niovp, duplstr(strt, 0));
                    231:                        if (xflag)
                    232:                                nputs += puta(nputs, strt);
                    233: #else
                    234:                        /*
                    235:                         * New code by steve 1/24/91.
                    236:                         * This allows globs in redirection args.
                    237:                         */
                    238:                        s = skipredir(np->n_strp);
                    239:                        nargs = nargc;
                    240:                        eval(s, EARGS);                 /* expand as arg */
                    241:                        for (s1 = np->n_strp, sp = strt; s1 < s; )
                    242:                                *sp++ = *s1++;
                    243:                        strcpy(sp, nargv[nargs]);       /* build redir arg */
                    244:                        niovp = addargl(niovp, duplstr(strt, 0));
                    245:                        if (xflag)
                    246:                                nputs += puta(nputs, strt);
                    247:                        --nargc;
                    248:                        for (app = nargv+nargs; *app; app++) {
                    249:                                *app = *(app + 1);      /* shift remaining args */
                    250:                                if (xflag && *app != NULL)
                    251:                                        nputs += puta(nputs, *app);
                    252:                        }
                    253: #endif
                    254:                        continue;
                    255:                case NARGS:
                    256:                        f |= FARGS;
                    257:                        nargs = nargc;
                    258:                        eval(np->n_strp, EARGS);
                    259:                        if (xflag)
                    260:                                for (app = nargv+nargs; *app; )
                    261:                                        nputs += puta(nputs, *app++);
                    262:                        continue;
                    263:                case NASSG:
                    264:                        if (kflag || (f&FARGS)==0) {
                    265:                                f |= FASSG;
                    266:                                eval(np->n_strp, EWORD);
                    267:                                nenvp = addargl(nenvp, duplstr(strt, 0));
                    268:                                if (xflag)
                    269:                                        nputs += puta(nputs, strt);
                    270:                        } else {
                    271:                                nargs = nargc;
                    272:                                eval(np->n_strp, EARGS);
                    273:                                if (xflag)
                    274:                                        for (app = nargv+nargs; *app; )
                    275:                                                nputs += puta(nputs, *app++);
                    276:                        }
                    277:                        continue;
                    278:                case NCTRL:
                    279:                        if (nctlp!=NULL) {
                    280:                                panic(3);
                    281:                                NOTREACHED;
                    282:                        }
                    283:                        f |= FARGS;
                    284:                        nctlp = np;
                    285:                        continue;
                    286:                default:
                    287:                        panic(4);
                    288:                        NOTREACHED;
                    289:                }
                    290:        }
                    291:        if (xflag && nputs)
                    292:                prints("\n");
                    293: #ifdef VERBOSE
                    294:        if (xflag) {
                    295:                prints("\t<%o flag, %d put, %d arg, %o arv, %o env, %o iov>\n",
                    296:                        f, nputs, nargc-1, *(nargv+1), *nenvp, *niovp);
                    297:        }
                    298: #endif
                    299: 
                    300:        nargv += 1;     /* Skip over "sh" */
                    301:        nargc -= 1;
                    302: 
                    303:        /* Last chance to quit */
                    304: #ifdef VERBOSE
                    305:        if (xflag) prints("errflag = %o\n", errflag);
                    306: #endif
                    307:        if (errflag || nflag)
                    308:                return (0);
                    309: 
                    310:        /* And away we go */
                    311:        sfree(lastcmd);
                    312:        if (*nargv)
                    313:                lastcmd = duplstr(*nargv, 1);
                    314:        else
                    315:                lastcmd = "";
                    316:        switch (f) {
                    317:        case    0:
                    318:                return (0);
                    319:        case    FARGS:
                    320:                if (nctlp) {
                    321:                        command(nctlp->n_auxp);
                    322:                        return (0);
                    323:                }
                    324:        case    FARGS|  FIORS:
                    325:        case    FARGS|          FASSG:
                    326:        case    FARGS|  FIORS|  FASSG:
                    327:                if (sh_fn() || inline())
                    328:                        return (0);
                    329:                break;
                    330:        case            FIORS:
                    331:                break;
                    332:        case                    FASSG:
                    333:        case            FIORS|  FASSG:
                    334:                for (app = nenvp; *app!=NULL; )
                    335:                        setsvar(*app++);
                    336:                if ((f&~FASSG)==0) {
                    337:                        slret = 0;
                    338:                        return (0);
                    339:                }
                    340:                break;
                    341:        default:
                    342:                panic(5);
                    343:                NOTREACHED;
                    344:        }
                    345:        if (nllflag || (f=clone()) == 0) {
                    346:                if (redirect (niovp, NULL) < 0) {
                    347:                        slret = 1;
                    348:                } else if (nargc) {
                    349:                        dflttrp(ICMD);
                    350:                        nenvp = envlvar(nenvp);
                    351:                        flexec();
                    352:                        slret = 1;
                    353:                } else if (nctlp) {
                    354:                        command(nctlp->n_auxp);
                    355:                }
                    356:                exit(slret);
                    357:                NOTREACHED;
                    358:        }
                    359:        return (f);
                    360: }
                    361: 
                    362: puta(n, p)
                    363: char *p;
                    364: {
                    365:        if (n)
                    366:                prints(" ");
                    367: #ifdef VERBOSE
                    368:        else
                    369:                prints("<%d> ", getpid());
                    370: #endif
                    371:        prints("%s", p);
                    372:        return (1);
                    373: }
                    374: 
                    375: /*
                    376:  * Execute a pipe command.
                    377:  * Fork, if necessary, a subshell to execute the pipe.
                    378:  * Fork each segment off.
                    379:  * Wait for last, save slret, wait for all, return slret from last.
                    380:  */
                    381: pipecoms(np)
                    382: register NODE *np;
                    383: {
                    384:        register int f;
                    385:        register int p1st = 0;
                    386:        int pipev[2];
                    387: 
                    388:        if ( ! nllflag && (f = clone()) != 0)
                    389:                return (f);
                    390:        while (np->n_type == NPIPE) {
                    391:                if (f = pipeline(pipev)) {
                    392:                        /* Parent takes right hand side */
                    393:                        np = np->n_next;
                    394:                        if (p1st == 0)
                    395:                                p1st = f;
                    396:                        dup2(pipev[0], 0);
                    397:                        if (pipev[0] != 0)
                    398:                                close(pipev[0]);
                    399:                        close(pipev[1]);
                    400:                } else {
                    401:                        /* Child takes left hand side */
                    402:                        np = np->n_auxp;
                    403:                        dup2(pipev[1], 1);
                    404:                        close(pipev[0]);
                    405:                        if (pipev[1] != 1)
                    406:                                close(pipev[1]);
                    407:                        exit(command(np));
                    408:                        NOTREACHED;
                    409:                }
                    410:        }
                    411:        if (f = clone()) {
                    412:                /* Parent waits out pipe line */
                    413:                spipe = p1st;
                    414:                close(0);
                    415:                if (f = waitc(f))
                    416:                        waitc(p1st);
                    417:                exit(f);
                    418:                NOTREACHED;
                    419:        } else {
                    420:                /* Child takes the pipe tail */
                    421:                exit(command(np));
                    422:                NOTREACHED;
                    423:        }
                    424: }
                    425: 
                    426: /*
                    427:  * Skip a redirection arg, return pointer to following nonspace.
                    428:  */
                    429: char *
                    430: skipredir(s) register char *s;
                    431: {
                    432:        if (*s >= '1' && *s <= '9')
                    433:                ++s;
                    434:        if (*s == '>' || *s == '<')
                    435:                ++s;
                    436:        if (*s == '>' || *s == '<')
                    437:                ++s;
                    438:        if (*s == '&')
                    439:                ++s;
                    440:        while (*s == ' ' || *s == '\t')
                    441:                ++s;
                    442:        return s;
                    443: }
                    444: 
                    445: /* end of sh/exec1.c */

unix.superglobalmegacorp.com

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