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