Annotation of 43BSD/contrib/jove/jove.c, revision 1.1.1.1

1.1       root        1: /*************************************************************************
                      2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
                      3:  * provided to you without charge for use only on a licensed Unix        *
                      4:  * system.  You may copy JOVE provided that this notice is included with *
                      5:  * the copy.  You may not sell copies of this program or versions        *
                      6:  * modified for use on microcomputer systems, unless the copies are      *
                      7:  * included with a Unix system distribution and the source is provided.  *
                      8:  *************************************************************************/
                      9: 
                     10: /* Contains the main loop initializations, and some system dependent
                     11:    type things, e.g. putting terminal in CBREAK mode, etc. */
                     12: 
                     13: #include "jove.h"
                     14: #include "io.h"
                     15: #include "termcap.h"
                     16: 
                     17: #include <varargs.h>
                     18: #include <sys/stat.h>
                     19: #include <signal.h>
                     20: #include <errno.h>
                     21: #ifndef SYSV
                     22: #include <sgtty.h>
                     23: #include <fcntl.h>
                     24: #else
                     25: #include <termio.h>
                     26: #endif SYSV
                     27: 
                     28: #ifdef TIOCSLTC
                     29: struct ltchars ls1,
                     30:                ls2;
                     31: #endif TIOCSLTC
                     32: 
                     33: #ifdef TIOCGETC
                     34: struct tchars  tc1,
                     35:                tc2;
                     36: #endif
                     37: 
                     38: #ifdef BRLUNIX
                     39: struct sg_brl  sg1, sg2;
                     40: #else
                     41: #ifdef SYSV
                     42: struct termio  sg1, sg2;
                     43: #else SYSV
                     44: struct sgttyb  sg1, sg2;
                     45: #endif SYSV
                     46: #endif BRLUNIX
                     47: 
                     48: #ifdef BIFF
                     49: private struct stat    tt_stat;        /* for biff */
                     50: #ifndef BSD4_2
                     51: private char   *tt_name = 0;           /* name of the control tty */
                     52: extern char    *ttyname();             /* for systems w/o fchmod ... */
                     53: #endif
                     54: private int    dw_biff = NO;           /* whether or not to fotz at all */
                     55: #endif
                     56: 
                     57: time_t time0;                  /* when jove started up */
                     58: int    errormsg;
                     59: extern char    *tfname;
                     60: char   NullStr[] = "";
                     61: 
                     62: finish(code)
                     63: {
                     64:        int     CoreDump = (code != 0 && code != SIGHUP),
                     65:                DelTmps = 1;            /* Usually we delete them. */
                     66: 
                     67: #ifdef LSRHS
                     68:        if (CoreDump)
                     69:                setdump(1);
                     70: #endif
                     71:        if (code == SIGINT) {
                     72:                char    c;
                     73: 
                     74: #ifndef MENLO_JCL
                     75:                (void) signal(code, finish);
                     76: #endif
                     77:                f_mess("Abort (Type 'n' if you're not sure)? ");
                     78:                (void) read(0, &c, 1);
                     79:                message(NullStr);
                     80:                if ((c & 0377) != 'y') {
                     81:                        redisplay();
                     82:                        return;
                     83:                }
                     84:        }
                     85:        ttyset(OFF);
                     86:        UnsetTerm(NullStr);
                     87:        if (code != 0) {
                     88:                if (!Crashing) {
                     89:                        Crashing++;
                     90:                        lsave();
                     91:                        SyncRec();
                     92:                        printf("JOVE CRASH!! (code %d)\n", code);
                     93:                        if (ModBufs(1)) {
                     94:                                printf("Your buffers have been saved.\n");
                     95:                                printf("Use \"jove_recover\" or \"jove -r\"\n");
                     96:                                printf("to have a look at them.\n");
                     97:                                DelTmps = 0;    /* Don't delete anymore. */
                     98:                        } else
                     99:                                printf("You didn't lose any work.\n");
                    100:                } else
                    101:                        printf("\r\nYou may have lost your work!\n");
                    102:        }
                    103:        flusho();
                    104:        if (DelTmps) {
                    105:                tmpclose();
                    106:                recclose();
                    107:        }
                    108:        if (CoreDump)
                    109:                abort();
                    110: #ifdef PROFILING
                    111:        exit(exp_p);
                    112: #else
                    113:        _exit(exp_p);
                    114: #endif
                    115: }
                    116: 
                    117: private char   smbuf[20],
                    118:                *bp = smbuf;
                    119: private int    nchars = 0;
                    120: 
                    121: private char   peekbuf[10],
                    122:                *peekp = peekbuf;
                    123: 
                    124: #ifdef SYSV
                    125: void
                    126: setblock(fd, on)       /* turn blocking on or off */
                    127: register int   fd, on;
                    128: {
                    129:     static int blockf, nonblockf;
                    130:     static int first = 1;
                    131:     int flags;
                    132: 
                    133:     if (first) {
                    134:        first = 0;
                    135:        if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
                    136:            finish(SIGHUP);
                    137:        blockf = flags & ~O_NDELAY;     /* make sure O_NDELAY is off */
                    138:        nonblockf = flags | O_NDELAY;   /* make sure O_NDELAY is on */
                    139:     }
                    140:     if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
                    141:        finish(SIGHUP);
                    142:     return;
                    143: }
                    144: #endif SYSV
                    145: 
                    146: Peekc()
                    147: {
                    148:        int     c;
                    149: 
                    150:        if (peekp == peekbuf)
                    151:                c = -1;
                    152:        else
                    153:                c = *--peekp & 0377;
                    154:        return c;
                    155: }
                    156: 
                    157: Ungetc(c)
                    158: {
                    159:        if (peekp == &peekbuf[(sizeof peekbuf) - 1])
                    160:                return;         /* Sorry, can't oblige you ... */
                    161:        *peekp++ = c;
                    162: }
                    163: 
                    164: char   *Inputp = 0;
                    165: 
                    166: #ifdef IPROCS
                    167: #ifdef PIPEPROCS
                    168: getchar()
                    169: {
                    170:        extern int      errno;
                    171:        register int    c;
                    172: 
                    173:        if (nchars <= 0) {
                    174:                do
                    175:                        nchars = read(0, smbuf, sizeof smbuf);
                    176: #ifdef SYSV
                    177:                while (nchars == 0 || (nchars < 0 && errno == EINTR));
                    178:                if (nchars < 0)
                    179: #else
                    180:                while (nchars < 0 && errno == EINTR);
                    181:                if (nchars <= 0)
                    182: #endif SYSV
                    183:                        finish(SIGHUP);
                    184:                bp = smbuf;
                    185:                InputPending = nchars > 1;
                    186:        }
                    187:        if (((c = *bp) & 0200) && MetaKey != 0) {
                    188:                *bp = (c & 0177);
                    189:                return '\033';
                    190:        }
                    191:        nchars--;
                    192:        return (*bp++ & 0177);
                    193: }
                    194: #else PIPEPROCS
                    195: getchar()
                    196: {
                    197:        extern int      global_fd,
                    198:                        NumProcs,
                    199:                        errno;
                    200:        register int    tmp,
                    201:                        nfds;
                    202:        int     reads,
                    203:                c;
                    204: 
                    205:        if (nchars <= 0) {
                    206:                /* Get a character from the keyboard, first checking for
                    207:                   any input from a process.  Handle that first, and then
                    208:                   deal with the terminal input. */
                    209:                if (NumProcs > 0) {
                    210:                        do {
                    211:                                do {
                    212:                                        reads = global_fd;
                    213:                                        nfds = select(32, &reads, (int *) 0, (int *) 0, (struct timeval *) 0);
                    214:                                } while (nfds < 0 && errno == EINTR);
                    215: 
                    216:                                switch (nfds) {
                    217:                                case -1:
                    218:                                        printf("\rerror %d in select %d", errno, global_fd);
                    219:                                        global_fd = 1;
                    220:                                        break;
                    221:                                default:
                    222:                                        if (reads & 01) {
                    223:                                                nchars = read(0, smbuf, sizeof(smbuf));
                    224:                                                reads &= ~01;
                    225:                                                --nfds;
                    226:                                        }
                    227: 
                    228:                                        while (nfds--) {
                    229:                                                tmp = ffs(reads) - 1;
                    230:                                                read_proc(tmp);
                    231:                                                reads &= ~tmp;
                    232:                                        }
                    233: 
                    234:                                        break;
                    235:                                }
                    236:                        } while (nchars <= 0);
                    237:                } else {
                    238:                        do
                    239:                                nchars = read(0, smbuf, sizeof(smbuf));
                    240:                        while (nchars < 0 && errno == EINTR);
                    241:                }
                    242: 
                    243:                if (nchars <= 0)
                    244:                        finish(SIGHUP);
                    245: 
                    246:                bp = smbuf;
                    247:                InputPending = (nchars > 1);
                    248:        }
                    249: 
                    250:        if (((c = *bp) & 0200) && MetaKey != 0) {
                    251:                *bp = (c & 0177);
                    252:                return '\033';
                    253:        }
                    254:        nchars--;
                    255:        return *bp++ & 0377;
                    256: }
                    257: #endif PIPEPROCS
                    258: #else IPROCS
                    259: getchar()
                    260: {
                    261:        extern int      errno;
                    262:        register int    c;
                    263: 
                    264:        if (nchars <= 0) {
                    265:                do
                    266:                        nchars = read(0, smbuf, sizeof smbuf);
                    267:                while (nchars < 0 && errno == EINTR);
                    268: 
                    269:                if (nchars <= 0)
                    270:                        finish(SIGHUP);
                    271:                bp = smbuf;
                    272:                InputPending = nchars > 1;
                    273:        }
                    274:        if (((c = *bp) & 0200) && MetaKey != 0) {
                    275:                *bp = (c & 0177);
                    276:                return '\033';
                    277:        }
                    278:        nchars--;
                    279:        return *bp++ & 0377;
                    280: }
                    281: #endif IPROCS
                    282: 
                    283: int    InputPending = 0;
                    284: 
                    285: /* Returns non-zero if a character waiting */
                    286: 
                    287: charp()
                    288: {
                    289:        int     some = 0;
                    290: 
                    291:        if (InJoverc != 0 || nchars > 0 || Inputp != 0)
                    292:                return 1;
                    293: #ifdef BRLUNIX
                    294:        {
                    295:                static struct sg_brl gttyBuf;
                    296: 
                    297:                gtty(0, (char *) &gttyBuf);
                    298:                if (gttyBuf.sg_xflags & INWAIT)
                    299:                        some++;
                    300:        }
                    301: #endif
                    302: #ifdef FIONREAD
                    303:        {
                    304:                long c;
                    305: 
                    306:                if (ioctl(0, FIONREAD, (struct sgttyb *) &c) == -1)
                    307:                        c = 0;
                    308:                some = (c > 0);
                    309:        }
                    310: #endif FIONREAD
                    311: #ifdef SYSV
                    312:        setblock(0, 0);         /* turn blocking off */
                    313:        nchars = read(0, smbuf, sizeof smbuf);  /* Is anything there? */
                    314:        setblock(0, 1);         /* turn blocking on */
                    315:        if (nchars > 0)         /* something was there */
                    316:            bp = smbuf;         /* make sure bp points to it */
                    317:        some = (nchars > 0);    /* just say we found something */
                    318: #endif SYSV
                    319: #ifdef c70
                    320:        some = !empty(0);
                    321: #endif
                    322:        return some;
                    323: }
                    324: 
                    325: ResetTerm()
                    326: {
                    327:        putpad(TI, 1);
                    328:        putpad(VS, 1);
                    329:        putpad(KS, 1);
                    330: #ifdef BIFF
                    331:        if (BiffChk != dw_biff)
                    332:                biff_init();
                    333:        /* just in case we changed our minds about whether to deal with
                    334:           biff */
                    335: #endif
                    336:        chkmail(YES);   /* force it to check to we can be accurate */
                    337:        do_sgtty();     /* this is so if you change baudrate or stuff
                    338:                           like that, JOVE will notice. */
                    339:        ttyset(ON);
                    340: }
                    341: 
                    342: UnsetTerm(mesg)
                    343: char   *mesg;
                    344: {
                    345:        ttyset(OFF);
                    346:        putpad(KE, 1);
                    347:        putpad(VE, 1);
                    348:        putpad(TE, 1);
                    349: #ifdef ID_CHAR
                    350:        INSmode(0);
                    351: #endif
                    352:        Placur(ILI, 0);
                    353:        printf("%s", mesg);
                    354:        putpad(CE, 1);
                    355:        flusho();
                    356: }
                    357: 
                    358: #ifdef JOB_CONTROL
                    359: PauseJove()
                    360: {
                    361:        UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
                    362:        (void) kill(0, SIGTSTP);
                    363:        ResetTerm();
                    364:        ClAndRedraw();
                    365: }
                    366: #endif
                    367: 
                    368: Push()
                    369: {
                    370:        int     pid;
                    371: 
                    372:        switch (pid = fork()) {
                    373:        case -1:
                    374:                complain("[Fork failed]");
                    375: 
                    376:        case 0:
                    377:                UnsetTerm(NullStr);
                    378:                (void) signal(SIGTERM, SIG_DFL);
                    379:                (void) signal(SIGINT, SIG_DFL);
                    380:                execl(Shell, basename(Shell), 0);
                    381:                message("[Execl failed]");
                    382:                _exit(1);
                    383: 
                    384:        default:
                    385:            {
                    386:                int     (*old_int)() = signal(SIGINT, SIG_IGN);
                    387:                int     (*old_quit)() = signal(SIGQUIT, SIG_IGN);
                    388: 
                    389: #ifdef IPROCS
                    390:                sighold(SIGCHLD);
                    391: #endif
                    392:                dowait(pid, (int *) 0);
                    393: #ifdef IPROCS
                    394:                sigrelse(SIGCHLD);
                    395: #endif
                    396:                ResetTerm();
                    397:                ClAndRedraw();
                    398:                (void) signal(SIGINT, old_int);
                    399:                (void) signal(SIGQUIT, old_quit);
                    400:            }
                    401:        }
                    402: }
                    403: 
                    404: int    OKXonXoff = 0;          /* ^S and ^Q initially DON'T work */
                    405: 
                    406: ttsize()
                    407: {
                    408: #ifdef TIOCGWINSZ
                    409:        struct winsize win;
                    410: 
                    411:        if (ioctl (0, TIOCGWINSZ, &win) == 0) {
                    412:                if (win.ws_col)
                    413:                        CO = win.ws_col;
                    414:                if (win.ws_row)
                    415:                        LI = win.ws_row;
                    416:        }
                    417: #else TIOCGWINSZ
                    418: #ifdef BTL_BLIT
                    419: #include <sys/jioctl.h>
                    420:        struct jwinsize jwin;
                    421: 
                    422:        if (ioctl(0, JWINSIZE, &jwin) == 0) {
                    423:                if (jwin.bytesx)
                    424:                        CO = jwin.bytesx;
                    425:                if (jwin.bytesy)
                    426:                        LI = jwin.bytesy;
                    427:        }
                    428: #endif BTL_BLIT
                    429: #endif TIOCGWINSZ
                    430:        ILI = LI - 1;
                    431: }
                    432: 
                    433: #ifdef BIFF
                    434: biff_init()
                    435: {
                    436:        dw_biff = ((BiffChk) &&
                    437: #ifndef BSD4_2
                    438:                   ((tt_name != 0) || (tt_name = ttyname(0))) &&
                    439:                   (stat(tt_name, &tt_stat) != -1) &&
                    440: #else
                    441:                   (fstat(0, &tt_stat) != -1) &&
                    442: #endif
                    443:                   (tt_stat.st_mode & S_IEXEC));        /* he's using biff */
                    444: 
                    445: }
                    446: 
                    447: biff(on)
                    448: {
                    449:        if (dw_biff == NO)
                    450:                return;
                    451: #ifndef BSD4_2
                    452:        (void) chmod(tt_name, on ? tt_stat.st_mode :
                    453:                                   (tt_stat.st_mode & ~S_IEXEC));
                    454: #else
                    455:        (void) fchmod(0, on ? tt_stat.st_mode :
                    456:                              (tt_stat.st_mode & ~S_IEXEC));
                    457: #endif
                    458: }
                    459: 
                    460: #endif
                    461: 
                    462: ttinit()
                    463: {
                    464: #ifdef BIFF
                    465:        biff_init();
                    466: #endif
                    467: #ifdef TIOCSLTC
                    468:        (void) ioctl(0, TIOCGLTC, (struct sgttyb *) &ls1);
                    469:        ls2 = ls1;
                    470:        ls2.t_suspc = (char) -1;
                    471:        ls2.t_dsuspc = (char) -1;
                    472:        ls2.t_flushc = (char) -1;
                    473:        ls2.t_lnextc = (char) -1;
                    474: #endif
                    475: 
                    476: #ifdef TIOCGETC
                    477:        /* Change interupt and quit. */
                    478:        (void) ioctl(0, TIOCGETC, (struct sgttyb *) &tc1);
                    479:        tc2 = tc1;
                    480:        tc2.t_intrc = CTL(]);
                    481:        tc2.t_quitc = (char) -1;
                    482:        if (OKXonXoff) {
                    483:                tc2.t_stopc = (char) -1;
                    484:                tc2.t_startc = (char) -1;
                    485:        }
                    486: #endif TIOCGETC
                    487:        do_sgtty();
                    488: }
                    489: 
                    490: private int    done_ttinit = 0;
                    491: 
                    492: do_sgtty()
                    493: {
                    494: #ifdef SYSV
                    495:        (void) ioctl(0, TCGETA, (char *) &sg1);
                    496: #else
                    497:        (void) gtty(0, &sg1);
                    498: #endif SYSV
                    499:        sg2 = sg1;
                    500: 
                    501: #ifdef SYSV
                    502:        TABS = !((sg1.c_oflag & TAB3) == TAB3);
                    503:        ospeed = sg1.c_cflag & CBAUD;
                    504: 
                    505:        sg2.c_iflag &= ~(INLCR|ICRNL|IGNCR);
                    506:        sg2.c_lflag &= ~(ISIG|ICANON|ECHO);
                    507:        sg2.c_oflag &= ~(OCRNL|ONLCR);
                    508:        sg2.c_cc[VMIN] = sizeof smbuf;
                    509:        sg2.c_cc[VTIME] = 1;
                    510: #else
                    511:        TABS = !(sg1.sg_flags & XTABS);
                    512:        ospeed = sg1.sg_ospeed;
                    513: #ifdef BRLUNIX
                    514:        sg2.sg_flags &= ~(ECHO | CRMOD);
                    515:        sg2.sg_flags |= CBREAK;
                    516: 
                    517:        /* VT100 Kludge: leave STALL on for flow control if DC3DC1 (Yuck.) */
                    518:        sg2.sg_xflags &= ~((sg2.sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
                    519: #else
                    520:        sg2.sg_flags &= ~(ECHO | CRMOD);
                    521: #endif BRLUNIX
                    522: 
                    523: #ifdef EUNICE
                    524:        sg2.sg_flags |= RAW;    /* Eunice needs RAW mode last I heard. */
                    525: #else
                    526: #ifdef PURDUE_EE
                    527: #   ifdef pdp11
                    528:        sg2.sg_flags |= RAW;
                    529: #   else
                    530:        sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
                    531: #   endif
                    532: #else
                    533:        sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
                    534: #endif PURDUE_EE
                    535: #endif EUNICE
                    536: #endif SYSV
                    537: }
                    538: 
                    539: tty_reset()
                    540: {
                    541:        if (!done_ttinit)
                    542:                return;
                    543:        ttyset(OFF);    /* go back to original modes */
                    544:        ttinit();
                    545:        ttyset(ON);
                    546: }
                    547: 
                    548: /* If n is OFF reset to original modes */
                    549: 
                    550: ttyset(n)
                    551: {
                    552:        if (!done_ttinit && n == 0)     /* Try to reset before we've set! */
                    553:                return;
                    554: #ifdef SYSV
                    555:        (void) ioctl(0, TCSETAW, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
                    556: #else
                    557: #ifdef BRLUNIX
                    558:        (void) stty(0, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
                    559: #else
                    560:        (void) ioctl(0, TIOCSETN, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
                    561: #endif BRLUNIX
                    562: #endif SYSV
                    563: 
                    564: #ifdef TIOCSETC
                    565:        (void) ioctl(0, TIOCSETC, n == 0 ? (struct sgttyb *) &tc1 : (struct sgttyb *) &tc2);
                    566: #endif TIOCSETC
                    567: #ifdef TIOCSLTC
                    568:        (void) ioctl(0, TIOCSLTC, n == 0 ? (struct sgttyb *) &ls1 : (struct sgttyb *) &ls2);
                    569: #endif TIOCSLTC
                    570:        done_ttinit = 1;
                    571: #ifdef BIFF
                    572:        biff(!n);
                    573: #endif
                    574: }
                    575: 
                    576: int    this_cmd,
                    577:        last_cmd;
                    578: 
                    579: dispatch(c)
                    580: register int   c;
                    581: {
                    582:        data_obj        *cp;
                    583: 
                    584:        this_cmd = 0;
                    585:        cp = mainmap[c & 0177];
                    586: 
                    587:        if (cp == 0) {
                    588:                rbell();
                    589:                exp = 1;
                    590:                exp_p = errormsg = 0;
                    591:                message(NullStr);
                    592:                return;
                    593:        }
                    594:        ExecCmd(cp);
                    595: }
                    596: 
                    597: int    LastKeyStruck,
                    598:        MetaKey = 0;
                    599: 
                    600: getch()
                    601: {
                    602:        register int    c,
                    603:                        peekc;
                    604: #ifdef IPROCS
                    605:        extern int      NumProcs;
                    606: #endif
                    607:        extern int      ModCount,
                    608:                        Interactive;
                    609: 
                    610:        if (Inputp) {
                    611:                if ((c = *Inputp++) != 0)
                    612:                        return LastKeyStruck = c;
                    613:                Inputp = 0;
                    614:        }
                    615: 
                    616:        if (InJoverc)
                    617:                return EOF;     /* somethings wrong if Inputp runs out while
                    618:                                   we're reading a .joverc file. */
                    619: 
                    620:        if (ModCount >= SyncFreq) {
                    621:                ModCount = 0;
                    622:                SyncRec();
                    623:        }
                    624: 
                    625:        /* If we're not interactive and we're not executing a macro,
                    626:           AND there are no ungetc'd characters, we read from the
                    627:           terminal (i.e., getch()).  And characters only get put
                    628:           in macros from inside this if. */
                    629:        if (((peekc = c = Peekc()) == -1) && (Interactive || ((c = mac_getc()) == -1))) {
                    630:                /* So messages that aren't error messages don't
                    631:                   hang around forever. */
                    632:                if (!UpdMesg && !Asking) {      /* Don't erase if we are asking */
                    633:                        if (mesgbuf[0] && !errormsg)
                    634:                                message(NullStr);
                    635:                }
                    636:                redisplay();
                    637: #ifdef IPROCS
                    638: #  ifdef PIPEPROCS
                    639:                if (NumProcs > 0) {
                    640:                        sigrelse(INPUT_SIG);
                    641:                        sigrelse(SIGCHLD);
                    642:                }
                    643: #  endif
                    644: #endif
                    645:                inIOread = 1;
                    646:                if ((c = getchar()) == EOF)
                    647:                        finish(SIGHUP);
                    648:                inIOread = 0;
                    649: 
                    650: #ifdef IPROCS
                    651: #  ifdef PIPEPROCS
                    652:                if (NumProcs > 0) {
                    653:                        sighold(INPUT_SIG);
                    654:                        sighold(SIGCHLD);
                    655:                }
                    656: #  endif
                    657: #endif
                    658:                if (!Interactive && (KeyMacro.m_flags & DEFINE))
                    659:                        mac_putc(c);
                    660:        }
                    661:        if (peekc == -1)        /* Don't add_stroke peekc's */
                    662:                add_stroke(c);
                    663:        return LastKeyStruck = c;
                    664: }
                    665: 
                    666: dorecover()
                    667: {
                    668:        execl(RECOVER, "jove_recover", 0);
                    669:        printf("%s: execl failed!\n", RECOVER);
                    670:        flusho();
                    671:        _exit(-1);
                    672: }
                    673:                
                    674: 
                    675: ShowVersion()
                    676: {
                    677:        extern char     *version;
                    678: 
                    679:        s_mess("Jonathan's Own Version of Emacs (%s)", version);
                    680: }
                    681: 
                    682: UNIX_cmdline(argc, argv)
                    683: char   *argv[];
                    684: {
                    685:        int     lineno = 0,
                    686:                nwinds = 1;
                    687:        Buffer  *b;
                    688: 
                    689:        ShowVersion();
                    690:        while (argc > 1) {
                    691:                if (argv[1][0] != '-' && argv[1][0] != '+') {
                    692:                        int     force = (nwinds > 0 || lineno != 0);
                    693: 
                    694:                        minib_add(argv[1], force ? YES : NO);
                    695:                        b = do_find(nwinds > 0 ? curwind : (Window *) 0,
                    696:                                    argv[1], force);
                    697:                        if (force) {
                    698:                                SetABuf(curbuf);
                    699:                                SetBuf(b);
                    700:                                SetLine(next_line(curbuf->b_first, lineno));
                    701:                                if (nwinds > 1)
                    702:                                        NextWindow();
                    703:                                if (nwinds)
                    704:                                        nwinds--;
                    705:                        }
                    706:                        lineno = 0;
                    707:                } else  switch (argv[1][1]) {
                    708:                        case 'd':
                    709:                                ++argv;
                    710:                                --argc;
                    711:                                break;
                    712: 
                    713:                        case 'j':       /* Ignore .joverc in HOME */
                    714:                                break;
                    715: 
                    716:                        case 'p':
                    717:                                ++argv;
                    718:                                --argc;
                    719:                                SetBuf(do_find(curwind, argv[1], 0));
                    720:                                ParseAll();
                    721:                                nwinds = 0;
                    722:                                break;
                    723: 
                    724:                        case 't':
                    725:                                ++argv;
                    726:                                --argc;
                    727:                                exp_p = 1;
                    728:                                find_tag(argv[1], YES);
                    729:                                break;
                    730: 
                    731:                        case 'w':
                    732:                                if (argv[1][2] == '\0')
                    733:                                        nwinds++;
                    734:                                else
                    735:                                        nwinds += -1 + chr_to_int(&argv[1][2], 10, NIL);
                    736:                                (void) div_wind(curwind, nwinds - 1);
                    737:                                break;
                    738: 
                    739:                        case '0':
                    740:                        case '1':
                    741:                        case '2':
                    742:                        case '3':
                    743:                        case '4':
                    744:                        case '5':
                    745:                        case '6':
                    746:                        case '7':
                    747:                        case '8':
                    748:                        case '9':
                    749:                                lineno = chr_to_int(&argv[1][1], 10, 0) - 1;
                    750:                                break;
                    751:                }
                    752:                ++argv;
                    753:                --argc;
                    754:        }
                    755: }
                    756: 
                    757: #ifdef lint
                    758: Ignore(a)
                    759:        char *a;
                    760: {
                    761: 
                    762:        a = a;
                    763: }
                    764: 
                    765: Ignorf(a)
                    766:        int (*a)();
                    767: {
                    768: 
                    769:        a = a;
                    770: }
                    771: 
                    772: Ignorl(a)
                    773: long   a;
                    774: {
                    775:        a = a;
                    776: }
                    777: #endif
                    778: 
                    779: /* VARARGS1 */
                    780: 
                    781: error(fmt, va_alist)
                    782: char   *fmt;
                    783: va_dcl
                    784: {
                    785:        va_list ap;
                    786: 
                    787:        if (fmt) {
                    788:                va_start(ap);
                    789:                format(mesgbuf, sizeof mesgbuf, fmt, ap);
                    790:                va_end(ap);
                    791:                UpdMesg++;
                    792:        }
                    793:        rbell();
                    794:        (void) longjmp(mainjmp, ERROR);
                    795: }
                    796: 
                    797: /* VARARGS1 */
                    798: 
                    799: complain(fmt, va_alist)
                    800: char   *fmt;
                    801: va_dcl
                    802: {
                    803:        va_list ap;
                    804: 
                    805:        if (fmt) {
                    806:                va_start(ap);
                    807:                format(mesgbuf, sizeof mesgbuf, fmt, ap);
                    808:                va_end(ap);
                    809:                UpdMesg++;
                    810:        }
                    811:        rbell();
                    812:        (void) longjmp(mainjmp, COMPLAIN);
                    813: }
                    814: 
                    815: /* VARARGS1 */
                    816: 
                    817: confirm(fmt, va_alist)
                    818: char   *fmt;
                    819: va_dcl
                    820: {
                    821:        char    *yorn;
                    822:        va_list ap;
                    823: 
                    824:        va_start(ap);
                    825:        format(mesgbuf, sizeof mesgbuf, fmt, ap);
                    826:        va_end(ap);
                    827:        yorn = ask((char *) 0, mesgbuf);
                    828:        if (*yorn != 'Y' && *yorn != 'y')
                    829:                (void) longjmp(mainjmp, COMPLAIN);
                    830: }
                    831: 
                    832: int    RecDepth = 0;
                    833: 
                    834: Recur()
                    835: {
                    836:        char    bname[128];
                    837:        Mark    *m;
                    838: 
                    839:        sprintf(bname, "%s", curbuf->b_name);
                    840:        m = MakeMark(curline, curchar, FLOATER);
                    841: 
                    842:        RecDepth++;
                    843:        UpdModLine++;
                    844:        DoKeys(1);      /* 1 means not first time */
                    845:        UpdModLine++;
                    846:        RecDepth--;
                    847:        SetBuf(do_select(curwind, bname));
                    848:        if (!exp_p)
                    849:                ToMark(m);
                    850:        DelMark(m);
                    851: }
                    852: 
                    853: jmp_buf        mainjmp;
                    854: int    iniargc;        /* main sets these for DoKeys() */
                    855: char   **iniargv;
                    856: 
                    857: DoKeys(nocmdline)
                    858: {
                    859:        int     c;
                    860:        jmp_buf savejmp;
                    861: 
                    862:        push_env(savejmp);
                    863: 
                    864:        switch (setjmp(mainjmp)) {
                    865:        case 0:
                    866:                if (!nocmdline)
                    867:                        UNIX_cmdline(iniargc, iniargv);
                    868:                break;
                    869: 
                    870:        case QUIT:
                    871:                if (RecDepth == 0) {
                    872:                        if (ModMacs()) {
                    873:                                rbell();
                    874:                                if (Upper(*ask("No",
                    875: "Some MACROS haven't been saved; leave anyway? ")) != 'Y')
                    876:                                        break;
                    877:                        }
                    878:                        if (ModBufs(0)) {
                    879:                                rbell();
                    880:                                if (Upper(*ask("No",
                    881: "Some buffers haven't been saved; leave anyway? ")) != 'Y')
                    882:                                        break;
                    883:                        }
                    884: #ifdef IPROCS
                    885:                        KillProcs();
                    886: #endif
                    887:                }
                    888:                pop_env(savejmp);
                    889:                return;
                    890: 
                    891:        case ERROR:
                    892:                getDOT();       /* God knows what state linebuf was in */
                    893: 
                    894:        case COMPLAIN:
                    895:                gc_openfiles(); /* close any files we left open */
                    896:                errormsg++;
                    897:                fix_macros();
                    898:                Asking = 0;
                    899:                curwind->w_bufp = curbuf;
                    900:                redisplay();
                    901:                break;
                    902:        }
                    903: 
                    904:        this_cmd = last_cmd = 0;
                    905: 
                    906:        for (;;) {
                    907:                if (this_cmd != ARG_CMD) {
                    908:                        exp = 1;
                    909:                        exp_p = 0;
                    910:                        last_cmd = this_cmd;
                    911:                        init_strokes();
                    912:                }
                    913:                c = getch();
                    914:                if (c == -1)
                    915:                        continue;
                    916:                dispatch(c);
                    917:        }
                    918: }
                    919: 
                    920: int    Crashing = 0;
                    921: 
                    922: char **
                    923: scanvec(args, str)
                    924: register char  **args,
                    925:                *str;
                    926: {
                    927:        while (*args) {
                    928:                if (strcmp(*args, str) == 0)
                    929:                        return args;
                    930:                args++;
                    931:        }
                    932:        return 0;
                    933: }
                    934: 
                    935: int    UpdFreq = 30,
                    936:        inIOread = 0;
                    937: 
                    938: updmode()
                    939: {
                    940:        UpdModLine++;
                    941:        if (inIOread)
                    942:                redisplay();
                    943: #ifndef JOB_CONTROL
                    944:        (void) signal(SIGALRM, updmode);
                    945: #endif
                    946:        (void) alarm((unsigned) UpdFreq);
                    947: }
                    948: 
                    949: #ifdef TIOCGWINSZ
                    950: #ifdef SIGWINCH
                    951: extern win_reshape();
                    952: #endif
                    953: #endif
                    954: 
                    955: #ifdef TIOCGWINSZ
                    956: #ifdef SIGWINCH
                    957: win_reshape()
                    958: {
                    959:        register int diff;
                    960: 
                    961:        (void) signal(SIGWINCH, SIG_IGN);
                    962: 
                    963:        /*
                    964:         * Save old number of lines.
                    965:         */
                    966:        diff = LI;
                    967: 
                    968:        /*
                    969:         * Get new line/col info.
                    970:         */
                    971:        ttsize();
                    972: 
                    973:        /*
                    974:         * LI has changed, and now holds the
                    975:         * new value.  See how much the size
                    976:         * changed.
                    977:         */
                    978:        diff = LI - diff;
                    979: 
                    980:        /*
                    981:         * Change the size of the current window
                    982:         * only.  If they shrank by more than
                    983:         * the window size, tough.
                    984:         */
                    985:        if ((curwind->w_height + diff) < 2)
                    986:                curwind->w_height = 2;
                    987:        else
                    988:                curwind->w_height += diff;
                    989: 
                    990:        make_scr();
                    991:        redisplay();
                    992: 
                    993:        (void) signal(SIGWINCH, win_reshape);
                    994: }
                    995: #endif
                    996: #endif
                    997: 
                    998: main(argc, argv)
                    999: char   *argv[];
                   1000: {
                   1001:        char    ttbuf[512],
                   1002: #ifndef VMUNIX
                   1003:                s_iobuff[LBSIZE],
                   1004:                s_genbuf[LBSIZE],
                   1005:                s_linebuf[LBSIZE],
                   1006: #endif
                   1007:                *cp;
                   1008: 
                   1009: 
                   1010: #ifndef VMUNIX
                   1011:        /* The way I look at it, there ain't no way I is gonna run
                   1012:           out of stack space UNLESS I have some kind of infinite
                   1013:           recursive bug.  So why use up some valuable memory, when
                   1014:           there is plenty of space on the stack?  (This only matters
                   1015:           on wimpy pdp11's, of course.) */
                   1016: 
                   1017:        iobuff = s_iobuff;
                   1018:        genbuf = s_genbuf;
                   1019:        linebuf = s_linebuf;
                   1020: #endif
                   1021: 
                   1022:        errormsg = 0;
                   1023: 
                   1024:        iniargc = argc;
                   1025:        iniargv = argv;
                   1026: 
                   1027:        if (setjmp(mainjmp)) {
                   1028:                printf("\rAck! I can't deal with error \"%s\" now.\n\r", mesgbuf);
                   1029:                finish(0);
                   1030:        }
                   1031: 
                   1032:        if (scanvec(argv, "-r"))
                   1033:                dorecover();
                   1034: 
                   1035:        getTERM();      /* Get terminal. */
                   1036:        if (getenv("METAKEY"))
                   1037:                MetaKey = 1;
                   1038:        ttsize();
                   1039:        InitCM();
                   1040: 
                   1041:        tmpinit();      /* Init temp file. */
                   1042: 
                   1043:        if (cp = getenv("SHELL"))
                   1044:                strcpy(Shell, cp);
                   1045: 
                   1046:        make_scr();
                   1047:        mac_init();     /* Initialize Macros */
                   1048:        winit();        /* Initialize Window */
                   1049: #ifdef IPROCS
                   1050:        pinit();        /* Pipes/process initialization */
                   1051: #endif
                   1052:        SetBuf(do_select(curwind, Mainbuf));
                   1053: 
                   1054: #ifdef CHDIR
                   1055:        {
                   1056:                char    **argp;
                   1057: 
                   1058:                if ((argp = scanvec(argv, "-d")) && (argp[1][0] == '/'))
                   1059:                        setCWD(argp[1]);
                   1060:                else
                   1061:                        getCWD();       /* After we setup curbuf in case we have to getwd() */
                   1062:        }
                   1063: #endif
                   1064:        HomeDir = getenv("HOME");
                   1065:        if (HomeDir == 0)
                   1066:                HomeDir = "/";
                   1067:        HomeLen = strlen(HomeDir);
                   1068:        (void) joverc(JOVERC);
                   1069:        if (!scanvec(argv, "-j")) {
                   1070:                char    tmpbuf[100];
                   1071: 
                   1072:                sprintf(tmpbuf, "%s/.joverc", HomeDir);
                   1073:                (void) joverc(tmpbuf);
                   1074:        }
                   1075: #ifdef SYSV
                   1076:        sprintf(MailBox, "/usr/mail/%s", getenv("LOGNAME"));
                   1077: #else
                   1078:        sprintf(Mailbox, "/usr/spool/mail/%s", getenv("USER"));
                   1079: #endif SYSV
                   1080:        (void) time(&time0);
                   1081:        ttinit();       /* initialize terminal (after ~/.joverc) */
                   1082:        settout(ttbuf); /* not until we know baudrate */
                   1083:        ResetTerm();
                   1084: 
                   1085:        (void) signal(SIGHUP, finish);
                   1086:        (void) signal(SIGINT, finish);
                   1087:        (void) signal(SIGQUIT, SIG_IGN);
                   1088:        (void) signal(SIGBUS, finish);
                   1089:        (void) signal(SIGSEGV, finish);
                   1090:        (void) signal(SIGPIPE, finish);
                   1091:        (void) signal(SIGTERM, SIG_IGN);
                   1092: #ifdef TIOCGWINSZ
                   1093: #ifdef SIGWINCH
                   1094:        (void) signal(SIGWINCH, win_reshape);
                   1095: #endif
                   1096: #endif
                   1097: 
                   1098:        /* set things up to update the modeline every UpdFreq seconds */
                   1099:        (void) signal(SIGALRM, updmode);
                   1100:        (void) alarm((unsigned) UpdFreq);
                   1101: 
                   1102:        cl_scr(1);
                   1103:        flusho();
                   1104:        RedrawDisplay();        /* start the redisplay process. */
                   1105:        DoKeys(0);
                   1106:        finish(0);
                   1107: }

unix.superglobalmegacorp.com

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