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