home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / readline.zip / readline-2.1 / rltty.c < prev    next >
C/C++ Source or Header  |  1997-02-06  |  17KB  |  729 lines

  1. /* rltty.c -- functions to prepare and restore the terminal for readline's
  2.    use. */
  3.  
  4. /* Copyright (C) 1992 Free Software Foundation, Inc.
  5.  
  6.    This file is part of the GNU Readline Library, a library for
  7.    reading lines of text with interactive input and history editing.
  8.  
  9.    The GNU Readline Library is free software; you can redistribute it
  10.    and/or modify it under the terms of the GNU General Public License
  11.    as published by the Free Software Foundation; either version 1, or
  12.    (at your option) any later version.
  13.  
  14.    The GNU Readline Library is distributed in the hope that it will be
  15.    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  16.    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.    GNU General Public License for more details.
  18.  
  19.    The GNU General Public License is often shipped with GNU software, and
  20.    is generally kept in a file called COPYING or LICENSE.  If you do not
  21.    have a copy of the license, write to the Free Software Foundation,
  22.    675 Mass Ave, Cambridge, MA 02139, USA. */
  23. #define READLINE_LIBRARY
  24.  
  25. #if defined (HAVE_CONFIG_H)
  26. #  include <config.h>
  27. #endif
  28.  
  29. #include <sys/types.h>
  30. #include <signal.h>
  31. #include <errno.h>
  32. #include <stdio.h>
  33.  
  34. #if defined (HAVE_UNISTD_H)
  35. #  include <unistd.h>
  36. #endif /* HAVE_UNISTD_H */
  37.  
  38. #include "rldefs.h"
  39.  
  40. #if !defined (SHELL) && defined (GWINSZ_IN_SYS_IOCTL)
  41. #  include <sys/ioctl.h>
  42. #endif /* !SHELL && GWINSZ_IN_SYS_IOCTL */
  43.  
  44. #include "rltty.h"
  45. #include "readline.h"
  46.  
  47. #if !defined (errno)
  48. extern int errno;
  49. #endif /* !errno */
  50.  
  51. extern int readline_echoing_p;
  52. extern int _rl_eof_char;
  53.  
  54. extern int _rl_enable_keypad, _rl_enable_meta;
  55.  
  56. extern void _rl_control_keypad ();
  57.  
  58. #if defined (__GO32__)
  59. #  include <pc.h>
  60. #  undef HANDLE_SIGNALS
  61. #endif /* __GO32__ */
  62.  
  63. /* Indirect functions to allow apps control over terminal management. */
  64. extern void rl_prep_terminal (), rl_deprep_terminal ();
  65.  
  66. VFunction *rl_prep_term_function = rl_prep_terminal;
  67. VFunction *rl_deprep_term_function = rl_deprep_terminal;
  68.  
  69. /* **************************************************************** */
  70. /*                                    */
  71. /*               Signal Management                */
  72. /*                                    */
  73. /* **************************************************************** */
  74.  
  75. #if defined (HAVE_POSIX_SIGNALS)
  76. static sigset_t sigint_set, sigint_oset;
  77. #else /* !HAVE_POSIX_SIGNALS */
  78. #  if defined (HAVE_BSD_SIGNALS)
  79. static int sigint_oldmask;
  80. #  endif /* HAVE_BSD_SIGNALS */
  81. #endif /* !HAVE_POSIX_SIGNALS */
  82.  
  83. static int sigint_blocked;
  84.  
  85. /* Cause SIGINT to not be delivered until the corresponding call to
  86.    release_sigint(). */
  87. static void
  88. block_sigint ()
  89. {
  90.   if (sigint_blocked)
  91.     return;
  92.  
  93. #if defined (HAVE_POSIX_SIGNALS)
  94.   sigemptyset (&sigint_set);
  95.   sigemptyset (&sigint_oset);
  96.   sigaddset (&sigint_set, SIGINT);
  97.   sigprocmask (SIG_BLOCK, &sigint_set, &sigint_oset);
  98. #else /* !HAVE_POSIX_SIGNALS */
  99. #  if defined (HAVE_BSD_SIGNALS)
  100.   sigint_oldmask = sigblock (sigmask (SIGINT));
  101. #  else /* !HAVE_BSD_SIGNALS */
  102. #    if defined (HAVE_USG_SIGHOLD)
  103.   sighold (SIGINT);
  104. #    endif /* HAVE_USG_SIGHOLD */
  105. #  endif /* !HAVE_BSD_SIGNALS */
  106. #endif /* !HAVE_POSIX_SIGNALS */
  107.   sigint_blocked = 1;
  108. }
  109.  
  110. /* Allow SIGINT to be delivered. */
  111. static void
  112. release_sigint ()
  113. {
  114.   if (!sigint_blocked)
  115.     return;
  116.  
  117. #if defined (HAVE_POSIX_SIGNALS)
  118.   sigprocmask (SIG_SETMASK, &sigint_oset, (sigset_t *)NULL);
  119. #else
  120. #  if defined (HAVE_BSD_SIGNALS)
  121.   sigsetmask (sigint_oldmask);
  122. #  else /* !HAVE_BSD_SIGNALS */
  123. #    if defined (HAVE_USG_SIGHOLD)
  124.   sigrelse (SIGINT);
  125. #    endif /* HAVE_USG_SIGHOLD */
  126. #  endif /* !HAVE_BSD_SIGNALS */
  127. #endif /* !HAVE_POSIX_SIGNALS */
  128.  
  129.   sigint_blocked = 0;
  130. }
  131.  
  132. /* **************************************************************** */
  133. /*                                    */
  134. /*              Saving and Restoring the TTY                */
  135. /*                                    */
  136. /* **************************************************************** */
  137.  
  138. /* Non-zero means that the terminal is in a prepped state. */
  139. static int terminal_prepped;
  140.  
  141. /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
  142.    and output is suspended. */
  143. #if defined (__ksr1__)
  144. static int ksrflow;
  145. #endif
  146.  
  147. #if !defined (SHELL) && defined (TIOCGWINSZ)
  148. /* Dummy call to force a backgrounded readline to stop before it tries
  149.    to get the tty settings. */
  150. static void
  151. set_winsize (tty)
  152.      int tty;
  153. {
  154.   struct winsize w;
  155.  
  156.   if (ioctl (tty, TIOCGWINSZ, &w) == 0)
  157.       (void) ioctl (tty, TIOCSWINSZ, &w);
  158. }
  159. #else /* SHELL || !TIOCGWINSZ */
  160. #  define set_winsize(tty)
  161. #endif /* SHELL || !TIOCGWINSZ */
  162.  
  163. #if defined (NEW_TTY_DRIVER)
  164.  
  165. /* Values for the `flags' field of a struct bsdtty.  This tells which
  166.    elements of the struct bsdtty have been fetched from the system and
  167.    are valid. */
  168. #define SGTTY_SET    0x01
  169. #define LFLAG_SET    0x02
  170. #define TCHARS_SET    0x04
  171. #define LTCHARS_SET    0x08
  172.  
  173. struct bsdtty {
  174.   struct sgttyb sgttyb;    /* Basic BSD tty driver information. */
  175.   int lflag;        /* Local mode flags, like LPASS8. */
  176. #if defined (TIOCGETC)
  177.   struct tchars tchars;    /* Terminal special characters, including ^S and ^Q. */
  178. #endif
  179. #if defined (TIOCGLTC)
  180.   struct ltchars ltchars; /* 4.2 BSD editing characters */
  181. #endif
  182.   int flags;        /* Bitmap saying which parts of the struct are valid. */
  183. };
  184.  
  185. #define TIOTYPE struct bsdtty
  186.  
  187. static TIOTYPE otio;
  188.  
  189. static int
  190. get_tty_settings (tty, tiop)
  191.      int tty;
  192.      TIOTYPE *tiop;
  193. {
  194.   set_winsize (tty);
  195.  
  196.   tiop->flags = tiop->lflag = 0;
  197.  
  198.   ioctl (tty, TIOCGETP, &(tiop->sgttyb));
  199.   tiop->flags |= SGTTY_SET;
  200.  
  201. #if defined (TIOCLGET)
  202.   ioctl (tty, TIOCLGET, &(tiop->lflag));
  203.   tiop->flags |= LFLAG_SET;
  204. #endif
  205.  
  206. #if defined (TIOCGETC)
  207.   ioctl (tty, TIOCGETC, &(tiop->tchars));
  208.   tiop->flags |= TCHARS_SET;
  209. #endif
  210.  
  211. #if defined (TIOCGLTC)
  212.   ioctl (tty, TIOCGLTC, &(tiop->ltchars));
  213.   tiop->flags |= LTCHARS_SET;
  214. #endif
  215.  
  216.   return 0;
  217. }
  218.  
  219. static int
  220. set_tty_settings (tty, tiop)
  221.      int tty;
  222.      TIOTYPE *tiop;
  223. {
  224.   if (tiop->flags & SGTTY_SET)
  225.     {
  226.       ioctl (tty, TIOCSETN, &(tiop->sgttyb));
  227.       tiop->flags &= ~SGTTY_SET;
  228.     }
  229.   readline_echoing_p = 1;
  230.  
  231. #if defined (TIOCLSET)
  232.   if (tiop->flags & LFLAG_SET)
  233.     {
  234.       ioctl (tty, TIOCLSET, &(tiop->lflag));
  235.       tiop->flags &= ~LFLAG_SET;
  236.     }
  237. #endif
  238.  
  239. #if defined (TIOCSETC)
  240.   if (tiop->flags & TCHARS_SET)
  241.     {
  242.       ioctl (tty, TIOCSETC, &(tiop->tchars));
  243.       tiop->flags &= ~TCHARS_SET;
  244.     }
  245. #endif
  246.  
  247. #if defined (TIOCSLTC)
  248.   if (tiop->flags & LTCHARS_SET)
  249.     {
  250.       ioctl (tty, TIOCSLTC, &(tiop->ltchars));
  251.       tiop->flags &= ~LTCHARS_SET;
  252.     }
  253. #endif
  254.  
  255.   return 0;
  256. }
  257.  
  258. static void
  259. prepare_terminal_settings (meta_flag, otio, tiop)
  260.      int meta_flag;
  261.      TIOTYPE otio, *tiop;
  262. {
  263. #if !defined (__GO32__)
  264.   readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
  265.  
  266.   /* Copy the original settings to the structure we're going to use for
  267.      our settings. */
  268.   tiop->sgttyb = otio.sgttyb;
  269.   tiop->lflag = otio.lflag;
  270. #if defined (TIOCGETC)
  271.   tiop->tchars = otio.tchars;
  272. #endif
  273. #if defined (TIOCGLTC)
  274.   tiop->ltchars = otio.ltchars;
  275. #endif
  276.   tiop->flags = otio.flags;
  277.  
  278.   /* First, the basic settings to put us into character-at-a-time, no-echo
  279.      input mode. */
  280.   tiop->sgttyb.sg_flags &= ~(ECHO | CRMOD);
  281.   tiop->sgttyb.sg_flags |= CBREAK;
  282.  
  283.   /* If this terminal doesn't care how the 8th bit is used, then we can
  284.      use it for the meta-key.  If only one of even or odd parity is
  285.      specified, then the terminal is using parity, and we cannot. */
  286. #if !defined (ANYP)
  287. #  define ANYP (EVENP | ODDP)
  288. #endif
  289.   if (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
  290.       ((otio.sgttyb.sg_flags & ANYP) == 0))
  291.     {
  292.       tiop->sgttyb.sg_flags |= ANYP;
  293.  
  294.       /* Hack on local mode flags if we can. */
  295. #if defined (TIOCLGET)
  296. #  if defined (LPASS8)
  297.       tiop->lflag |= LPASS8;
  298. #  endif /* LPASS8 */
  299. #endif /* TIOCLGET */
  300.     }
  301.  
  302. #if defined (TIOCGETC)
  303. #  if defined (USE_XON_XOFF)
  304.   /* Get rid of terminal output start and stop characters. */
  305.   tiop->tchars.t_stopc = -1; /* C-s */
  306.   tiop->tchars.t_startc = -1; /* C-q */
  307.  
  308.   /* If there is an XON character, bind it to restart the output. */
  309.   if (otio.tchars.t_startc != -1)
  310.     rl_bind_key (otio.tchars.t_startc, rl_restart_output);
  311. #  endif /* USE_XON_XOFF */
  312.  
  313.   /* If there is an EOF char, bind _rl_eof_char to it. */
  314.   if (otio.tchars.t_eofc != -1)
  315.     _rl_eof_char = otio.tchars.t_eofc;
  316.  
  317. #  if defined (NO_KILL_INTR)
  318.   /* Get rid of terminal-generated SIGQUIT and SIGINT. */
  319.   tiop->tchars.t_quitc = -1; /* C-\ */
  320.   tiop->tchars.t_intrc = -1; /* C-c */
  321. #  endif /* NO_KILL_INTR */
  322. #endif /* TIOCGETC */
  323.  
  324. #if defined (TIOCGLTC)
  325.   /* Make the interrupt keys go away.  Just enough to make people happy. */
  326.   tiop->ltchars.t_dsuspc = -1;    /* C-y */
  327.   tiop->ltchars.t_lnextc = -1;    /* C-v */
  328. #endif /* TIOCGLTC */
  329. #endif /* !__GO32__ */
  330. }
  331.  
  332. #else  /* !defined (NEW_TTY_DRIVER) */
  333.  
  334. #if !defined (VMIN)
  335. #  define VMIN VEOF
  336. #endif
  337.  
  338. #if !defined (VTIME)
  339. #  define VTIME VEOL
  340. #endif
  341.  
  342. #if defined (TERMIOS_TTY_DRIVER)
  343. #  define TIOTYPE struct termios
  344. #  define DRAIN_OUTPUT(fd)    tcdrain (fd)
  345. #  define GETATTR(tty, tiop)    (tcgetattr (tty, tiop))
  346. #  ifdef M_UNIX
  347. #    define SETATTR(tty, tiop)    (tcsetattr (tty, TCSANOW, tiop))
  348. #  else
  349. #    define SETATTR(tty, tiop)    (tcsetattr (tty, TCSADRAIN, tiop))
  350. #  endif /* !M_UNIX */
  351. #else
  352. #  define TIOTYPE struct termio
  353. #  define DRAIN_OUTPUT(fd)
  354. #  define GETATTR(tty, tiop)    (ioctl (tty, TCGETA, tiop))
  355. #  define SETATTR(tty, tiop)    (ioctl (tty, TCSETA, tiop))
  356. #endif /* !TERMIOS_TTY_DRIVER */
  357.  
  358. static TIOTYPE otio;
  359.  
  360. #if defined (FLUSHO)
  361. #  define OUTPUT_BEING_FLUSHED(tp)  (tp->c_lflag & FLUSHO)
  362. #else
  363. #  define OUTPUT_BEING_FLUSHED(tp)  0
  364. #endif
  365.  
  366. static void
  367. rltty_warning (msg)
  368.      char *msg;
  369. {
  370.   fprintf (stderr, "readline: warning: %s\n", msg);
  371. }
  372.  
  373. #if defined (_AIX)
  374. void
  375. setopost(tp)
  376. TIOTYPE *tp;
  377. {
  378.   if ((tp->c_oflag & OPOST) == 0)
  379.     {
  380.       rltty_warning ("turning on OPOST for terminal\r");
  381.       tp->c_oflag |= OPOST|ONLCR;
  382.     }
  383. }
  384. #endif
  385.  
  386. static int
  387. get_tty_settings (tty, tiop)
  388.      int tty;
  389.      TIOTYPE *tiop;
  390. {
  391.   int ioctl_ret;
  392.   set_winsize (tty);
  393.  
  394.   while (1)
  395.     {
  396.       ioctl_ret = GETATTR (tty, tiop);
  397.       if (ioctl_ret < 0)
  398.     {
  399.       if (errno != EINTR)
  400.         return -1;
  401.       else
  402.         continue;
  403.     }
  404.       if (OUTPUT_BEING_FLUSHED (tiop))
  405.     {
  406. #if defined (FLUSHO) && defined (_AIX41)
  407.       rltty_warning ("turning off output flushing");
  408.       tiop->c_lflag &= ~FLUSHO;
  409.       break;
  410. #else
  411.       continue;
  412. #endif
  413.     }
  414.       break;
  415.     }
  416.  
  417. #if defined (_AIX)
  418.   setopost(tiop);
  419. #endif
  420.  
  421.   return 0;
  422. }
  423.  
  424. static int
  425. set_tty_settings (tty, tiop)
  426.      int tty;
  427.      TIOTYPE *tiop;
  428. {
  429.   while (SETATTR (tty, tiop) < 0)
  430.     {
  431.       if (errno != EINTR)
  432.     return -1;
  433.       errno = 0;
  434.     }
  435.  
  436. #if 0
  437.  
  438. #if defined (TERMIOS_TTY_DRIVER)
  439. #  if defined (__ksr1__)
  440.   if (ksrflow)
  441.     {
  442.       ksrflow = 0;
  443.       tcflow (tty, TCOON);
  444.     }
  445. #  else /* !ksr1 */
  446.   tcflow (tty, TCOON);        /* Simulate a ^Q. */
  447. #  endif /* !ksr1 */
  448. #else
  449.   ioctl (tty, TCXONC, 1);    /* Simulate a ^Q. */
  450. #endif /* !TERMIOS_TTY_DRIVER */
  451.  
  452. #endif
  453.  
  454.   return 0;
  455. }
  456.  
  457. static void
  458. prepare_terminal_settings (meta_flag, otio, tiop)
  459.      int meta_flag;
  460.      TIOTYPE otio, *tiop;
  461. {
  462.   readline_echoing_p = (otio.c_lflag & ECHO);
  463.  
  464.   tiop->c_lflag &= ~(ICANON | ECHO);
  465.  
  466.   if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
  467.     _rl_eof_char = otio.c_cc[VEOF];
  468.  
  469. #if defined (USE_XON_XOFF)
  470. #if defined (IXANY)
  471.   tiop->c_iflag &= ~(IXON | IXOFF | IXANY);
  472. #else
  473.   /* `strict' Posix systems do not define IXANY. */
  474.   tiop->c_iflag &= ~(IXON | IXOFF);
  475. #endif /* IXANY */
  476. #endif /* USE_XON_XOFF */
  477.  
  478.   /* Only turn this off if we are using all 8 bits. */
  479.   if (((tiop->c_cflag & CSIZE) == CS8) || meta_flag)
  480.     tiop->c_iflag &= ~(ISTRIP | INPCK);
  481.  
  482.   /* Make sure we differentiate between CR and NL on input. */
  483.   tiop->c_iflag &= ~(ICRNL | INLCR);
  484.  
  485. #if !defined (HANDLE_SIGNALS)
  486.   tiop->c_lflag &= ~ISIG;
  487. #else
  488.   tiop->c_lflag |= ISIG;
  489. #endif
  490.  
  491.   tiop->c_cc[VMIN] = 1;
  492.   tiop->c_cc[VTIME] = 0;
  493.  
  494. #if defined (FLUSHO)
  495.   if (OUTPUT_BEING_FLUSHED (tiop))
  496.     {
  497.       tiop->c_lflag &= ~FLUSHO;
  498.       otio.c_lflag &= ~FLUSHO;
  499.     }
  500. #endif
  501.  
  502.   /* Turn off characters that we need on Posix systems with job control,
  503.      just to be sure.  This includes ^Y and ^V.  This should not really
  504.      be necessary.  */
  505. #if defined (TERMIOS_TTY_DRIVER) && defined (_POSIX_VDISABLE)
  506.  
  507. #if defined (VLNEXT)
  508.   tiop->c_cc[VLNEXT] = _POSIX_VDISABLE;
  509. #endif
  510.  
  511. #if defined (VDSUSP)
  512.   tiop->c_cc[VDSUSP] = _POSIX_VDISABLE;
  513. #endif
  514.  
  515. #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
  516. }
  517. #endif  /* NEW_TTY_DRIVER */
  518.  
  519. /* Put the terminal in CBREAK mode so that we can detect key presses. */
  520. void
  521. rl_prep_terminal (meta_flag)
  522.      int meta_flag;
  523. {
  524. #if !defined (__GO32__)
  525.   int tty;
  526.   TIOTYPE tio;
  527.  
  528.   if (terminal_prepped)
  529.     return;
  530.  
  531.   /* Try to keep this function from being INTerrupted. */
  532.   block_sigint ();
  533.  
  534.   tty = fileno (rl_instream);
  535.  
  536.   if (get_tty_settings (tty, &tio) < 0)
  537.     {
  538.       release_sigint ();
  539.       return;
  540.     }
  541.  
  542.   otio = tio;
  543.  
  544.   prepare_terminal_settings (meta_flag, otio, &tio);
  545.  
  546.   if (set_tty_settings (tty, &tio) < 0)
  547.     {
  548.       release_sigint ();
  549.       return;
  550.     }
  551.  
  552.   if (_rl_enable_keypad)
  553.     _rl_control_keypad (1);
  554.  
  555.   fflush (rl_outstream);
  556.   terminal_prepped = 1;
  557.  
  558.   release_sigint ();
  559. #endif /* !__GO32__ */
  560. }
  561.  
  562. /* Restore the terminal's normal settings and modes. */
  563. void
  564. rl_deprep_terminal ()
  565. {
  566. #if !defined (__GO32__)
  567.   int tty;
  568.  
  569.   if (!terminal_prepped)
  570.     return;
  571.  
  572.   /* Try to keep this function from being interrupted. */
  573.   block_sigint ();
  574.  
  575.   tty = fileno (rl_instream);
  576.  
  577.   if (_rl_enable_keypad)
  578.     _rl_control_keypad (0);
  579.  
  580.   fflush (rl_outstream);
  581.  
  582.   if (set_tty_settings (tty, &otio) < 0)
  583.     {
  584.       release_sigint ();
  585.       return;
  586.     }
  587.  
  588.   terminal_prepped = 0;
  589.  
  590.   release_sigint ();
  591. #endif /* !__GO32__ */
  592. }
  593.  
  594. /* **************************************************************** */
  595. /*                                    */
  596. /*            Bogus Flow Control                  */
  597. /*                                    */
  598. /* **************************************************************** */
  599.  
  600. int
  601. rl_restart_output (count, key)
  602.      int count, key;
  603. {
  604.   int fildes = fileno (rl_outstream);
  605. #if defined (TIOCSTART)
  606. #if defined (apollo)
  607.   ioctl (&fildes, TIOCSTART, 0);
  608. #else
  609.   ioctl (fildes, TIOCSTART, 0);
  610. #endif /* apollo */
  611.  
  612. #else /* !TIOCSTART */
  613. #  if defined (TERMIOS_TTY_DRIVER)
  614. #    if defined (__ksr1__)
  615.   if (ksrflow)
  616.     {
  617.       ksrflow = 0;
  618.       tcflow (fildes, TCOON);
  619.     }
  620. #    else /* !ksr1 */
  621.   tcflow (fildes, TCOON);        /* Simulate a ^Q. */
  622. #    endif /* !ksr1 */
  623. #  else /* !TERMIOS_TTY_DRIVER */
  624. #    if defined (TCXONC)
  625.   ioctl (fildes, TCXONC, TCOON);
  626. #    endif /* TCXONC */
  627. #  endif /* !TERMIOS_TTY_DRIVER */
  628. #endif /* !TIOCSTART */
  629.  
  630.   return 0;
  631. }
  632.  
  633. int
  634. rl_stop_output (count, key)
  635.      int count, key;
  636. {
  637.   int fildes = fileno (rl_instream);
  638.  
  639. #if defined (TIOCSTOP)
  640. # if defined (apollo)
  641.   ioctl (&fildes, TIOCSTOP, 0);
  642. # else
  643.   ioctl (fildes, TIOCSTOP, 0);
  644. # endif /* apollo */
  645. #else /* !TIOCSTOP */
  646. # if defined (TERMIOS_TTY_DRIVER)
  647. #  if defined (__ksr1__)
  648.   ksrflow = 1;
  649. #  endif /* ksr1 */
  650.   tcflow (fildes, TCOOFF);
  651. # else
  652. #   if defined (TCXONC)
  653.   ioctl (fildes, TCXONC, TCOON);
  654. #   endif /* TCXONC */
  655. # endif /* !TERMIOS_TTY_DRIVER */
  656. #endif /* !TIOCSTOP */
  657.  
  658.   return 0;
  659. }
  660.  
  661. /* **************************************************************** */
  662. /*                                    */
  663. /*            Default Key Bindings                */
  664. /*                                    */
  665. /* **************************************************************** */
  666. void
  667. rltty_set_default_bindings (kmap)
  668.      Keymap kmap;
  669. {
  670.   TIOTYPE ttybuff;
  671.   int tty = fileno (rl_instream);
  672.  
  673. #if defined (NEW_TTY_DRIVER)
  674.  
  675. #define SET_SPECIAL(sc, func) \
  676.   do \
  677.     { \
  678.       int ic; \
  679.       ic = sc; \
  680.       if (ic != -1 && kmap[ic].type == ISFUNC) \
  681.     kmap[ic].function = func; \
  682.     } \
  683.   while (0)
  684.  
  685.   if (get_tty_settings (tty, &ttybuff) == 0)
  686.     {
  687.       if (ttybuff.flags & SGTTY_SET)
  688.     {
  689.       SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
  690.       SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
  691.     }
  692.  
  693. #  if defined (TIOCGLTC)
  694.       if (ttybuff.flags & LTCHARS_SET)
  695.     {
  696.       SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
  697.       SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
  698.     }
  699. #  endif /* TIOCGLTC */
  700.     }
  701.  
  702. #else /* !NEW_TTY_DRIVER */
  703.  
  704. #define SET_SPECIAL(sc, func) \
  705.   do \
  706.     { \
  707.       unsigned char uc; \
  708.       uc = ttybuff.c_cc[sc]; \
  709.       if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
  710.     kmap[uc].function = func; \
  711.     } \
  712.   while (0)
  713.  
  714.   if (get_tty_settings (tty, &ttybuff) == 0)
  715.     {
  716.       SET_SPECIAL (VERASE, rl_rubout);
  717.       SET_SPECIAL (VKILL, rl_unix_line_discard);
  718.  
  719. #  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
  720.       SET_SPECIAL (VLNEXT, rl_quoted_insert);
  721. #  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
  722.  
  723. #  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
  724.       SET_SPECIAL (VWERASE, rl_unix_word_rubout);
  725. #  endif /* VWERASE && TERMIOS_TTY_DRIVER */
  726.     }
  727. #endif /* !NEW_TTY_DRIVER */
  728. }
  729.