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