Annotation of gforth/io.c, revision 1.6
1.1 anton 1: /* direct key io driver
2:
3: The following is stolen from the readline library for bash
4: */
5:
1.2 benschop 6: /* Use -DDOMAINOS for Apollo Domain-OS.
7: Use -D_POSIX_VERSION for POSIX systems.
8: */
9:
10: #ifdef DOMAINOS
11: #define _POSIX_VERSION
12: #endif
13:
1.1 anton 14: #include <stdio.h>
15: #include <signal.h>
16: #include <sys/types.h>
1.2 benschop 17: #ifndef DOMAINOS
1.1 anton 18: #include <sys/ioctl.h>
1.2 benschop 19: #endif
1.1 anton 20: #include <fcntl.h>
21: #include <sys/file.h>
1.4 anton 22: #include <setjmp.h>
23: #include "forth.h"
24: #include "io.h"
1.1 anton 25:
26: #if defined (__GNUC__)
27: # define alloca __builtin_alloca
28: #else
29: # if defined (sparc) || defined (HAVE_ALLOCA_H)
30: # include <alloca.h>
31: # endif
32: #endif
33:
34: #if defined (HAVE_UNISTD_H)
35: # include <unistd.h>
36: #endif
37:
38: #define NEW_TTY_DRIVER
39: #define HAVE_BSD_SIGNALS
1.5 pazsan 40: /*
1.2 benschop 41: #ifndef DOMAINOS
1.1 anton 42: #define USE_XON_XOFF
1.2 benschop 43: #endif
1.5 pazsan 44: */
1.1 anton 45:
1.5 pazsan 46: #define HANDLE_SIGNALS
47:
1.1 anton 48: /* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
49: #if defined (USG) && !defined (hpux)
50: #undef HAVE_BSD_SIGNALS
51: #endif
52:
53: /* System V machines use termio. */
54: #if !defined (_POSIX_VERSION)
1.6 ! pazsan 55: # if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX) || defined (ultrix) || defined (Solaris)
1.1 anton 56: # undef NEW_TTY_DRIVER
57: # define TERMIO_TTY_DRIVER
58: # include <termio.h>
59: # if !defined (TCOON)
60: # define TCOON 1
61: # endif
62: # endif /* USG || hpux || Xenix || sgi || DUGX || ultrix*/
63: #endif /* !_POSIX_VERSION */
64:
65: /* Posix systems use termios and the Posix signal functions. */
66: #if defined (_POSIX_VERSION)
67: # if !defined (TERMIOS_MISSING)
68: # undef NEW_TTY_DRIVER
69: # define TERMIOS_TTY_DRIVER
70: # include <termios.h>
71: # endif /* !TERMIOS_MISSING */
72: # define HAVE_POSIX_SIGNALS
73: # if !defined (O_NDELAY)
74: # define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */
75: # endif /* O_NDELAY */
76: #endif /* _POSIX_VERSION */
77:
78: /* Other (BSD) machines use sgtty. */
79: #if defined (NEW_TTY_DRIVER)
80: #include <sgtty.h>
81: #endif
82:
83: /* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
84: it is not already defined. It is used both to determine if a
85: special character is disabled and to disable certain special
86: characters. Posix systems should set to 0, USG systems to -1. */
87: #if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
88: # if defined (_POSIX_VERSION)
89: # define _POSIX_VDISABLE 0
90: # else /* !_POSIX_VERSION */
91: # define _POSIX_VDISABLE -1
92: # endif /* !_POSIX_VERSION */
93: #endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
94:
95: #include <errno.h>
96: extern int errno;
97:
98: #if defined (SHELL)
99: # include <posixstat.h>
100: #else
101: # include <sys/stat.h>
102: #endif /* !SHELL */
103: /* #define HACK_TERMCAP_MOTION */
104:
105: #if defined (USG) && defined (hpux)
106: # if !defined (USGr3)
107: # define USGr3
108: # endif /* USGr3 */
109: #endif /* USG && hpux */
110:
1.2 benschop 111: #if (defined (_POSIX_VERSION) || defined (USGr3)) && !defined(DOMAINOS)
1.1 anton 112: # include <dirent.h>
113: # define direct dirent
114: # if defined (_POSIX_VERSION)
115: # define D_NAMLEN(d) (strlen ((d)->d_name))
116: # else /* !_POSIX_VERSION */
117: # define D_NAMLEN(d) ((d)->d_reclen)
118: # endif /* !_POSIX_VERSION */
119: #else /* !_POSIX_VERSION && !USGr3 */
120: # define D_NAMLEN(d) ((d)->d_namlen)
121: # if !defined (USG)
122: # include <sys/dir.h>
123: # else /* USG */
124: # if defined (Xenix)
125: # include <sys/ndir.h>
126: # else /* !Xenix */
127: # include <ndir.h>
128: # endif /* !Xenix */
129: # endif /* USG */
130: #endif /* !POSIX_VERSION && !USGr3 */
131:
132: #if defined (USG) && defined (TIOCGWINSZ)
133: # include <sys/stream.h>
134: # if defined (USGr4) || defined (USGr3)
135: # if defined (Symmetry) || defined (_SEQUENT_)
136: # include <sys/pte.h>
137: # else
138: # include <sys/ptem.h>
139: # endif /* !Symmetry || _SEQUENT_ */
140: # endif /* USGr4 */
141: #endif /* USG && TIOCGWINSZ */
142:
143: #if defined (TERMIOS_TTY_DRIVER)
144: static struct termios otio;
145: #else
146: static struct termio otio;
147: #endif /* !TERMIOS_TTY_DRIVER */
148:
149: /* Non-zero means echo characters as they are read. */
150: int readline_echoing_p = 1;
151:
152: /* The character that can generate an EOF. Really read from
153: the terminal driver... just defaulted here. */
154:
155: #ifndef CTRL
156: #define CTRL(key) ((key)-'@')
157: #endif
158:
159: static int eof_char = CTRL ('D');
160:
161: /* **************************************************************** */
162: /* */
163: /* Saving and Restoring the TTY */
164: /* */
165: /* **************************************************************** */
166:
167: /* Non-zero means that the terminal is in a prepped state. */
168: static int terminal_prepped = 0;
169:
170: #if defined (NEW_TTY_DRIVER)
171:
172: /* Standard flags, including ECHO. */
173: static int original_tty_flags = 0;
174:
175: /* Local mode flags, like LPASS8. */
176: static int local_mode_flags = 0;
177:
178: /* Terminal characters. This has C-s and C-q in it. */
179: static struct tchars original_tchars;
180:
181: /* Local special characters. This has the interrupt characters in it. */
182: #if defined (TIOCGLTC)
183: static struct ltchars original_ltchars;
184: #endif
185:
186: /* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */
187:
188: #if defined (TIOCGETC)
189: #if defined (USE_XON_XOFF)
190:
191: int
192: bind_key (key, function)
193: int key;
194: Function *function;
195: {
196: if (key < 0)
197: return (key);
198:
199: if (key > 127 && key < 256)
200: {
201: if (keymap[ESC].type == ISKMAP)
202: {
203: Keymap escmap = (Keymap)keymap[ESC].function;
204:
205: key -= 128;
206: escmap[key].type = ISFUNC;
207: escmap[key].function = function;
208: return (0);
209: }
210: return (key);
211: }
212:
213: keymap[key].type = ISFUNC;
214: keymap[key].function = function;
215: return (0);
216: }
217: #endif
218: #endif
219:
220: /* We use this to get and set the tty_flags. */
221: static struct sgttyb the_ttybuff;
222:
223: #if defined (USE_XON_XOFF)
224: /* If the terminal was in xoff state when we got to it, then xon_char
225: contains the character that is supposed to start it again. */
226: static int xon_char, xoff_state;
227: #endif /* USE_XON_XOFF */
228:
229: /* **************************************************************** */
230: /* */
231: /* Bogus Flow Control */
232: /* */
233: /* **************************************************************** */
234:
235: restart_output (count, key)
236: int count, key;
237: {
238: int fildes = fileno (stdin);
239: #if defined (TIOCSTART)
240: #if defined (apollo)
241: ioctl (&fildes, TIOCSTART, 0);
242: #else
243: ioctl (fildes, TIOCSTART, 0);
244: #endif /* apollo */
245:
246: #else
247: # if defined (TERMIOS_TTY_DRIVER)
248: tcflow (fildes, TCOON);
249: # else
250: # if defined (TCXONC)
251: ioctl (fildes, TCXONC, TCOON);
252: # endif /* TCXONC */
253: # endif /* !TERMIOS_TTY_DRIVER */
254: #endif /* TIOCSTART */
255: }
256:
257: /* Put the terminal in CBREAK mode so that we can detect key presses. */
258: void prep_terminal ()
259: {
260: int tty = fileno (stdin);
261: #if defined (HAVE_BSD_SIGNALS)
262: int oldmask;
263: #endif /* HAVE_BSD_SIGNALS */
264:
265: if (terminal_prepped)
266: return;
267:
268: oldmask = sigblock (sigmask (SIGINT));
269:
270: /* We always get the latest tty values. Maybe stty changed them. */
271: ioctl (tty, TIOCGETP, &the_ttybuff);
272: original_tty_flags = the_ttybuff.sg_flags;
273:
274: readline_echoing_p = (original_tty_flags & ECHO);
275:
276: #if defined (TIOCLGET)
277: ioctl (tty, TIOCLGET, &local_mode_flags);
278: #endif
279:
280: #if !defined (ANYP)
281: # define ANYP (EVENP | ODDP)
282: #endif
283:
284: /* If this terminal doesn't care how the 8th bit is used,
285: then we can use it for the meta-key. We check by seeing
286: if BOTH odd and even parity are allowed. */
287: if (the_ttybuff.sg_flags & ANYP)
288: {
289: #if defined (PASS8)
290: the_ttybuff.sg_flags |= PASS8;
291: #endif
292:
293: /* Hack on local mode flags if we can. */
294: #if defined (TIOCLGET) && defined (LPASS8)
295: {
296: int flags;
297: flags = local_mode_flags | LPASS8;
298: ioctl (tty, TIOCLSET, &flags);
299: }
300: #endif /* TIOCLGET && LPASS8 */
301: }
302:
303: #if defined (TIOCGETC)
304: {
305: struct tchars temp;
306:
307: ioctl (tty, TIOCGETC, &original_tchars);
308: temp = original_tchars;
309:
310: #if defined (USE_XON_XOFF)
311: /* Get rid of C-s and C-q.
312: We remember the value of startc (C-q) so that if the terminal is in
313: xoff state, the user can xon it by pressing that character. */
314: xon_char = temp.t_startc;
315: temp.t_stopc = -1;
316: temp.t_startc = -1;
317:
318: /* If there is an XON character, bind it to restart the output. */
319: if (xon_char != -1)
320: bind_key (xon_char, restart_output);
321: #endif /* USE_XON_XOFF */
322:
323: /* If there is an EOF char, bind eof_char to it. */
324: if (temp.t_eofc != -1)
325: eof_char = temp.t_eofc;
326:
327: #if defined (NO_KILL_INTR)
328: /* Get rid of C-\ and C-c. */
329: temp.t_intrc = temp.t_quitc = -1;
330: #endif /* NO_KILL_INTR */
331:
332: ioctl (tty, TIOCSETC, &temp);
333: }
334: #endif /* TIOCGETC */
335:
336: #if defined (TIOCGLTC)
337: {
338: struct ltchars temp;
339:
340: ioctl (tty, TIOCGLTC, &original_ltchars);
341: temp = original_ltchars;
342:
343: /* Make the interrupt keys go away. Just enough to make people
344: happy. */
345: temp.t_dsuspc = -1; /* C-y */
346: temp.t_lnextc = -1; /* C-v */
347:
348: ioctl (tty, TIOCSLTC, &temp);
349: }
350: #endif /* TIOCGLTC */
351:
352: the_ttybuff.sg_flags &= ~(ECHO | CRMOD);
353: the_ttybuff.sg_flags |= CBREAK;
354: ioctl (tty, TIOCSETN, &the_ttybuff);
355:
356: terminal_prepped = 1;
357:
358: #if defined (HAVE_BSD_SIGNALS)
359: sigsetmask (oldmask);
360: #endif
361: }
362:
363: /* Restore the terminal to its original state. */
364: void deprep_terminal ()
365: {
366: int tty = fileno (stdin);
367: #if defined (HAVE_BSD_SIGNALS)
368: int oldmask;
369: #endif
370:
371: if (!terminal_prepped)
372: return;
373:
374: oldmask = sigblock (sigmask (SIGINT));
375:
376: the_ttybuff.sg_flags = original_tty_flags;
377: ioctl (tty, TIOCSETN, &the_ttybuff);
378: readline_echoing_p = 1;
379:
380: #if defined (TIOCLGET)
381: ioctl (tty, TIOCLSET, &local_mode_flags);
382: #endif
383:
384: #if defined (TIOCSLTC)
385: ioctl (tty, TIOCSLTC, &original_ltchars);
386: #endif
387:
388: #if defined (TIOCSETC)
389: ioctl (tty, TIOCSETC, &original_tchars);
390: #endif
391: terminal_prepped = 0;
392:
393: #if defined (HAVE_BSD_SIGNALS)
394: sigsetmask (oldmask);
395: #endif
396: }
397:
398: #else /* !defined (NEW_TTY_DRIVER) */
399:
400: #if !defined (VMIN)
401: #define VMIN VEOF
402: #endif
403:
404: #if !defined (VTIME)
405: #define VTIME VEOL
406: #endif
407:
408: void prep_terminal ()
409: {
410: int tty = fileno (stdin);
411: #if defined (TERMIOS_TTY_DRIVER)
412: struct termios tio;
413: #else
414: struct termio tio;
415: #endif /* !TERMIOS_TTY_DRIVER */
416:
417: #if defined (HAVE_POSIX_SIGNALS)
418: sigset_t set, oset;
419: #else
420: # if defined (HAVE_BSD_SIGNALS)
421: int oldmask;
422: # endif /* HAVE_BSD_SIGNALS */
423: #endif /* !HAVE_POSIX_SIGNALS */
424:
425: if (terminal_prepped)
426: return;
427:
428: /* Try to keep this function from being INTerrupted. We can do it
429: on POSIX and systems with BSD-like signal handling. */
430: #if defined (HAVE_POSIX_SIGNALS)
431: sigemptyset (&set);
432: sigemptyset (&oset);
433: sigaddset (&set, SIGINT);
434: sigprocmask (SIG_BLOCK, &set, &oset);
435: #else /* !HAVE_POSIX_SIGNALS */
436: # if defined (HAVE_BSD_SIGNALS)
437: oldmask = sigblock (sigmask (SIGINT));
438: # endif /* HAVE_BSD_SIGNALS */
439: #endif /* !HAVE_POSIX_SIGNALS */
440:
441: #if defined (TERMIOS_TTY_DRIVER)
442: tcgetattr (tty, &tio);
443: #else
444: ioctl (tty, TCGETA, &tio);
445: #endif /* !TERMIOS_TTY_DRIVER */
446:
447: otio = tio;
448:
449: readline_echoing_p = (tio.c_lflag & ECHO);
450:
451: tio.c_lflag &= ~(ICANON | ECHO);
452:
453: if (otio.c_cc[VEOF] != _POSIX_VDISABLE)
454: eof_char = otio.c_cc[VEOF];
455:
456: #if defined (USE_XON_XOFF)
457: #if defined (IXANY)
458: tio.c_iflag &= ~(IXON | IXOFF | IXANY);
459: #else
460: /* `strict' Posix systems do not define IXANY. */
461: tio.c_iflag &= ~(IXON | IXOFF);
462: #endif /* IXANY */
463: #endif /* USE_XON_XOFF */
464:
465: /* Only turn this off if we are using all 8 bits. */
466: if ((tio.c_cflag & CSIZE) == CS8)
467: tio.c_iflag &= ~(ISTRIP | INPCK);
468:
469: /* Make sure we differentiate between CR and NL on input. */
470: tio.c_iflag &= ~(ICRNL | INLCR);
471:
472: #if !defined (HANDLE_SIGNALS)
473: tio.c_lflag &= ~ISIG;
474: #else
475: tio.c_lflag |= ISIG;
476: #endif
477:
478: tio.c_cc[VMIN] = 1;
479: tio.c_cc[VTIME] = 0;
480:
481: /* Turn off characters that we need on Posix systems with job control,
482: just to be sure. This includes ^Y and ^V. This should not really
483: be necessary. */
484: #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_JOB_CONTROL)
485:
486: #if defined (VLNEXT)
487: tio.c_cc[VLNEXT] = _POSIX_VDISABLE;
488: #endif
489:
490: #if defined (VDSUSP)
491: tio.c_cc[VDSUSP] = _POSIX_VDISABLE;
492: #endif
493:
494: #endif /* POSIX && JOB_CONTROL */
495:
496: #if defined (TERMIOS_TTY_DRIVER)
497: tcsetattr (tty, TCSADRAIN, &tio);
498: tcflow (tty, TCOON); /* Simulate a ^Q. */
499: #else
500: ioctl (tty, TCSETAW, &tio);
501: ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
502: #endif /* !TERMIOS_TTY_DRIVER */
503:
504: terminal_prepped = 1;
505:
506: #if defined (HAVE_POSIX_SIGNALS)
507: sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
508: #else
509: # if defined (HAVE_BSD_SIGNALS)
510: sigsetmask (oldmask);
511: # endif /* HAVE_BSD_SIGNALS */
512: #endif /* !HAVE_POSIX_SIGNALS */
513: }
514:
515: void deprep_terminal ()
516: {
517: int tty = fileno (stdin);
518:
519: /* Try to keep this function from being INTerrupted. We can do it
520: on POSIX and systems with BSD-like signal handling. */
521: #if defined (HAVE_POSIX_SIGNALS)
522: sigset_t set, oset;
523: #else /* !HAVE_POSIX_SIGNALS */
524: # if defined (HAVE_BSD_SIGNALS)
525: int oldmask;
526: # endif /* HAVE_BSD_SIGNALS */
527: #endif /* !HAVE_POSIX_SIGNALS */
528:
529: if (!terminal_prepped)
530: return;
531:
532: #if defined (HAVE_POSIX_SIGNALS)
533: sigemptyset (&set);
534: sigemptyset (&oset);
535: sigaddset (&set, SIGINT);
536: sigprocmask (SIG_BLOCK, &set, &oset);
537: #else /* !HAVE_POSIX_SIGNALS */
538: # if defined (HAVE_BSD_SIGNALS)
539: oldmask = sigblock (sigmask (SIGINT));
540: # endif /* HAVE_BSD_SIGNALS */
541: #endif /* !HAVE_POSIX_SIGNALS */
542:
543: #if defined (TERMIOS_TTY_DRIVER)
544: tcsetattr (tty, TCSADRAIN, &otio);
545: tcflow (tty, TCOON); /* Simulate a ^Q. */
546: #else /* TERMIOS_TTY_DRIVER */
547: ioctl (tty, TCSETAW, &otio);
548: ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
549: #endif /* !TERMIOS_TTY_DRIVER */
550:
551: terminal_prepped = 0;
552:
553: #if defined (HAVE_POSIX_SIGNALS)
554: sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
555: #else /* !HAVE_POSIX_SIGNALS */
556: # if defined (HAVE_BSD_SIGNALS)
557: sigsetmask (oldmask);
558: # endif /* HAVE_BSD_SIGNALS */
559: #endif /* !HAVE_POSIX_SIGNALS */
560: }
561: #endif /* NEW_TTY_DRIVER */
562:
563: /* If a character is available to be read, then read it
564: and stuff it into IBUFFER. Otherwise, just return. */
565:
566: long pending = -1L;
567:
568: long key_avail (stream)
569: FILE *stream;
570: {
571: int tty = fileno (stream);
572: long chars_avail = pending;
573: int result;
574:
575: #if defined (FIONREAD)
576: result = ioctl (tty, FIONREAD, &chars_avail);
577: #endif
578:
579: if(chars_avail == -1L)
580: { unsigned char inchar;
581:
582: fcntl(tty, F_SETFL, O_NDELAY);
583: result = read(tty, &inchar, sizeof(char));
584: if(result == sizeof(char))
585: {
586: chars_avail = 1;
587: pending = (long)inchar;
588: }
589: else
590: chars_avail = 0;
591: fcntl(tty, F_SETFL, 0);
592: }
593:
594: return chars_avail;
595: }
596:
597: /* Get a key from the buffer of characters to be read.
598: Return the key in KEY.
599: Result is KEY if there was a key, or 0 if there wasn't. */
600:
601: /* When compiling and running in the `Posix' environment, Ultrix does
602: not restart system calls, so this needs to do it. */
603:
604: unsigned char getkey(stream)
605: FILE *stream;
606: {
607: int result;
608: unsigned char c;
609:
610: while (pending < 0)
611: {
612: result = read (fileno (stream), &c, sizeof (char));
613:
614: if (result == sizeof (char))
615: return /* (c == 0x7F ? 0x08 :*/ c /*)*/;
616:
617: /* If zero characters are returned, then the file that we are
618: reading from is empty! Return EOF in that case. */
619: if (result == 0)
620: return (0);
621:
622: /* If the error that we received was SIGINT, then try again,
623: this is simply an interrupted system call to read ().
624: Otherwise, some error ocurred, also signifying EOF. */
625: if (errno != EINTR)
626: return (EOF);
627: }
628:
629: result = (int) pending;
630: pending = -1L;
631:
632: return result;
633: }
634:
635: #ifdef TEST
636:
637: #include <time.h>
638:
639: int timewait=100000;
640:
641: int main()
642: {
643: unsigned char c;
644:
645: prep_terminal();
646:
647: do
648: {
649: int i=0;
650:
651: while(!key_avail(stdin))
652: {
653: printf("%04d",i);
654: fflush(stdout);
655: {
656: struct timeval timeout;
657: timeout.tv_sec=timewait/1000000;
658: timeout.tv_usec=timewait%1000000;
659: (void)select(0,0,0,0,&timeout);
660: }
661: i++;
662: printf("\b\b\b\b");
663: fflush(stdout);
664: }
665: c = getkey(stdin);
666: printf("%02x,",(int)c);
667: fflush(stdout);
668: } while(c != 0x1B);
669:
670: deprep_terminal();
671: puts("");
672: }
673: #endif
674:
675: /* signal handling taken from pfe by Dirk Zoller (Copylefted) - anton */
676: /* !! needs cleanup */
677: char *
678: sigmsg (int sig)
679: {
680: static char buf [25];
681: static char *msg [] =
682: {
683: "Hangup", /* These strings are cited from */
684: "Interrupt", /* Rochkind: Advanced UNIX programming */
685: "Quit",
686: "Illegal Instruction",
687: "Trace Trap",
688: "IOT instruction",
689: "EMT instruction",
690: "Floating point exception",
691: "Kill",
692: "Bus error",
693: "Segmentation Violation",
694: "Bad arg to system call",
695: "Broken pipe",
696: "Alarm clock",
697: "Terminate signal",
698: "User signal 1",
699: "User signal 2",
700: };
701:
702: if ((unsigned)sig <= 17)
703: return msg [sig - 1];
704: sprintf (buf, "signal %d received", sig);
705: return buf;
706: }
707:
708: static void
709: graceful_exit (int sig)
710: {
711: deprep_terminal();
712: if ((unsigned)sig <= 17)
713: fprintf (stderr, "\n\n%s.\n", sigmsg (sig));
714: else
715: fprintf (stderr, "\n\nSignal %d received, terminated.\n", sig);
1.4 anton 716: exit (0x80|sig);
1.1 anton 717: }
718:
1.4 anton 719: jmp_buf throw_jmp_buf;
720:
721: static void
722: signal_throw(int sig)
723: {
724: static int throw_codes[] = {
725: -256,
726: -28,
727: -257,
728: -258,
729: -259,
730: -260,
731: -261,
732: -55,
733: -262,
734: -23,
735: -9,
736: -263,
737: -264,
738: -265,
739: -266,
740: -267,
741: -268,
742: };
743: signal(sig,signal_throw);
744: longjmp(throw_jmp_buf,throw_codes[sig-1]); /* or use siglongjmp ? */
745: }
746:
1.5 pazsan 747: static void
748: termprep (int sig)
749: {
750: terminal_prepped=0; prep_terminal();
751: signal(sig,termprep);
752: }
753:
1.1 anton 754: void
755: install_signal_handlers (void)
756: {
757: /* !! These definitions seem to be system dependent
758: We could have them in the machine.h file,
759: but I would like something more automatic - anton */
760: #define SIGS_TO_IGNORE SIGCHLD
761: #define SIGS_TO_ABORT SIGINT, SIGILL, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2, \
1.3 anton 762: SIGALRM, SIGBUS
1.1 anton 763: #define SIGS_TO_QUIT SIGHUP, SIGQUIT, SIGABRT, SIGPIPE, \
764: SIGTERM
1.5 pazsan 765: #define SIGS_TO_TERMPREP SIGCONT
1.1 anton 766:
767: static short sigs_to_ignore [] = { SIGS_TO_IGNORE };
768: static short sigs_to_abort [] = { SIGS_TO_ABORT };
769: static short sigs_to_quit [] = { SIGS_TO_QUIT };
1.5 pazsan 770: static short sigs_to_termprep [] = { SIGS_TO_TERMPREP };
1.1 anton 771: int i;
772:
773: #define DIM(X) (sizeof (X) / sizeof *(X))
774: for (i = 0; i < DIM (sigs_to_ignore); i++)
775: if (sigs_to_ignore [i])
776: signal (sigs_to_ignore [i], SIG_IGN);
777: for (i = 0; i < DIM (sigs_to_abort); i++)
1.4 anton 778: signal (sigs_to_abort [i], signal_throw); /* !! change to throw */
1.1 anton 779: for (i = 0; i < DIM (sigs_to_quit); i++)
780: signal (sigs_to_quit [i], graceful_exit);
1.5 pazsan 781: for (i = 0; i < DIM (sigs_to_termprep); i++)
782: signal (sigs_to_termprep [i], termprep);
1.1 anton 783: }
784: /* end signal handling */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>