|
|
1.1 root 1: /*************************************************************************
2: * This program is copyright (C) 1985, 1986 by Jonathan Payne. It is *
3: * provided to you without charge for use only on a licensed Unix *
4: * system. You may copy JOVE provided that this notice is included with *
5: * the copy. You may not sell copies of this program or versions *
6: * modified for use on microcomputer systems, unless the copies are *
7: * included with a Unix system distribution and the source is provided. *
8: *************************************************************************/
9:
10: /* Contains the main loop initializations, and some system dependent
11: type things, e.g. putting terminal in CBREAK mode, etc. */
12:
13: #include "jove.h"
14: #include "io.h"
15: #include "termcap.h"
16:
17: #include <varargs.h>
18: #include <sys/stat.h>
19: #include <signal.h>
20: #include <errno.h>
21: #ifndef SYSV
22: #include <sgtty.h>
23: #include <fcntl.h>
24: #else
25: #include <termio.h>
26: #endif SYSV
27:
28: #ifdef TIOCSLTC
29: struct ltchars ls1,
30: ls2;
31: #endif TIOCSLTC
32:
33: #ifdef TIOCGETC
34: struct tchars tc1,
35: tc2;
36: #endif
37:
38: #ifdef BRLUNIX
39: struct sg_brl sg1, sg2;
40: #else
41: #ifdef SYSV
42: struct termio sg1, sg2;
43: #else SYSV
44: struct sgttyb sg1, sg2;
45: #endif SYSV
46: #endif BRLUNIX
47:
48: #ifdef BIFF
49: private struct stat tt_stat; /* for biff */
50: #ifndef BSD4_2
51: private char *tt_name = 0; /* name of the control tty */
52: extern char *ttyname(); /* for systems w/o fchmod ... */
53: #endif
54: private int dw_biff = NO; /* whether or not to fotz at all */
55: #endif
56:
57: time_t time0; /* when jove started up */
58: int errormsg;
59: extern char *tfname;
60: char NullStr[] = "";
61:
62: finish(code)
63: {
64: int CoreDump = (code != 0 && code != SIGHUP),
65: DelTmps = 1; /* Usually we delete them. */
66:
67: #ifdef LSRHS
68: if (CoreDump)
69: setdump(1);
70: #endif
71: if (code == SIGINT) {
72: char c;
73:
74: #ifndef MENLO_JCL
75: (void) signal(code, finish);
76: #endif
77: f_mess("Abort (Type 'n' if you're not sure)? ");
78: (void) read(0, &c, 1);
79: message(NullStr);
80: if ((c & 0377) != 'y') {
81: redisplay();
82: return;
83: }
84: }
85: ttyset(OFF);
86: UnsetTerm(NullStr);
87: if (code != 0) {
88: if (!Crashing) {
89: Crashing++;
90: lsave();
91: SyncRec();
92: printf("JOVE CRASH!! (code %d)\n", code);
93: if (ModBufs(1)) {
94: printf("Your buffers have been saved.\n");
95: printf("Use \"jove_recover\" or \"jove -r\"\n");
96: printf("to have a look at them.\n");
97: DelTmps = 0; /* Don't delete anymore. */
98: } else
99: printf("You didn't lose any work.\n");
100: } else
101: printf("\r\nYou may have lost your work!\n");
102: }
103: flusho();
104: if (DelTmps) {
105: tmpclose();
106: recclose();
107: }
108: if (CoreDump)
109: abort();
110: #ifdef PROFILING
111: exit(exp_p);
112: #else
113: _exit(exp_p);
114: #endif
115: }
116:
117: private char smbuf[20],
118: *bp = smbuf;
119: private int nchars = 0;
120:
121: private char peekbuf[10],
122: *peekp = peekbuf;
123:
124: #ifdef SYSV
125: void
126: setblock(fd, on) /* turn blocking on or off */
127: register int fd, on;
128: {
129: static int blockf, nonblockf;
130: static int first = 1;
131: int flags;
132:
133: if (first) {
134: first = 0;
135: if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
136: finish(SIGHUP);
137: blockf = flags & ~O_NDELAY; /* make sure O_NDELAY is off */
138: nonblockf = flags | O_NDELAY; /* make sure O_NDELAY is on */
139: }
140: if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
141: finish(SIGHUP);
142: return;
143: }
144: #endif SYSV
145:
146: Peekc()
147: {
148: int c;
149:
150: if (peekp == peekbuf)
151: c = -1;
152: else
153: c = *--peekp & 0377;
154: return c;
155: }
156:
157: Ungetc(c)
158: {
159: if (peekp == &peekbuf[(sizeof peekbuf) - 1])
160: return; /* Sorry, can't oblige you ... */
161: *peekp++ = c;
162: }
163:
164: char *Inputp = 0;
165:
166: #ifdef IPROCS
167: #ifdef PIPEPROCS
168: getchar()
169: {
170: extern int errno;
171: register int c;
172:
173: if (nchars <= 0) {
174: do
175: nchars = read(0, smbuf, sizeof smbuf);
176: #ifdef SYSV
177: while (nchars == 0 || (nchars < 0 && errno == EINTR));
178: if (nchars < 0)
179: #else
180: while (nchars < 0 && errno == EINTR);
181: if (nchars <= 0)
182: #endif SYSV
183: finish(SIGHUP);
184: bp = smbuf;
185: InputPending = nchars > 1;
186: }
187: if (((c = *bp) & 0200) && MetaKey != 0) {
188: *bp = (c & 0177);
189: return '\033';
190: }
191: nchars--;
192: return (*bp++ & 0177);
193: }
194: #else PIPEPROCS
195: getchar()
196: {
197: extern int global_fd,
198: NumProcs,
199: errno;
200: register int tmp,
201: nfds;
202: int reads,
203: c;
204:
205: if (nchars <= 0) {
206: /* Get a character from the keyboard, first checking for
207: any input from a process. Handle that first, and then
208: deal with the terminal input. */
209: if (NumProcs > 0) {
210: do {
211: do {
212: reads = global_fd;
213: nfds = select(32, &reads, (int *) 0, (int *) 0, (struct timeval *) 0);
214: } while (nfds < 0 && errno == EINTR);
215:
216: switch (nfds) {
217: case -1:
218: printf("\rerror %d in select %d", errno, global_fd);
219: global_fd = 1;
220: break;
221: default:
222: if (reads & 01) {
223: nchars = read(0, smbuf, sizeof(smbuf));
224: reads &= ~01;
225: --nfds;
226: }
227:
228: while (nfds--) {
229: tmp = ffs(reads) - 1;
230: read_proc(tmp);
231: reads &= ~tmp;
232: }
233:
234: break;
235: }
236: } while (nchars <= 0);
237: } else {
238: do
239: nchars = read(0, smbuf, sizeof(smbuf));
240: while (nchars < 0 && errno == EINTR);
241: }
242:
243: if (nchars <= 0)
244: finish(SIGHUP);
245:
246: bp = smbuf;
247: InputPending = (nchars > 1);
248: }
249:
250: if (((c = *bp) & 0200) && MetaKey != 0) {
251: *bp = (c & 0177);
252: return '\033';
253: }
254: nchars--;
255: return *bp++ & 0377;
256: }
257: #endif PIPEPROCS
258: #else IPROCS
259: getchar()
260: {
261: extern int errno;
262: register int c;
263:
264: if (nchars <= 0) {
265: do
266: nchars = read(0, smbuf, sizeof smbuf);
267: while (nchars < 0 && errno == EINTR);
268:
269: if (nchars <= 0)
270: finish(SIGHUP);
271: bp = smbuf;
272: InputPending = nchars > 1;
273: }
274: if (((c = *bp) & 0200) && MetaKey != 0) {
275: *bp = (c & 0177);
276: return '\033';
277: }
278: nchars--;
279: return *bp++ & 0377;
280: }
281: #endif IPROCS
282:
283: int InputPending = 0;
284:
285: /* Returns non-zero if a character waiting */
286:
287: charp()
288: {
289: int some = 0;
290:
291: if (InJoverc != 0 || nchars > 0 || Inputp != 0)
292: return 1;
293: #ifdef BRLUNIX
294: {
295: static struct sg_brl gttyBuf;
296:
297: gtty(0, (char *) >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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.