Annotation of 43BSDTahoe/bin/csh/sh.sem.c, revision 1.1

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

unix.superglobalmegacorp.com

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