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