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