Annotation of coherent/b/bin/sh_B4_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 <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.