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

unix.superglobalmegacorp.com

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