Annotation of coherent/b/bin/sh_B4_420/exec2.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * sh/exec2.c
        !             3:  * Bourne shell.
        !             4:  * System part of execution.
        !             5:  */
        !             6: 
        !             7: #include "sh.h"
        !             8: #include <errno.h>
        !             9: #include <sys/param.h>
        !            10: #include <signal.h>
        !            11: #include <sys/stat.h>
        !            12: #include <fcntl.h>
        !            13: 
        !            14: /*
        !            15:  * Wait for the given process to complete.
        !            16:  */
        !            17: waitc(pid)
        !            18: int pid;
        !            19: {
        !            20:        register int f;
        !            21:        unsigned s;
        !            22:        register int w, n;
        !            23:        int     (*ssig)();
        !            24: 
        !            25:        if (pid < 0)
        !            26:                f = -pid;
        !            27:        else
        !            28:                f = pid;
        !            29:        if ((ssig=signal(SIGINT, SIG_IGN)) != SIG_IGN)
        !            30:                signal(SIGINT, sigintr);
        !            31:        for (;;) {
        !            32:                if ((w=wait(&s)) >= 0) {
        !            33:                        if (n = (s&0177)) {
        !            34:                                if (n==SIGINT)
        !            35:                                        sigintr(n);
        !            36:                                else if (n==SIGPIPE && spipe
        !            37:                                         && (w >= spipe && w <= f))
        !            38:                                        ;
        !            39:                                else {
        !            40:                                        if (w != f)
        !            41:                                                prints("%d: ", w);
        !            42:                                        if (n==SIGSYS && (s&0200)==0)
        !            43:                                            prints("exec failed");
        !            44:                                        else if (n>0 && n<=NSIG)
        !            45:                                                prints("%s", signame[n]);
        !            46:                                        else
        !            47:                                                prints("status %d", n);
        !            48:                                        if (s & 0200)
        !            49:                                                prints(" -- core dumped");
        !            50:                                        prints("\n");
        !            51:                                }
        !            52:                                s = 200 + n;
        !            53:                        } else
        !            54:                                s >>= 8;
        !            55:                        if (w == f) {
        !            56:                                slret = s;
        !            57:                                break;
        !            58:                        }
        !            59:                } else if (errno==EINTR) {
        !            60:                        if (pid > 0)
        !            61:                                continue;
        !            62:                        else {
        !            63:                                slret = 0;
        !            64:                                break;
        !            65:                        }
        !            66:                } else if (errno==ECHILD) {
        !            67:                        if (pid == 0)   
        !            68:                                slret = 0;
        !            69:                        else
        !            70:                                slret = ECHILD;
        !            71:                        break;
        !            72:                } else {
        !            73:                        panic(6);
        !            74:                        NOTREACHED;
        !            75:                }
        !            76:        }
        !            77:        signal(SIGINT, ssig);
        !            78:        return (slret);
        !            79: }
        !            80: 
        !            81: /*
        !            82:  * Make an imperfect copy of ourself.
        !            83:  */
        !            84: clone()
        !            85: {
        !            86:        register int f;
        !            87:        register SES *sp;
        !            88: 
        !            89:        if ((f=fork()) < 0) {
        !            90:                prints("Try again\n");
        !            91:                reset(RSYSER);
        !            92:                NOTREACHED;
        !            93:        } else if (f == 0) {
        !            94:                nllflag = 1;
        !            95:                sflag = iflag = cflag = no1flag = lgnflag = 0;
        !            96:                slret = spipe = 0;
        !            97:                sp = sesp;
        !            98:                sp->s_con->c_next = NULL;
        !            99: 
        !           100:                /*
        !           101:                 * Originally this function suppressed function definitions
        !           102:                 * in child processes. This is wrong. Note that we have to
        !           103:                 * detach the temporary-file stuff from the child functions,
        !           104:                 * however, so that functions with here-documents work (as
        !           105:                 * long as the top-level shell is alive, that is).
        !           106:                 */
        !           107: #if 1
        !           108:                subshell_shell_fns ();
        !           109: #else
        !           110:                sh_fnp = NULL;
        !           111: #endif
        !           112: 
        !           113:                while (sp) {
        !           114:                        if (sp->s_type == SFILE)
        !           115:                                fclose(sp->s_ifp);
        !           116:                        sp = sp->s_next;
        !           117:                }
        !           118:                dflttrp(IFORK);
        !           119:        }
        !           120:        return (f);
        !           121: }
        !           122: 
        !           123: /*
        !           124:  * Open a pipe, panic on failure.
        !           125:  * Otherwise return as a clone.
        !           126:  */
        !           127: pipeline(pv)
        !           128: int *pv;
        !           129: {
        !           130:        if (pipe(pv) < 0) {
        !           131:                prints("Pipe failed\n");
        !           132:                reset(RSYSER);
        !           133:                NOTREACHED;
        !           134:        }
        !           135:        return (clone());
        !           136: }
        !           137: 
        !           138: /*
        !           139:  * Try to execute a file in several ways.
        !           140:  *     A return is always an error.
        !           141:  *     Used by exec in inline.
        !           142:  */
        !           143: flexec()
        !           144: {
        !           145:        ffind(NULL);
        !           146:        while (ffind(vpath, *nargv, 1)) {
        !           147:                execve(strt, nargv, nenvp);
        !           148:                if (errno==ENOEXEC) {
        !           149:                        scmdp = duplstr(strt, 0);
        !           150:                        nargc += 1;
        !           151:                        nargv -= 1;
        !           152:                        nargv = vdupl(nargv);
        !           153:                        nenvp = vdupl(nenvp);
        !           154:                        while (sesp) {
        !           155:                                freebuf(sesp->s_bpp);
        !           156:                                sesp = sesp->s_next;
        !           157:                        }
        !           158:                        longjmp(restart, 1);
        !           159:                }
        !           160:                if (errno==E2BIG) {
        !           161:                        e2big(nargv[0]);
        !           162:                        return(-1);
        !           163:                }
        !           164:        }
        !           165:        ecantfind(nargv[0]);
        !           166:        return (-1);
        !           167: }
        !           168: 
        !           169: ALLOC_COUNT (undo)
        !           170: 
        !           171: /*
        !           172:  * Process a redirection vector.
        !           173:  * Abort and return -1 at the first failure, return 0 for success.
        !           174:  *
        !           175:  * NB: In ordr to support redirection of builtins, an extra argument to this
        !           176:  * function has been addded. If undo is NULL, things remain as before, but if
        !           177:  * non-NULL it is taken to be the head of a list of undo items. As the list of
        !           178:  * redirections is processed, undo entries will be added to the head of the
        !           179:  * list, so that the caller will see the list in the appropriate order for
        !           180:  * undoing the redirections.
        !           181:  */
        !           182: redirect(iovp, undo)
        !           183: char **iovp;
        !           184: REDIR_UNDO ** undo;
        !           185: {
        !           186:        register char **iopp;
        !           187:        register char *io;
        !           188:        register int op;
        !           189:        int u1, u2;
        !           190:        REDIR_UNDO * undo_node;
        !           191: 
        !           192:        for (iopp = iovp;(io = *iopp++)!=NULL; ) {
        !           193:                if (class(*io, MDIGI))
        !           194:                        u1 = *io++ - '0';
        !           195:                else
        !           196:                        u1 = *io=='<' ? 0 : 1;
        !           197: 
        !           198:                if (undo) {
        !           199:                        /*
        !           200:                         * Create and link in the undo node now. Stash away a
        !           201:                         * spare copy of the original fd as well. Note that
        !           202:                         * this may cause semantic changes in attempts to
        !           203:                         * redirect from fds that would otherwise be closed,
        !           204:                         * but that error was never diagnosed before anyway...
        !           205:                         */
        !           206: 
        !           207:                        ALLOC_ALLOC (undo);
        !           208:                        undo_node = (REDIR_UNDO *) salloc (sizeof (REDIR_UNDO));
        !           209:                        undo_node->ru_next = * undo;
        !           210:                        undo_node->ru_oldfd = u1;
        !           211:                        if ((undo_node->ru_newfd = dup (u1)) == -1) {
        !           212:                                if (errno != EBADF)
        !           213:                                        eredirundo ();
        !           214:                        } else {
        !           215:                                fcntl (undo_node->ru_newfd, F_SETFD,
        !           216:                                       fcntl (undo_node->ru_newfd, F_GETFD,
        !           217:                                              0) | FD_CLOEXEC);
        !           218:                        }
        !           219:                        * undo = undo_node;
        !           220:                } else
        !           221:                        undo_node = NULL;
        !           222:                for (op=0; ; io+=1)
        !           223:                        if (*io=='>')
        !           224:                                op += 1;
        !           225:                        else if (*io=='<')
        !           226:                                op -= 1;
        !           227:                        else
        !           228:                                break;
        !           229:                if (*io++ == '&') {
        !           230:                        if (op != 1 && op != -1) {
        !           231:                                panic(7);
        !           232:                                NOTREACHED;
        !           233:                        }
        !           234:                        u2 = *io++;
        !           235:                        if (u2 == '-') {
        !           236:                                close(u1);
        !           237:                                continue;
        !           238:                        } else if (!class(u2, MDIGI)) {
        !           239:                                eredir();
        !           240:                                return (-1);
        !           241:                        } else {
        !           242:                                u2 -= '0';
        !           243:                                dup2(u2, u1);
        !           244:                                continue;
        !           245:                        }
        !           246:                }
        !           247:                for (io-=1; *io==' '||*io=='\t'; io+=1);
        !           248:                switch (op) {
        !           249:                case -2:        /* Unquoted here */
        !           250:                                /* Fall through */
        !           251:                case -1:        /* Input file, quoted here */
        !           252:                        if ((u2 = open(io, 0)) < 0) {
        !           253:                                ecantopen(io);
        !           254:                                return (-1);
        !           255:                        }
        !           256:                        if (op == -2 && (u2 = evalhere(u2)) < 0)
        !           257:                                return (-1);
        !           258:                        dup2(u2, u1);
        !           259:                        close(u2);
        !           260:                        continue;
        !           261:                case 2:         /* Append to output */
        !           262:                        if ((u2 = open(io, 1)) >= 0) {
        !           263:                                lseek(u2, 0L, 2);
        !           264:                                dup2(u2, u1);
        !           265:                                close(u2);
        !           266:                                continue;
        !           267:                        } /* else fall through */
        !           268:                case 1:         /* Output file */
        !           269:                        if ((u2 = creat(io, 0666)) < 0) {
        !           270:                                ecantmake(io);
        !           271:                                return (-1);
        !           272:                        }
        !           273:                        dup2(u2, u1);
        !           274:                        close(u2);
        !           275:                        continue;
        !           276:                default:
        !           277:                        panic(8);
        !           278:                        NOTREACHED;
        !           279:                }
        !           280:        }
        !           281:        return (0);
        !           282: }
        !           283: 
        !           284: /*
        !           285:  * Undo a redirection sequence, reclaiming all the space for the undo nodes.
        !           286:  */
        !           287: redirundo (undo)
        !           288: REDIR_UNDO ** undo;
        !           289: {
        !           290:        REDIR_UNDO    * undo_node;
        !           291: 
        !           292:        while ((undo_node = * undo) != NULL) {
        !           293:                * undo = undo_node->ru_next;
        !           294:                if (undo_node->ru_newfd == -1)
        !           295:                        close (undo_node->ru_oldfd);
        !           296:                else {
        !           297:                        dup2 (undo_node->ru_newfd, undo_node->ru_oldfd);
        !           298:                        close (undo_node->ru_newfd);
        !           299:                }
        !           300:                ALLOC_FREE (undo);
        !           301:                sfree (undo_node);
        !           302:        }
        !           303:        return 0;
        !           304: }
        !           305: 
        !           306: 
        !           307: #ifdef NAMEPIPE
        !           308: /*
        !           309:  * Create a named pipe.
        !           310:  */
        !           311: npipe(np)
        !           312: register NODE *np;
        !           313: {
        !           314:        register char *tmp;
        !           315:        register int f;
        !           316:        char *tvec[2];
        !           317: 
        !           318:        tmp = shtmp();
        !           319:        mknod(tmp, S_IFPIP, 0);
        !           320:        if ((f = clone()) == 0) {
        !           321:                if (np->n_type==NRPIPE)
        !           322:                        strt[0] = '<';
        !           323:                else
        !           324:                        strt[0] = '>';
        !           325:                strt[1] = '\0';
        !           326:                tvec[0] = strcat(strt, tmp);
        !           327:                tvec[1] = NULL;
        !           328:                redirect(tvec, NULL);
        !           329:                command(np->n_auxp);
        !           330:                exit(slret);
        !           331:                NOTREACHED;
        !           332:        }
        !           333:        remember_temp (tmp);
        !           334:        strcpy(strt, tmp);
        !           335:        return;
        !           336: }
        !           337: #endif
        !           338: 
        !           339: /*
        !           340:  * Search a path, perhaps repeatedly, for a file with access mode.
        !           341:  * Is called with paths == NULL to reset pointers.
        !           342:  * UGLY, but it works.
        !           343:  */
        !           344: ffind(paths, file, mode)
        !           345: char *paths, *file;
        !           346: {
        !           347:        register char c, *cp1, *cp2;
        !           348:        static char *fp, *ff, *fcp;
        !           349: 
        !           350:        if (paths==NULL) {
        !           351:                fp = ff = fcp = NULL;
        !           352:                return (0);
        !           353:        }
        !           354:        if (ff!=file) {
        !           355:                fp = fcp = paths;
        !           356:                ff = file;
        !           357:                if (index(ff, '/')!=NULL)
        !           358:                        fcp = "";
        !           359:        }
        !           360:        for (c=':'; c==':'; ) {
        !           361:                cp1 = fcp;
        !           362:                cp2 = strt;
        !           363:                while (*cp1 && *cp1!=':')
        !           364:                        *cp2++ = *cp1++;
        !           365:                if (cp2 != strt)
        !           366:                        *cp2++ = '/';
        !           367:                c = *cp1++;
        !           368:                fcp = cp1;
        !           369:                cp1 = ff;
        !           370:                while (*cp2++ = *cp1++);
        !           371:                if (access(strt, mode)>=0)
        !           372:                        return (1);
        !           373:        }
        !           374:        return (0);
        !           375: }
        !           376: 
        !           377: /*
        !           378:  * execute a non standard shell.
        !           379:  */
        !           380: exshell(vp) VAR *vp;
        !           381: {
        !           382:        char *vshell;
        !           383:        register char *p;
        !           384: 
        !           385:        vshell = vp->v_strp;
        !           386:        while (*vshell && *vshell++ != '=');
        !           387:        /* Construct -name argv[0] */
        !           388:        if ((p = rindex(vshell, '/')) != NULL)
        !           389:                p += 1;
        !           390:        else
        !           391:                p = vshell;
        !           392:        strcpy(strt, "-");
        !           393:        strcat(strt, p);
        !           394:        /* Construct argv */
        !           395:        nargv = makargl();
        !           396:        nargv = addargl(nargv, "sh");
        !           397:        nargv = addargl(nargv, duplstr(strt, 0));
        !           398:        nargc = 2;
        !           399:        /* Construct envp */
        !           400:        nenvp = makargl();
        !           401:        nenvp = envlvar(nenvp);
        !           402:        /* Try exec */
        !           403:        execve(vshell, nargv+1, nenvp);
        !           404: 
        !           405:        if (errno==ENOEXEC) {
        !           406:                fakearg(1, nargc, nargv, nenvp);
        !           407:                sargc = 0;
        !           408:                sargp = nargv+2;
        !           409:                sarg0 = nargv[1];
        !           410:                nllflag = 0;
        !           411:                return session(SFILE, vshell);
        !           412:        }
        !           413:        fprintf(stderr, "No shell: %s\n", vshell);
        !           414:        exit(1);
        !           415: }
        !           416: 
        !           417: /*
        !           418:  * Check to see if we have mail.
        !           419:  */
        !           420: checkmail()
        !           421: {
        !           422:        static long mailsize = -1;
        !           423:        struct stat sbuf;
        !           424: 
        !           425:        if (*vmail == '\0')
        !           426:                return;
        !           427:        if (stat(vmail, &sbuf)<0) {
        !           428:                mailsize = 0;
        !           429:        } else {
        !           430:                if (sbuf.st_size != 0
        !           431:                 && sbuf.st_size > mailsize) {
        !           432:                        if (mailsize == -1)
        !           433:                                prints("You have mail.\n");
        !           434:                        else
        !           435:                                prints("You have new mail.\n");
        !           436:                }
        !           437:                mailsize = sbuf.st_size;
        !           438:        }
        !           439: }
        !           440: 
        !           441: /* end of sh/exec2.c */

unix.superglobalmegacorp.com

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