|
|
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 *) >tyBuf); ! 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(®s, ®s); ! 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.