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

unix.superglobalmegacorp.com

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