Annotation of coherent/b/bin/sh.420/main.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * sh/main.c
        !             3:  * The Bourne shell.
        !             4:  * Main program, initialization and miscellaneous routines.
        !             5:  */
        !             6: 
        !             7: #include <assert.h>
        !             8: #include <stdarg.h>
        !             9: #include "sh.h"
        !            10: #include <fcntl.h>
        !            11: 
        !            12: void           fakearg         ();
        !            13: void           reset           ();
        !            14: void           ecantopen       ();
        !            15: void           panic           ();
        !            16: void           printe          ();
        !            17: void           syntax          ();
        !            18: 
        !            19: 
        !            20: int
        !            21: main(argc, argv, envp)
        !            22: char *argv[];
        !            23: char *envp[];
        !            24: {
        !            25: 
        !            26:        sarg0 = argc > 0 ? argv [0] : "";
        !            27:        fakearg (0, argc, argv, envp);
        !            28: 
        !            29:        if (argc > 0 && argv [0][0] == '-') {
        !            30:                lgnflag = 1;
        !            31:                umask (ufmask = 022);
        !            32:        } else if (argc > 0 && argv [0][0] == '+') {
        !            33:                lgnflag = 2;
        !            34:                umask (ufmask = 022);
        !            35:        } else
        !            36:                umask (ufmask = umask (ufmask));
        !            37: 
        !            38:        /*
        !            39:         * NIGEL: we must *force* stdin to be unbuffered to defeat some
        !            40:         * excessive cleverness in the stdio library. Note that line-buffering
        !            41:         * is a mode that only applies to output.
        !            42:         */
        !            43: 
        !            44:        if (setvbuf (stdin, NULL, _IONBF, BUFSIZ) != 0)
        !            45:                printe ("Cannot set stdin buffering\n");
        !            46: 
        !            47:        if (setjmp (restart) != 0) {
        !            48:                /* reentry for shell command file execution */
        !            49:                fakearg (1, nargc, nargv, nenvp);
        !            50:                argc = nargc;
        !            51:                argv = nargv;
        !            52:                envp = nenvp;
        !            53:                cmdflag ++;
        !            54:                nllflag = 0;
        !            55:        }
        !            56: 
        !            57:        shpid = getpid ();
        !            58:        initvar (envp);
        !            59: 
        !            60:        if (set (argc, argv, 1))
        !            61:                return 1;
        !            62: 
        !            63:        if (cflag) {
        !            64:                if (sargp [0] == NULL) {
        !            65:                        printe ("No string for -c?");
        !            66:                        return 1;
        !            67:                }
        !            68:                -- sargc;
        !            69:                session (SARGS, * sargp ++);
        !            70:        } else if (! sflag && ! iflag && sargc != 0) {
        !            71:                sarg0 = * sargp ++;
        !            72:                --sargc;
        !            73:                if (scmdp == NULL)
        !            74:                        scmdp = sarg0;
        !            75:                session (SFILE, scmdp);
        !            76:        } else
        !            77:                session (SSTR, stdin);
        !            78: 
        !            79:        cleanup_shell_fns ();
        !            80:        unlink_temp (capture_temp ());
        !            81:        return slret;
        !            82: }
        !            83: 
        !            84: 
        !            85: /*
        !            86:  * Make the arg listing of ps come out right.
        !            87:  *     f == 0, first entry, determine buffer limits.
        !            88:  *     f != 0, later entry, fill buffer with lies.
        !            89:  */
        !            90: 
        !            91: void
        !            92: fakearg(f, argc, argv, envp)
        !            93: int f, argc;
        !            94: char **argv, **envp;
        !            95: {
        !            96:        static char *fbuf;
        !            97:        static int nbuf;
        !            98:        register int n;
        !            99: 
        !           100:        if (f == 0) {
        !           101:                fbuf = argv [0];
        !           102:                nbuf = 0;
        !           103:                if (envp != NULL && envp [0] != NULL) {
        !           104:                        while (envp [1] != NULL)
        !           105:                                envp += 1;
        !           106:                        nbuf = envp [0] - fbuf + strlen (envp [0]) - 1;
        !           107:                } else if (argc > 0)
        !           108:                        nbuf = argv [argc - 1] - fbuf +
        !           109:                                strlen (argv [argc - 1]) - 1;
        !           110:        } else {
        !           111:                if (fbuf == NULL || nbuf == 0)
        !           112:                        return;
        !           113:                n = 0;
        !           114:                fbuf [0] = 0;
        !           115:                while (-- argc > 0) {
        !           116:                        argv += 1;
        !           117:                        n += strlen (argv [0]) + 1;
        !           118:                        if (n >= nbuf)
        !           119:                                break;
        !           120:                        strcat (fbuf, argv [0]);
        !           121:                        strcat (fbuf, " ");
        !           122:                }
        !           123:                strcat (fbuf, "\1");    /* non-ascii terminator */
        !           124:        }
        !           125: }
        !           126: 
        !           127: 
        !           128: /*
        !           129:  * Push a session of the indicated type. A non-zero return value is the
        !           130:  * appropriate return value for the session, but offset by one.
        !           131:  */
        !           132: 
        !           133: int
        !           134: push_session (type, info, session)
        !           135: int            type;
        !           136: __VOID__      *        info;
        !           137: SES          * session;
        !           138: {
        !           139:        session->s_next = sesp;
        !           140:        sesp = session;
        !           141:        session->s_bpp = savebuf ();
        !           142: 
        !           143:        switch (session->s_type = type) {
        !           144:        case SARGS:
        !           145:                session->s_strp = (char *) info;
        !           146:                session->s_flag = 0;
        !           147:                break;
        !           148: 
        !           149:        case SARGV:
        !           150:                session->s_argv = (char **) info;
        !           151:                if ((session->s_strp = session->s_argv [0]) == NULL)
        !           152:                        return 1;
        !           153:                session->s_flag = 0;
        !           154:                break;
        !           155: 
        !           156:        case SFILE:
        !           157:                session->s_strp = (char *) info;
        !           158: 
        !           159:                /*
        !           160:                 * NIGEL: We should take steps to ensure that the file
        !           161:                 * descriptors created for these input files lie above the
        !           162:                 * range that can be redirected in scripts!
        !           163:                 */
        !           164: 
        !           165:                if ((type = open (session->s_strp, O_RDONLY)) < 0) {
        !           166:                        ecantopen (session->s_strp);
        !           167:                        return 2;
        !           168:                }
        !           169:                if (type > 9) {
        !           170:                        int             scan;
        !           171:                        for (scan = 10 ; scan < FOPEN_MAX ; scan ++) {
        !           172:                                if (fcntl (scan, F_GETFD) == -1) {
        !           173:                                        /*
        !           174:                                         * Move the new FD to the new place.
        !           175:                                         */
        !           176: 
        !           177:                                        dup2 (type, scan);
        !           178:                                        close (type);
        !           179:                                        type = scan;
        !           180: 
        !           181:                                        break;
        !           182:                                }
        !           183:                        }
        !           184:                }
        !           185:                if ((session->s_ifp = fdopen (type, "r")) == NULL) {
        !           186:                        ecantopen (session->s_strp);
        !           187:                        return 2;
        !           188:                }
        !           189:                session->s_flag = isatty (fileno (session->s_ifp)) &&
        !           190:                                          isatty (2);
        !           191:                break;
        !           192: 
        !           193:        case SSTR:
        !           194:                session->s_strp = NULL;
        !           195:                session->s_ifp = (FILE *) info;
        !           196:                session->s_flag = isatty (fileno (session->s_ifp)) &&
        !           197:                                          isatty (2);
        !           198:                break;
        !           199:        }
        !           200: 
        !           201:        return 0;
        !           202: }
        !           203: 
        !           204: 
        !           205: /*
        !           206:  * Pop the passed-in session, which must be the current session.
        !           207:  */
        !           208: 
        !           209: void
        !           210: pop_session (session)
        !           211: SES          * session;
        !           212: {
        !           213:        assert (sesp == session);
        !           214: 
        !           215:        freebuf (session->s_bpp);
        !           216: 
        !           217:        if (session->s_type == SFILE)
        !           218:                fclose (session->s_ifp);
        !           219: 
        !           220:        if (session->s_next == NULL) {
        !           221:                sigintr (0);
        !           222:                recover (IRDY);
        !           223:        }
        !           224: 
        !           225:        sesp = session->s_next;
        !           226: }
        !           227: 
        !           228: 
        !           229: /*
        !           230:  * Loop on input.
        !           231:  */
        !           232: 
        !           233: int
        !           234: session(t, p)
        !           235: register char *p;
        !           236: {
        !           237:        SES s;
        !           238:        register int rcode;
        !           239: 
        !           240:        if ((rcode = push_session (t, p, & s)) > 0)
        !           241:                return rcode - 1;
        !           242: 
        !           243:        if (s.s_next == NULL) {         /* Initial entry */
        !           244:                if (iflag)
        !           245:                        s.s_flag = iflag;
        !           246:                else
        !           247:                        iflag = s.s_flag;
        !           248:                dflttrp (IRDY);
        !           249:        }
        !           250: 
        !           251:        /* Loop on input */
        !           252:        for (;;) {
        !           253:                unlink_temp (capture_temp ());
        !           254: 
        !           255:                rcode = setjmp (s.s_envl);
        !           256:                switch (rcode) {
        !           257:                case RSET:      /* initial setjmp call */
        !           258:                        switch (lgnflag) {
        !           259:                        case 1:         /* - sign invocation */
        !           260:                                lgnflag = 0;
        !           261:                                if (ffind ("/etc", "profile", 4))
        !           262:                                        session (SFILE, duplstr (strt, 0));
        !           263:                                recover (IPROF);
        !           264:                                if (* vhome && ffind (vhome, ".profile", 4))
        !           265:                                        session (SFILE, duplstr (strt, 0));
        !           266:                                break;
        !           267: 
        !           268:                        case 2:         /* + sign invocation */
        !           269:                                lgnflag = 0;
        !           270:                                if (ffind ("/etc", "profile", 4))
        !           271:                                        session (SFILE, duplstr (strt, 0));
        !           272:                                recover (IPROF);
        !           273:                                return exshell (findvar ("SHELL"));
        !           274:                        }
        !           275:                        checkmail ();
        !           276:                        comflag = 1;
        !           277:                        errflag = 0;
        !           278:                        recover (IRDY);
        !           279:                        freebuf (s.s_bpp);
        !           280:                        s.s_bpp = savebuf ();
        !           281:                        if (yyparse () != 0)
        !           282:                                syntax ();
        !           283: 
        !           284:                case REOF:
        !           285:                        recover (IRDY);
        !           286:                        break;
        !           287: 
        !           288:                case RCMD:
        !           289:                        recover (IRDY);
        !           290:                        s.s_con = NULL;
        !           291:                        command (s.s_node);
        !           292:                        if (tflag && tflag ++ >= 2)
        !           293:                                break;
        !           294:                        continue;
        !           295: 
        !           296:                case RERR:
        !           297:                        recover (IRDY);
        !           298:                        if (! errflag)
        !           299:                                syntax ();
        !           300:                        if (! iflag || (tflag && tflag ++ >= 2))
        !           301:                                break;
        !           302:                        continue;
        !           303: 
        !           304:                case RINT:
        !           305:                        if (s.s_next != NULL) {
        !           306:                                sesp = s.s_next;
        !           307:                                reset (RINT);
        !           308:                                NOTREACHED;
        !           309:                        }
        !           310:                        prpflag = 2;
        !           311:                        if (! iflag || (tflag && tflag ++ >= 2))
        !           312:                                break;
        !           313:                        continue;
        !           314: 
        !           315:                case RUEXITS:
        !           316:                case RUABORT:
        !           317:                        if (s.s_next != NULL) {
        !           318:                                sesp = s.s_next;
        !           319:                                reset (rcode);
        !           320:                                NOTREACHED;
        !           321:                        }
        !           322:                        if (rcode == RUEXITS || ! iflag ||
        !           323:                            (tflag && tflag ++ >= 2))
        !           324:                                break;
        !           325:                        continue;
        !           326: 
        !           327:                case RNOSBRK:
        !           328:                case RSYSER:
        !           329:                case RBRKCON:
        !           330:                case RNOWAY:
        !           331:                default:
        !           332:                        if (s.s_next != NULL)
        !           333:                                break;
        !           334:                        if (! iflag || (tflag && tflag ++ >= 2))
        !           335:                                break;
        !           336:                        continue;
        !           337:                }
        !           338:                break;
        !           339:        }
        !           340: 
        !           341:        pop_session (& s);
        !           342:        return (slret);
        !           343: }
        !           344: 
        !           345: 
        !           346: void
        !           347: reset (f)
        !           348: {
        !           349:        longjmp (sesp->s_envl, f);
        !           350:        NOTREACHED;
        !           351: }
        !           352: 
        !           353: 
        !           354: /*
        !           355:  * Global head of list of temporary files.
        !           356:  */
        !           357: 
        !           358: static TEMP_FILE      *        temp_list;
        !           359: 
        !           360: ALLOC_COUNT (temp)
        !           361: 
        !           362: /*
        !           363:  * Remember the name of a temporary file.
        !           364:  */
        !           365: 
        !           366: void
        !           367: remember_temp (filename)
        !           368: char * filename;
        !           369: {
        !           370:        TEMP_FILE     * temp = (TEMP_FILE *) salloc (sizeof (* temp));
        !           371: 
        !           372:        temp->tf_name = duplstr (filename, 1);
        !           373:        temp->tf_next = temp_list;
        !           374:        temp_list = temp;
        !           375: 
        !           376:        ALLOC_ALLOC (temp)
        !           377: }
        !           378: 
        !           379: 
        !           380: /*
        !           381:  * Return a pointer to the current global list of temporary files and clear
        !           382:  * the global pointer to that list.
        !           383:  */
        !           384: 
        !           385: TEMP_FILE *
        !           386: capture_temp ()
        !           387: {
        !           388:        TEMP_FILE     * temp = temp_list;
        !           389: 
        !           390:        temp_list = NULL;
        !           391:        return temp;
        !           392: }
        !           393: 
        !           394: 
        !           395: /*
        !           396:  * Deallocate a list of temporary files.
        !           397:  */
        !           398: 
        !           399: void
        !           400: forget_temp (templist)
        !           401: TEMP_FILE     *        templist;
        !           402: {
        !           403:        TEMP_FILE     * temp;
        !           404: 
        !           405:        while ((temp = templist) != NULL) {
        !           406: 
        !           407:                templist = temp->tf_next;
        !           408: 
        !           409:                ALLOC_FREE (temp);
        !           410:                sfree (temp->tf_name);
        !           411:                sfree (temp);
        !           412:        }
        !           413: }
        !           414: 
        !           415: 
        !           416: /*
        !           417:  * Walk over a list of temporary files, unlinking the files and deallocating
        !           418:  * the list nodes.
        !           419:  */
        !           420: 
        !           421: void
        !           422: unlink_temp (templist)
        !           423: TEMP_FILE     *        templist;
        !           424: {
        !           425:        TEMP_FILE     * temp;
        !           426: 
        !           427:        while ((temp = templist) != NULL) {
        !           428: 
        !           429:                templist = temp->tf_next;
        !           430:                unlink (temp->tf_name);
        !           431: 
        !           432:                ALLOC_FREE (temp)
        !           433:                sfree (temp->tf_name);
        !           434:                sfree (temp);
        !           435:        }
        !           436: }
        !           437: 
        !           438: 
        !           439: /*
        !           440:  * Make a temp file name.
        !           441:  */
        !           442: 
        !           443: char *
        !           444: shtmp ()
        !           445: {
        !           446:        static char tmpfile [] = "/tmp/shXXXXXXX";
        !           447:        static int tmpflag = 0;
        !           448: 
        !           449:        tmpflag ++;
        !           450:        sprintf (tmpfile + 6, "%05d%c%c", shpid, tmpflag % 26 + 'a',
        !           451:                 (tmpflag / 26) % 26 + 'a');
        !           452:        return tmpfile;
        !           453: }
        !           454: 
        !           455: 
        !           456: /*
        !           457:  * Print formatted.
        !           458:  */
        !           459: 
        !           460: void
        !           461: prints (format /* , ... */)
        !           462: char * format;
        !           463: {
        !           464:        va_list         args;
        !           465: 
        !           466:        va_start (args, format);
        !           467:        vfprintf (stderr, format, args);
        !           468:        va_end (args);
        !           469: }
        !           470: 
        !           471: 
        !           472: /*
        !           473:  * Make a core dump in /tmp and longjmp back to session -
        !           474:  *     there's a possibility we'll die horribly.
        !           475:  */
        !           476: 
        !           477: void
        !           478: panic (i)
        !           479: int i;
        !           480: {
        !           481: #ifdef PARANOID
        !           482:        register int f;
        !           483: 
        !           484:        if ((f = fork ()) == 0) {
        !           485:                abort ();
        !           486:                NOTREACHED;
        !           487:        }
        !           488:        waitc (f);
        !           489: #endif
        !           490:        printe ("Internal shell assertion %d failed", i);
        !           491:        reset (RNOWAY);
        !           492:        NOTREACHED;
        !           493: }
        !           494: 
        !           495: 
        !           496: /*
        !           497:  * Print out an error message.
        !           498:  */
        !           499: 
        !           500: void
        !           501: printe (format /* , ... */)
        !           502: char * format;
        !           503: {
        !           504:        errflag += 1;
        !           505:        if (! noeflag) {
        !           506:                va_list         args;
        !           507: 
        !           508:                va_start (args, format);
        !           509:                vfprintf (stderr, format, args);
        !           510:                va_end (args);
        !           511:                fprintf (stderr, "\n");
        !           512:        }
        !           513: }
        !           514: 
        !           515: /*
        !           516:  * Some familiar errors.
        !           517:  */
        !           518: 
        !           519: void   ecantopen(s) char *s; { printe ("Cannot open %s", s); }
        !           520: void   ecantfind(s) char *s; { printe ("Cannot find %s", s); }
        !           521: void   e2big(s) char *s; { printe ("File to big to execute: %s", s); }
        !           522: void   ecantmake(s) char *s; { printe ("Cannot create %s", s); }
        !           523: void   emisschar(c) { printe ("Missing `%c'", c); }
        !           524: void   ecantfdop() { printe ("Fdopen failed"); }
        !           525: void   enotdef(s) char *s; { printe ("Cannot find variable %s", s); }
        !           526: void   eillvar(s) char *s; { printe ("Illegal variable name: %s", s); }
        !           527: void   eredir() { printe ("Illegal redirection"); }
        !           528: void   etoolong(s) char *s; {
        !           529:        printe ("Argument too long %s: %.*s", s, STRSIZE, strt);
        !           530: }
        !           531: void   eredirundo() {
        !           532:   printe ("Unable to preserve redirection state when redirecting builtin");
        !           533: }
        !           534: 
        !           535: 
        !           536: /*
        !           537:  * Don't print out an error message.
        !           538:  */
        !           539: 
        !           540: void
        !           541: yyerror()
        !           542: {
        !           543: }
        !           544: 
        !           545: 
        !           546: /*
        !           547:  * print out the prompt given the prompt to write
        !           548:  */
        !           549: 
        !           550: void
        !           551: prompt(vps)
        !           552: char *vps;
        !           553: {
        !           554:        prints ("%s", vps);
        !           555: #if RSX
        !           556:        fflush (stdout);
        !           557: #endif
        !           558: }
        !           559: 
        !           560: 
        !           561: /*
        !           562:  * Syntax error message - print line number and file if
        !           563:  *     not interactive.
        !           564:  */
        !           565: 
        !           566: void
        !           567: syntax()
        !           568: {
        !           569:        if (sesp->s_type == SFILE) {
        !           570:                if (feof (sesp->s_ifp))
        !           571:                        printe ("%s: Syntax error at EOF", sesp->s_strp);
        !           572:                else
        !           573:                        printe ("%s: Syntax error in line %d", sesp->s_strp,
        !           574:                                yyline);
        !           575:        } else
        !           576:                printe ("Syntax error");
        !           577: }

unix.superglobalmegacorp.com

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