Annotation of 42BSD/bin/csh/sh.sem.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)sh.sem.c 4.3 6/11/83";
                      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: #ifdef notdef
                    155:                                        sigsys(SIGCHLD, SIG_DFL);
                    156: #endif
                    157:                                        sigsys(SIGINT,
                    158:                                            ignint ? SIG_IGN : vffree);
                    159:                                        sigsys(SIGQUIT,
                    160:                                            ignint ? SIG_IGN : SIG_DFL);
                    161:                                        if (wanttty >= 0) {
                    162:                                                sigsys(SIGTSTP, SIG_DFL);
                    163:                                                sigsys(SIGTTIN, SIG_DFL);
                    164:                                                sigsys(SIGTTOU, SIG_DFL);
                    165:                                        }
                    166:                                        sigsys(SIGTERM, parterm);
                    167:                                } else if (tpgrp == -1 && (t->t_dflg&FINT)) {
                    168:                                        sigsys(SIGINT, SIG_IGN);
                    169:                                        sigsys(SIGQUIT, SIG_IGN);
                    170:                                }
                    171:                                if (wanttty > 0)
                    172:                                        ioctl(FSHTTY, TIOCSPGRP, &pgrp);
                    173:                                if (wanttty >= 0 && tpgrp >= 0)
                    174:                                        setpgrp(0, pgrp);
                    175:                                if (tpgrp > 0)
                    176:                                        tpgrp = 0;
                    177:                                if (t->t_dflg & FNOHUP)
                    178:                                        sigsys(SIGHUP, SIG_IGN);
                    179:                                if (t->t_dflg & FNICE)
                    180:                                        nice(t->t_nice);
                    181:                        }
                    182: 
                    183:                }
                    184: #endif
                    185:                if (pid != 0) {
                    186:                        /*
                    187:                         * It would be better if we could wait for the
                    188:                         * whole job when we knew the last process
                    189:                         * had been started.  Pwait, in fact, does
                    190:                         * wait for the whole job anyway, but this test
                    191:                         * doesn't really express our intentions.
                    192:                         */
                    193:                        if (didfds==0 && t->t_dflg&FPIN)
                    194:                                close(pipein[0]), close(pipein[1]);
                    195:                        if ((t->t_dflg & (FPOU|FAND)) == 0)
                    196:                                pwait();
                    197:                        break;
                    198:                }
                    199:                doio(t, pipein, pipeout);
                    200:                if (t->t_dflg & FPOU)
                    201:                        close(pipeout[0]), close(pipeout[1]);
                    202: 
                    203:                /*
                    204:                 * Perform a builtin function.
                    205:                 * If we are not forked, arrange for possible stopping
                    206:                 */
                    207:                if (bifunc) {
                    208:                        func(t, bifunc);
                    209:                        if (forked)
                    210:                                exitstat();
                    211:                        break;
                    212:                }
                    213:                if (t->t_dtyp != TPAR) {
                    214:                        doexec(t);
                    215:                        /*NOTREACHED*/
                    216:                }
                    217:                /*
                    218:                 * For () commands must put new 0,1,2 in FSH* and recurse
                    219:                 */
                    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:                wanttty = -1;
                    226:                t->t_dspr->t_dflg |= t->t_dflg & FINT;
                    227:                execute(t->t_dspr, wanttty);
                    228:                exitstat();
                    229: 
                    230:        case TFIL:
                    231:                t->t_dcar->t_dflg |= FPOU |
                    232:                    (t->t_dflg & (FPIN|FAND|FDIAG|FINT));
                    233:                execute(t->t_dcar, wanttty, pipein, pv);
                    234:                t->t_dcdr->t_dflg |= FPIN |
                    235:                    (t->t_dflg & (FPOU|FAND|FPAR|FINT));
                    236:                if (wanttty > 0)
                    237:                        wanttty = 0;            /* got tty already */
                    238:                execute(t->t_dcdr, wanttty, pv, pipeout);
                    239:                break;
                    240: 
                    241:        case TLST:
                    242:                if (t->t_dcar) {
                    243:                        t->t_dcar->t_dflg |= t->t_dflg & FINT;
                    244:                        execute(t->t_dcar, wanttty);
                    245:                        /*
                    246:                         * In strange case of A&B make a new job after A
                    247:                         */
                    248:                        if (t->t_dcar->t_dflg&FAND && t->t_dcdr &&
                    249:                            (t->t_dcdr->t_dflg&FAND) == 0)
                    250:                                pendjob();
                    251:                }
                    252:                if (t->t_dcdr) {
                    253:                        t->t_dcdr->t_dflg |= t->t_dflg & (FPAR|FINT);
                    254:                        execute(t->t_dcdr, wanttty);
                    255:                }
                    256:                break;
                    257: 
                    258:        case TOR:
                    259:        case TAND:
                    260:                if (t->t_dcar) {
                    261:                        t->t_dcar->t_dflg |= t->t_dflg & FINT;
                    262:                        execute(t->t_dcar, wanttty);
                    263:                        if ((getn(value("status")) == 0) != (t->t_dtyp == TAND))
                    264:                                return;
                    265:                }
                    266:                if (t->t_dcdr) {
                    267:                        t->t_dcdr->t_dflg |= t->t_dflg & (FPAR|FINT);
                    268:                        execute(t->t_dcdr, wanttty);
                    269:                }
                    270:                break;
                    271:        }
                    272:        /*
                    273:         * Fall through for all breaks from switch
                    274:         *
                    275:         * If there will be no more executions of this
                    276:         * command, flush all file descriptors.
                    277:         * Places that turn on the FREDO bit are responsible
                    278:         * for doing donefds after the last re-execution
                    279:         */
                    280:        if (didfds && !(t->t_dflg & FREDO))
                    281:                donefds();
                    282: }
                    283: 
                    284: #ifdef VFORK
                    285: vffree()
                    286: {
                    287:        register char **v;
                    288: 
                    289:        if (v = gargv)
                    290:                gargv = 0, xfree(gargv);
                    291:        if (v = pargv)
                    292:                pargv = 0, xfree(pargv);
                    293:        _exit(1);
                    294: }
                    295: #endif
                    296: 
                    297: /*
                    298:  * Perform io redirection.
                    299:  * We may or maynot be forked here.
                    300:  */
                    301: doio(t, pipein, pipeout)
                    302:        register struct command *t;
                    303:        int *pipein, *pipeout;
                    304: {
                    305:        register char *cp;
                    306:        register int flags = t->t_dflg;
                    307: 
                    308:        if (didfds || (flags & FREDO))
                    309:                return;
                    310:        if ((flags & FHERE) == 0) {     /* FHERE already done */
                    311:                close(0);
                    312:                if (cp = t->t_dlef) {
                    313:                        cp = globone(Dfix1(cp));
                    314:                        xfree(cp);
                    315:                        if (open(cp, 0) < 0)
                    316:                                Perror(cp);
                    317:                } else if (flags & FPIN)
                    318:                        dup(pipein[0]), close(pipein[0]), close(pipein[1]);
                    319:                else if ((flags & FINT) && tpgrp == -1)
                    320:                        close(0), open("/dev/null", 0);
                    321:                else
                    322:                        dup(OLDSTD);
                    323:        }
                    324:        close(1);
                    325:        if (cp = t->t_drit) {
                    326:                cp = globone(Dfix1(cp));
                    327:                xfree(cp);
                    328:                if ((flags & FCAT) && open(cp, 1) >= 0)
                    329:                        lseek(1, 0l, 2);
                    330:                else {
                    331:                        if (!(flags & FANY) && adrof("noclobber")) {
                    332:                                if (flags & FCAT)
                    333:                                        Perror(cp);
                    334:                                chkclob(cp);
                    335:                        }
                    336:                        if (creat(cp, 0666) < 0)
                    337:                                Perror(cp);
                    338:                }
                    339:        } else if (flags & FPOU)
                    340:                dup(pipeout[1]);
                    341:        else
                    342:                dup(SHOUT);
                    343: 
                    344:        close(2);
                    345:        dup((flags & FDIAG) ? 1 : SHDIAG);
                    346:        didfds = 1;
                    347: }
                    348: 
                    349: mypipe(pv)
                    350:        register int *pv;
                    351: {
                    352: 
                    353:        if (pipe(pv) < 0)
                    354:                goto oops;
                    355:        pv[0] = dmove(pv[0], -1);
                    356:        pv[1] = dmove(pv[1], -1);
                    357:        if (pv[0] >= 0 && pv[1] >= 0)
                    358:                return;
                    359: oops:
                    360:        error("Can't make pipe");
                    361: }
                    362: 
                    363: chkclob(cp)
                    364:        register char *cp;
                    365: {
                    366:        struct stat stb;
                    367: 
                    368:        if (stat(cp, &stb) < 0)
                    369:                return;
                    370:        if ((stb.st_mode & S_IFMT) == S_IFCHR)
                    371:                return;
                    372:        error("%s: File exists", cp);
                    373: }

unix.superglobalmegacorp.com

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