Annotation of 41BSD/cmd/csh/sh.sem.c, revision 1.1

1.1     ! root        1: static char *sccsid = "@(#)sh.sem.c 4.1 10/9/80";
        !             2: 
        !             3: #include "sh.h"
        !             4: #include "sh.proc.h"
        !             5: #include <sys/ioctl.h>
        !             6: 
        !             7: /*
        !             8:  * C shell
        !             9:  */
        !            10: 
        !            11: /*VARARGS 1*/
        !            12: execute(t, wanttty, pipein, pipeout)
        !            13:        register struct command *t;
        !            14:        int wanttty, *pipein, *pipeout;
        !            15: {
        !            16:        bool forked = 0;
        !            17:        struct biltins *bifunc;
        !            18:        int pid = 0;
        !            19:        int pv[2];
        !            20: 
        !            21:        if (t == 0)
        !            22:                return;
        !            23:        if ((t->t_dflg & FAND) && wanttty > 0)
        !            24:                wanttty = 0;
        !            25:        switch (t->t_dtyp) {
        !            26: 
        !            27:        case TCOM:
        !            28:                if ((t->t_dcom[0][0] & (QUOTE|TRIM)) == QUOTE)
        !            29:                        strcpy(t->t_dcom[0], t->t_dcom[0] + 1);
        !            30:                if ((t->t_dflg & FREDO) == 0)
        !            31:                        Dfix(t);                /* $ " ' \ */
        !            32:                if (t->t_dcom[0] == 0)
        !            33:                        return;
        !            34:                /* fall into... */
        !            35: 
        !            36:        case TPAR:
        !            37:                if (t->t_dflg & FPOU)
        !            38:                        mypipe(pipeout);
        !            39:                /*
        !            40:                 * Must do << early so parent will know
        !            41:                 * where input pointer should be.
        !            42:                 * If noexec then this is all we do.
        !            43:                 */
        !            44:                if (t->t_dflg & FHERE) {
        !            45:                        close(0);
        !            46:                        heredoc(t->t_dlef);
        !            47:                        if (noexec)
        !            48:                                close(0);
        !            49:                }
        !            50:                if (noexec)
        !            51:                        break;
        !            52: 
        !            53:                set("status", "0");
        !            54: 
        !            55:                /*
        !            56:                 * This mess is the necessary kludge to handle the prefix
        !            57:                 * builtins: nice, nohup, time.  These commands can also
        !            58:                 * be used by themselves, and this is not handled here.
        !            59:                 * This will also work when loops are parsed.
        !            60:                 */
        !            61:                while (t->t_dtyp == TCOM)
        !            62:                        if (eq(t->t_dcom[0], "nice"))
        !            63:                                if (t->t_dcom[1])
        !            64:                                        if (any(t->t_dcom[1][0], "+-"))
        !            65:                                                if (t->t_dcom[2]) {
        !            66:                                                        setname("nice");
        !            67:                                                        t->t_nice = getn(t->t_dcom[1]);
        !            68:                                                        lshift(t->t_dcom, 2);
        !            69:                                                        t->t_dflg |= FNICE;
        !            70:                                                } else
        !            71:                                                        break;
        !            72:                                        else {
        !            73:                                                t->t_nice = 4;
        !            74:                                                lshift(t->t_dcom, 1);
        !            75:                                                t->t_dflg |= FNICE;
        !            76:                                        }
        !            77:                                else
        !            78:                                        break;
        !            79:                        else if (eq(t->t_dcom[0], "nohup"))
        !            80:                                if (t->t_dcom[1]) {
        !            81:                                        t->t_dflg |= FNOHUP;
        !            82:                                        lshift(t->t_dcom, 1);
        !            83:                                } else
        !            84:                                        break;
        !            85:                        else if (eq(t->t_dcom[0], "time"))
        !            86:                                if (t->t_dcom[1]) {
        !            87:                                        t->t_dflg |= FTIME;
        !            88:                                        lshift(t->t_dcom, 1);
        !            89:                                } else
        !            90:                                        break;
        !            91:                        else
        !            92:                                break;
        !            93:                /*
        !            94:                 * Check if we have a builtin function and remember which one.
        !            95:                 */
        !            96:                bifunc = t->t_dtyp == TCOM ? isbfunc(t) : (struct biltins *) 0;
        !            97: 
        !            98:                /*
        !            99:                 * We fork only if we are timed, or are not the end of
        !           100:                 * a parenthesized list and not a simple builtin function.
        !           101:                 * Simple meaning one that is not pipedout, niced, nohupped,
        !           102:                 * or &'d.
        !           103:                 * It would be nice(?) to not fork in some of these cases.
        !           104:                 */
        !           105:                if (((t->t_dflg & FTIME) || (t->t_dflg & FPAR) == 0 &&
        !           106:                     (!bifunc || t->t_dflg & (FPOU|FAND|FNICE|FNOHUP))))
        !           107: #ifdef VFORK
        !           108:                    if (t->t_dtyp == TPAR || t->t_dflg&(FREDO|FAND) || bifunc)
        !           109: #endif
        !           110:                        { forked++; pid = pfork(t, wanttty); }
        !           111: #ifdef VFORK
        !           112:                    else {
        !           113:                        int vffree();
        !           114:                        int ochild, osetintr, ohaderr, odidfds, odidcch;
        !           115:                        int oSHIN, oSHOUT, oSHDIAG, oOLDSTD, otpgrp;
        !           116: 
        !           117:                        sighold(SIGCHLD);
        !           118:                        ochild = child; osetintr = setintr;
        !           119:                        ohaderr = haderr; odidfds = didfds; odidcch = didcch;
        !           120:                        oSHIN = SHIN; oSHOUT = SHOUT;
        !           121:                        oSHDIAG = SHDIAG; oOLDSTD = OLDSTD; otpgrp = tpgrp;
        !           122:                        Vsav = Vdp = 0; Vav = 0;
        !           123:                        pid = vfork();
        !           124:                        if (pid < 0) {
        !           125:                                sigrelse(SIGCHLD);
        !           126:                                error("No more processes");
        !           127:                        }
        !           128:                        forked++;
        !           129:                        if (pid) {
        !           130:                                child = ochild; setintr = osetintr;
        !           131:                                haderr = ohaderr; didfds = odidfds;
        !           132:                                didcch = odidcch; SHIN = oSHIN;
        !           133:                                SHOUT = oSHOUT; SHDIAG = oSHDIAG;
        !           134:                                OLDSTD = oOLDSTD; tpgrp = otpgrp;
        !           135:                                xfree(Vsav); Vsav = 0;
        !           136:                                xfree(Vdp); Vdp = 0;
        !           137:                                xfree(Vav); Vav = 0;
        !           138:                                /* this is from pfork() */
        !           139:                                palloc(pid, t);
        !           140:                                sigrelse(SIGCHLD);
        !           141:                        } else {
        !           142:                                /* this is from pfork() */
        !           143:                                int pgrp;
        !           144:                                bool ignint = 0;
        !           145: 
        !           146:                                if (setintr)
        !           147:                                        ignint =
        !           148:                                            (tpgrp == -1 && (t->t_dflg&FINT))
        !           149:                                            || gointr && eq(gointr, "-");
        !           150:                                pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();
        !           151:                                child++;
        !           152:                                if (setintr) {
        !           153:                                        setintr = 0;
        !           154:                                        sigsys(SIGCHLD, SIG_DFL);
        !           155:                                        sigsys(SIGINT, ignint ? SIG_IGN : vffree);
        !           156:                                        sigsys(SIGQUIT, ignint ? SIG_IGN : SIG_DFL);
        !           157:                                        if (wanttty >= 0) {
        !           158:                                                sigsys(SIGTSTP, SIG_DFL);
        !           159:                                                sigsys(SIGTTIN, SIG_DFL);
        !           160:                                                sigsys(SIGTTOU, SIG_DFL);
        !           161:                                        }
        !           162:                                        sigsys(SIGTERM, parterm);
        !           163:                                } else if (tpgrp == -1 && (t->t_dflg&FINT)) {
        !           164:                                        sigsys(SIGINT, SIG_IGN);
        !           165:                                        sigsys(SIGQUIT, SIG_IGN);
        !           166:                                }
        !           167:                                if (wanttty > 0)
        !           168:                                        ioctl(FSHTTY, TIOCSPGRP, &pgrp);
        !           169:                                if (wanttty >= 0 && tpgrp >= 0)
        !           170:                                        setpgrp(0, pgrp);
        !           171:                                if (tpgrp > 0)
        !           172:                                        tpgrp = 0;
        !           173:                                if (t->t_dflg & FNOHUP)
        !           174:                                        sigsys(SIGHUP, SIG_IGN);
        !           175:                                if (t->t_dflg & FNICE)
        !           176:                                        nice(t->t_nice);
        !           177:                        }
        !           178: 
        !           179:                }
        !           180: #endif
        !           181:                if (pid != 0) {
        !           182:                        /*
        !           183:                         * It would be better if we could wait for the
        !           184:                         * whole job when we knew the last process
        !           185:                         * had been started.  Pwait, in fact, does
        !           186:                         * wait for the whole job anyway, but this test
        !           187:                         * doesn't really express our intentions.
        !           188:                         */
        !           189:                        if (didfds==0 && t->t_dflg&FPIN)
        !           190:                                close(pipein[0]), close(pipein[1]);
        !           191:                        if ((t->t_dflg & (FPOU|FAND)) == 0)
        !           192:                                pwait();
        !           193:                        break;
        !           194:                }
        !           195:                doio(t, pipein, pipeout);
        !           196:                if (t->t_dflg & FPOU)
        !           197:                        close(pipeout[0]), close(pipeout[1]);
        !           198: 
        !           199:                /*
        !           200:                 * Perform a builtin function.
        !           201:                 * If we are not forked, arrange for possible stopping
        !           202:                 */
        !           203:                if (bifunc) {
        !           204:                        func(t, bifunc);
        !           205:                        if (forked)
        !           206:                                exitstat();
        !           207:                        break;
        !           208:                }
        !           209:                if (t->t_dtyp != TPAR) {
        !           210:                        doexec(t);
        !           211:                        /*NOTREACHED*/
        !           212:                }
        !           213:                /*
        !           214:                 * For () commands must put new 0,1,2 in FSH* and recurse
        !           215:                 */
        !           216:                OLDSTD = dcopy(0, FOLDSTD);
        !           217:                SHOUT = dcopy(1, FSHOUT);
        !           218:                SHDIAG = dcopy(2, FSHDIAG);
        !           219:                close(SHIN), SHIN = -1;
        !           220:                didcch = 0, didfds = 0;
        !           221:                wanttty = -1;
        !           222:                t->t_dspr->t_dflg |= t->t_dflg & FINT;
        !           223:                execute(t->t_dspr, wanttty);
        !           224:                exitstat();
        !           225: 
        !           226:        case TFIL:
        !           227:                t->t_dcar->t_dflg |= FPOU |
        !           228:                    (t->t_dflg & (FPIN|FAND|FDIAG|FINT));
        !           229:                execute(t->t_dcar, wanttty, pipein, pv);
        !           230:                t->t_dcdr->t_dflg |= FPIN |
        !           231:                    (t->t_dflg & (FPOU|FAND|FPAR|FINT));
        !           232:                if (wanttty > 0)
        !           233:                        wanttty = 0;            /* got tty already */
        !           234:                execute(t->t_dcdr, wanttty, pv, pipeout);
        !           235:                break;
        !           236: 
        !           237:        case TLST:
        !           238:                if (t->t_dcar) {
        !           239:                        t->t_dcar->t_dflg |= t->t_dflg & FINT;
        !           240:                        execute(t->t_dcar, wanttty);
        !           241:                        /*
        !           242:                         * In strange case of A&B make a new job after A
        !           243:                         */
        !           244:                        if (t->t_dcar->t_dflg&FAND && t->t_dcdr &&
        !           245:                            (t->t_dcdr->t_dflg&FAND) == 0)
        !           246:                                pendjob();
        !           247:                }
        !           248:                if (t->t_dcdr) {
        !           249:                        t->t_dcdr->t_dflg |= t->t_dflg & (FPAR|FINT);
        !           250:                        execute(t->t_dcdr, wanttty);
        !           251:                }
        !           252:                break;
        !           253: 
        !           254:        case TOR:
        !           255:        case TAND:
        !           256:                if (t->t_dcar) {
        !           257:                        t->t_dcar->t_dflg |= t->t_dflg & FINT;
        !           258:                        execute(t->t_dcar, wanttty);
        !           259:                        if ((getn(value("status")) == 0) != (t->t_dtyp == TAND))
        !           260:                                return;
        !           261:                }
        !           262:                if (t->t_dcdr) {
        !           263:                        t->t_dcdr->t_dflg |= t->t_dflg & (FPAR|FINT);
        !           264:                        execute(t->t_dcdr, wanttty);
        !           265:                }
        !           266:                break;
        !           267:        }
        !           268:        /*
        !           269:         * Fall through for all breaks from switch
        !           270:         *
        !           271:         * If there will be no more executions of this
        !           272:         * command, flush all file descriptors.
        !           273:         * Places that turn on the FREDO bit are responsible
        !           274:         * for doing donefds after the last re-execution
        !           275:         */
        !           276:        if (didfds && !(t->t_dflg & FREDO))
        !           277:                donefds();
        !           278: }
        !           279: 
        !           280: #ifdef VFORK
        !           281: vffree()
        !           282: {
        !           283:        register char **v;
        !           284: 
        !           285:        if (v = gargv)
        !           286:                gargv = 0, xfree(gargv);
        !           287:        if (v = pargv)
        !           288:                pargv = 0, xfree(pargv);
        !           289:        _exit(1);
        !           290: }
        !           291: #endif
        !           292: 
        !           293: /*
        !           294:  * Perform io redirection.
        !           295:  * We may or maynot be forked here.
        !           296:  */
        !           297: doio(t, pipein, pipeout)
        !           298:        register struct command *t;
        !           299:        int *pipein, *pipeout;
        !           300: {
        !           301:        register char *cp;
        !           302:        register int flags = t->t_dflg;
        !           303: 
        !           304:        if (didfds || (flags & FREDO))
        !           305:                return;
        !           306:        if ((flags & FHERE) == 0) {     /* FHERE already done */
        !           307:                close(0);
        !           308:                if (cp = t->t_dlef) {
        !           309:                        cp = globone(Dfix1(cp));
        !           310:                        xfree(cp);
        !           311:                        if (open(cp, 0) < 0)
        !           312:                                Perror(cp);
        !           313:                } else if (flags & FPIN)
        !           314:                        dup(pipein[0]), close(pipein[0]), close(pipein[1]);
        !           315:                else if ((flags & FINT) && tpgrp == -1)
        !           316:                        close(0), open("/dev/null", 0);
        !           317:                else
        !           318:                        dup(OLDSTD);
        !           319:        }
        !           320:        close(1);
        !           321:        if (cp = t->t_drit) {
        !           322:                cp = globone(Dfix1(cp));
        !           323:                xfree(cp);
        !           324:                if ((flags & FCAT) && open(cp, 1) >= 0)
        !           325:                        lseek(1, 0l, 2);
        !           326:                else {
        !           327:                        if (!(flags & FANY) && adrof("noclobber")) {
        !           328:                                if (flags & FCAT)
        !           329:                                        Perror(cp);
        !           330:                                chkclob(cp);
        !           331:                        }
        !           332:                        if (creat(cp, 0666) < 0)
        !           333:                                Perror(cp);
        !           334:                }
        !           335:        } else if (flags & FPOU)
        !           336:                dup(pipeout[1]);
        !           337:        else
        !           338:                dup(SHOUT);
        !           339: 
        !           340:        close(2);
        !           341:        dup((flags & FDIAG) ? 1 : SHDIAG);
        !           342:        didfds = 1;
        !           343: }
        !           344: 
        !           345: mypipe(pv)
        !           346:        register int *pv;
        !           347: {
        !           348: 
        !           349:        if (pipe(pv) < 0)
        !           350:                goto oops;
        !           351:        pv[0] = dmove(pv[0], -1);
        !           352:        pv[1] = dmove(pv[1], -1);
        !           353:        if (pv[0] >= 0 && pv[1] >= 0)
        !           354:                return;
        !           355: oops:
        !           356:        error("Can't make pipe");
        !           357: }
        !           358: 
        !           359: chkclob(cp)
        !           360:        register char *cp;
        !           361: {
        !           362:        struct stat stb;
        !           363: 
        !           364:        if (stat(cp, &stb) < 0)
        !           365:                return;
        !           366:        if ((stb.st_mode & S_IFMT) == S_IFCHR)
        !           367:                return;
        !           368:        error("%s: File exists", cp);
        !           369: }

unix.superglobalmegacorp.com

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