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 *) >tyBuf); 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: }