rltty.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:16k
源码类别:

MySQL数据库

开发平台:

Visual C++

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