Annotation of 41BSD/cmd/oldcsh/sh.sem.c, revision 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.