Annotation of 40BSD/cmd/oldcsh/sh.sem.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include "sh.h"
                      3: 
                      4: /*
                      5:  * C shell
                      6:  */
                      7: 
                      8: execute(t, pipein, pipeout)
                      9:        register struct command *t;
                     10:        int *pipein, *pipeout;
                     11: {
                     12:        int pid, flags, pv[2];
                     13:        register struct command *t1;
                     14:        register char *cp;
                     15:        bool forked = 0;
                     16:        bool shudint, shudhup;
                     17: #ifdef VFORK
                     18:        int (*savint)(), vffree();
                     19:        int ochild, osetintr, ohaderr, otimflg, odidfds, odidcch;
                     20:        int oSHIN, oSHOUT, oSHDIAG, oOLDSTD;
                     21:        int isvfork = 0;
                     22: #endif
                     23: 
                     24:        if (t == 0)
                     25:                return;
                     26:        switch (t->t_dtyp) {
                     27: 
                     28:        case TCOM:
                     29:                cp = t->t_dcom[0];
                     30:                if ((cp[0] & (QUOTE|TRIM)) == QUOTE)
                     31:                        strcpy(cp, cp + 1);
                     32:                if ((t->t_dflg & FREDO) == 0)
                     33:                        Dfix(t);                /* $ " ' \ */
                     34:                /* fall into... */
                     35: 
                     36:        case TPAR:
                     37:                flags = t->t_dflg;
                     38:                if (flags & FPOU)
                     39:                        mypipe(pipeout);
                     40:                /*
                     41:                 * A child will be interruptible only under very
                     42:                 * certain conditions:
                     43:                 *      we must be monkeying with interrupts
                     44:                 *      the child must not be &'ed
                     45:                 *      we must not have had an "onintr -"
                     46:                 */
                     47:                shudint = setintr && (flags & FINT) == 0 && (!gointr || !eq(gointr, "-"));
                     48:                shudhup = (flags & FAND) == 0;
                     49: 
                     50:                /*
                     51:                 * Must do << early so parent will know
                     52:                 * where input pointer should be
                     53:                 */
                     54:                if (flags & FHERE)
                     55:                        close(0), heredoc(t->t_dlef);
                     56: 
                     57:                /*
                     58:                 * If not executing commands then
                     59:                 * all we must do is read forward in the input to
                     60:                 * account for << redirection if present.
                     61:                 */
                     62:                if (noexec) {
                     63:                        if (flags & FHERE)
                     64:                                close(0);
                     65:                        return;
                     66:                }
                     67: 
                     68:                set("status", "0");
                     69:                pid = 0;
                     70: 
                     71:                /*
                     72:                 * Built-in functions
                     73:                 */
                     74:                if (t->t_dtyp == TCOM && isbfunc(t->t_dcom[0])) {
                     75:                        /*
                     76:                         * If output is piped, or running & and we would
                     77:                         * eventually fork for non-builtin commands,
                     78:                         * then do it now, so we won't block.
                     79:                         */
                     80:                        if ((flags & (FPOU|FAND)) && (flags & FPAR) == 0)
                     81:                                pid = dofork(shudint, shudhup), forked++;
                     82: 
                     83:                        /*
                     84:                         * If the builtin is actually executed (some, e.g.
                     85:                         * time and nice may refuse to execute here)
                     86:                         * then either exit (if we forked) or close i/o
                     87:                         * and continue execution (if we didn't).
                     88:                         */
                     89:                        if (pid == 0) {
                     90:                                doio(t, pipein, pipeout);
                     91:                                if (flags & FPOU) {
                     92:                                        close(pipeout[0]), close(pipeout[1]);
                     93:                                        pipeout[0] = pipeout[1] = -1;
                     94:                                }
                     95:                                if (setintr && forked) {
                     96:                                        if (shudint)
                     97:                                                signal(SIGINT, SIG_DFL), signal(SIGQUIT, SIG_DFL);
                     98:                                        signal(SIGTERM, parterm);
                     99:                                        if (flags & FINT)
                    100:                                                setintr = 0;
                    101:                                }
                    102:                                if (func(t, pipein, pipeout)) {
                    103:                                        if (forked)
                    104:                                                exitstat();
                    105:                                        if (didfds && !(t->t_dflg & FREDO))
                    106:                                                donefds();
                    107:                                        return;
                    108:                                }
                    109:                        }
                    110:                }
                    111: 
                    112:                /*
                    113:                 * Now, we must make a new process since either the
                    114:                 * command is non-builtin, a parenthesized list,
                    115:                 * or builtin such as time or nice which really
                    116:                 * requires a child.
                    117:                 */
                    118:                if (!forked && (flags & FPAR) == 0)
                    119: #ifdef VFORK
                    120:                        if (t->t_dtyp == TPAR || (flags&FREDO) ||
                    121:                            eq(t->t_dcom[0], "nice") || eq(t->t_dcom[0], "nohup"))
                    122: #endif
                    123:                                pid = dofork(shudint, shudhup);
                    124: #ifdef VFORK
                    125:                        else {
                    126:                                savint = signal(SIGINT, SIG_IGN);
                    127:                                ochild = child; osetintr = setintr;
                    128:                                ohaderr = haderr; otimflg = timflg;
                    129:                                odidfds = didfds; odidcch = didcch;
                    130:                                oSHIN = SHIN; oSHOUT = SHOUT;
                    131:                                oSHDIAG = SHDIAG; oOLDSTD = OLDSTD;
                    132:                                Vsav = Vdp = 0; Vav = 0;
                    133:                                isvfork++;
                    134:                                pid = vfork();
                    135:                                if (pid < 0) {
                    136:                                        signal(SIGINT, savint);
                    137:                                        error("No more processes");
                    138:                                }
                    139:                                if (pid == 0) {
                    140:                                        child++;
                    141:                                        signal(SIGINT, shudint ? SIG_DFL : savint);
                    142:                                        if (!shudhup)
                    143:                                                signal(SIGHUP, SIG_IGN);
                    144:                                } else {
                    145:                                        child = ochild; setintr = osetintr;
                    146:                                        haderr = ohaderr; timflg = otimflg;
                    147:                                        didfds = odidfds; didcch = odidcch;
                    148:                                        SHIN = oSHIN; SHOUT = oSHOUT;
                    149:                                        SHDIAG = oSHDIAG; OLDSTD = oOLDSTD;
                    150:                                        xfree(Vsav), Vsav = 0;
                    151:                                        xfree(Vdp), Vdp = 0;
                    152:                                        xfree(Vav), Vav = 0;
                    153:                                        signal(SIGINT, savint);
                    154:                                }
                    155:                        }
                    156: #endif
                    157:                if (pid != 0) {
                    158:                        /*
                    159:                         * The parent path (or nobody does this if
                    160:                         * (flags & FPAR), i.e. date in (set;date))
                    161:                         */
                    162:                        if (didfds == 0 && (flags & FPIN))
                    163:                                close(pipein[0]), close(pipein[1]);
                    164:                        if (didfds && !(t->t_dflg & FREDO))
                    165:                                donefds();
                    166:                        if (flags & FPRS)
                    167:                                printf("%d\n", pid), set("child", putn(pid));
                    168:                        /*
                    169:                         * Unless output is piped or command is &
                    170:                         * wait for it.
                    171:                         */
                    172:                        if (t->t_dtyp == TCOM)
                    173:                                cadd(pid, t->t_dcom[0]);
                    174:                        else
                    175:                                cadd(pid, "()");
                    176:                        if ((flags & (FPOU|FAND)) == 0)
                    177:                                pwait(pid);
                    178:                        return;
                    179:                }
                    180: 
                    181:                /*
                    182:                 * Insure that this (child) shell doesn't muck on
                    183:                 */
                    184:                child++;
                    185: 
                    186:                /*
                    187:                 * If havent yet, finally set up the file descriptors.
                    188:                 */
                    189:                doio(t, pipein, pipeout);
                    190:                if (flags & FPOU)
                    191:                        close(pipeout[0]), close(pipeout[1]);
                    192: 
                    193:                /*
                    194:                 * If mucking with interrupts fix interrupt, quit,
                    195:                 * and terminate handling ... in any case set setintr
                    196:                 * to 0 if we are not interruptible so that no further
                    197:                 * interrupt mucking occurs.
                    198:                 */
                    199:                if (setintr) {
                    200:                        if (shudint) {
                    201:                                signal(SIGQUIT, SIG_DFL);
                    202: #ifdef VFORK
                    203:                                if (isvfork)
                    204:                                        signal(SIGINT, vffree);
                    205:                                else
                    206: #endif
                    207:                                        signal(SIGINT, SIG_DFL);
                    208:                        }
                    209:                        signal(SIGTERM, parterm);
                    210:                        if (flags & FINT)
                    211:                                setintr = 0;
                    212:                }
                    213: 
                    214:                /*
                    215:                 * For () commands must put new 0,1,2 in FSH* and recurse
                    216:                 */
                    217:                if (t->t_dtyp == TPAR) {
                    218:                        t1 = t->t_dspr;
                    219:                        t1->t_dflg |= flags & FINT;
                    220:                        OLDSTD = dcopy(0, FOLDSTD);
                    221:                        SHOUT = dcopy(1, FSHOUT);
                    222:                        SHDIAG = dcopy(2, FSHDIAG);
                    223:                        close(SHIN), SHIN = -1;
                    224:                        didcch = 0, didfds = 0;
                    225:                        execute(t1);
                    226:                        exitstat();
                    227:                }
                    228:                if (eq(t->t_dcom[0], "nice")) {
                    229: /* sigh...
                    230:                        nice(20);
                    231:                        nice(-10);
                    232: */
                    233:                        cp = t->t_dcom[1];
                    234:                        if (any(cp[0], "+-"))
                    235:                                nice(getn(cp)), lshift(t->t_dcom, 2);
                    236:                        else
                    237:                                nice(4), lshift(t->t_dcom, 1);
                    238:                        t->t_dflg = FPAR | FREDO;
                    239:                        execute(t);
                    240:                        exitstat();
                    241:                }
                    242:                if (eq(t->t_dcom[0], "nohup")) {
                    243:                        if (setintr == 0)
                    244:                                signal(SIGHUP, SIG_IGN);
                    245:                        signal(SIGTERM, SIG_IGN);
                    246:                        lshift(t->t_dcom, 1);
                    247:                        t->t_dflg = FPAR | FREDO;
                    248:                        execute(t);
                    249:                        exitstat();
                    250:                }
                    251:                doexec(t);
                    252:                /* no return */
                    253: 
                    254:        case TFIL:
                    255:                flags = t->t_dflg;
                    256:                t1 = t->t_dcar;
                    257:                t1->t_dflg |= FPOU | (flags & (FPIN|FINT|FPRS|FDIAG));
                    258:                execute(t1, pipein, pv);
                    259:                t1 = t->t_dcdr;
                    260:                t1->t_dflg |= FPIN | (flags & (FPOU|FINT|FAND|FPRS|FPAR));
                    261:                execute(t1, pv, pipeout);
                    262:                return;
                    263: 
                    264:        case TLST:
                    265:                flags = t->t_dflg & FINT;
                    266:                if (t1 = t->t_dcar)
                    267:                        t1->t_dflg |= flags, execute(t1);
                    268:                if (t1 = t->t_dcdr)
                    269:                        t1->t_dflg |= t->t_dflg & (FINT|FPAR), execute(t1);
                    270:                return;
                    271: 
                    272:        case TOR:
                    273:        case TAND:
                    274:                flags = t->t_dflg & FINT;
                    275:                if (t1 = t->t_dcar) {
                    276:                        t1->t_dflg |= flags, execute(t1);
                    277:                        if ((getn(value("status")) == 0) == (t->t_dtyp == TAND))
                    278:                                return;
                    279:                }
                    280:                if (t1 = t->t_dcdr)
                    281:                        t1->t_dflg |= t->t_dflg & (FINT|FPAR), execute(t1);
                    282:                return;
                    283:        }
                    284: }
                    285: 
                    286: #ifdef VFORK
                    287: vffree()
                    288: {
                    289:        register char **v;
                    290: 
                    291:        if (v = gargv)
                    292:                gargv = 0, xfree(gargv);
                    293:        if (v = pargv)
                    294:                pargv = 0, xfree(pargv);
                    295:        _exit(1);
                    296: }
                    297: #endif
                    298: 
                    299: doio(t, pipein, pipeout)
                    300:        register struct command *t;
                    301:        int *pipein, *pipeout;
                    302: {
                    303:        register char *cp;
                    304:        register int flags = t->t_dflg;
                    305:        char *dp;
                    306: 
                    307:        if (didfds || (flags & FREDO))
                    308:                return;
                    309:        if (flags & FHERE)
                    310:                goto skipin;
                    311:        close(0);
                    312:        if (cp = t->t_dlef) {
                    313:                cp = globone(dp = Dfix1(cp));
                    314:                xfree(dp);
                    315:                xfree(cp);
                    316:                if (open(cp, 0) < 0)
                    317:                        Perror(cp);
                    318:        } else if (flags & FPIN)
                    319:                dup(pipein[0]), close(pipein[0]), close(pipein[1]);
                    320:        else if (flags & FINT)
                    321:                close(0), open("/dev/null", 0);
                    322:        else
                    323:                dup(OLDSTD);
                    324: 
                    325: skipin:
                    326:        close(1);
                    327:        if (cp = t->t_drit) {
                    328:                cp = globone(dp = Dfix1(cp));
                    329:                xfree(dp);
                    330:                xfree(cp);
                    331:                if ((flags & FCAT) && open(cp, 1) >= 0)
                    332:                        lseek(1, 0l, 2);
                    333:                else {
                    334:                        if (!(flags & FANY) && adrof("noclobber")) {
                    335:                                if (flags & FCAT)
                    336:                                        Perror(cp);
                    337:                                chkclob(cp);
                    338:                        }
                    339: #ifdef V6
                    340:                        if (creat(cp, 0644) < 0)
                    341:                                Perror(cp);
                    342: #else
                    343:                        if (creat(cp, 0666) < 0)
                    344:                                Perror(cp);
                    345: #endif
                    346:                }
                    347:        } else
                    348:                dup((flags & FPOU) ? pipeout[1] : SHOUT);
                    349: 
                    350:        close(2);
                    351:        dup((flags & FDIAG) ? 1 : SHDIAG);
                    352:        didfds = 1;
                    353: }
                    354: 
                    355: dofork(shudint, shudhup)
                    356:        bool shudint, shudhup;
                    357: {
                    358:        register int pid, (*savint)();
                    359: 
                    360:        savint = signal(SIGINT, SIG_IGN);
                    361:        pid = fork();
                    362:        if (pid < 0) {
                    363:                signal(SIGINT, savint);
                    364:                error("No more processes");
                    365:        }
                    366:        if (pid == 0) {
                    367:                child++;
                    368:                signal(SIGINT, shudint ? SIG_DFL : savint);
                    369:                if (!shudhup)
                    370:                        signal(SIGHUP, SIG_IGN);
                    371:        } else
                    372:                signal(SIGINT, savint);
                    373:        return (pid);
                    374: }
                    375: 
                    376: mypipe(pv)
                    377:        register int *pv;
                    378: {
                    379: 
                    380:        if (pipe(pv) < 0)
                    381:                goto oops;
                    382:        pv[0] = dmove(pv[0], -1);
                    383:        pv[1] = dmove(pv[1], -1);
                    384:        if (pv[0] >= 0 && pv[1] >= 0)
                    385:                return;
                    386: oops:
                    387:        error("Can't make pipe");
                    388: }
                    389: 
                    390: chkclob(cp)
                    391:        register char *cp;
                    392: {
                    393:        struct stat stb;
                    394: 
                    395:        if (stat(cp, &stb) < 0)
                    396:                return;
                    397:        if ((stb.st_mode & S_IFMT) == S_IFCHR)
                    398:                return;
                    399:        error("%s: File exists", cp);
                    400: }

unix.superglobalmegacorp.com

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