Annotation of 43BSDTahoe/new/jove/jove.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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