Annotation of coherent/b/bin/sh.420/exec2.c, revision 1.1.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.