sim/
[deliverable/binutils-gdb.git] / readline / rltty.c
index 203056ed093a03fa8b426e8b2df91b8fd7019a2e..0cd5028e491220fdd027437f1222f5b719e926f8 100644 (file)
@@ -1,7 +1,7 @@
 /* rltty.c -- functions to prepare and restore the terminal for readline's
    use. */
 
-/* Copyright (C) 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
 
    This file is part of the GNU Readline Library, a library for
    reading lines of text with interactive input and history editing.
 extern int errno;
 #endif /* !errno */
 
-VFunction *rl_prep_term_function = rl_prep_terminal;
-VFunction *rl_deprep_term_function = rl_deprep_terminal;
+rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
+rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
+
+void _rl_block_sigint PARAMS((void));
+void _rl_release_sigint PARAMS((void));
+
+static void set_winsize PARAMS((int));
 
 /* **************************************************************** */
 /*                                                                 */
@@ -69,9 +74,9 @@ static int sigint_oldmask;
 static int sigint_blocked;
 
 /* Cause SIGINT to not be delivered until the corresponding call to
-   release_sigint(). */
-static void
-block_sigint ()
+   _rl_release_sigint(). */
+void
+_rl_block_sigint ()
 {
   if (sigint_blocked)
     return;
@@ -95,8 +100,8 @@ block_sigint ()
 }
 
 /* Allow SIGINT to be delivered. */
-static void
-release_sigint ()
+void
+_rl_release_sigint ()
 {
   if (sigint_blocked == 0)
     return;
@@ -147,7 +152,9 @@ set_winsize (tty)
 #endif /* TIOCGWINSZ */
 }
 
-#if defined (NEW_TTY_DRIVER)
+#if defined (NO_TTY_DRIVER)
+/* Nothing */
+#elif defined (NEW_TTY_DRIVER)
 
 /* Values for the `flags' field of a struct bsdtty.  This tells which
    elements of the struct bsdtty have been fetched from the system and
@@ -173,6 +180,16 @@ struct bsdtty {
 
 static TIOTYPE otio;
 
+static void save_tty_chars PARAMS((TIOTYPE *));
+static int _get_tty_settings PARAMS((int, TIOTYPE *));
+static int get_tty_settings PARAMS((int, TIOTYPE *));
+static int _set_tty_settings PARAMS((int, TIOTYPE *));
+static int set_tty_settings PARAMS((int, TIOTYPE *));
+
+static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
+
+static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
+
 static void
 save_tty_chars (tiop)
      TIOTYPE *tiop;
@@ -190,7 +207,7 @@ save_tty_chars (tiop)
       _rl_tty_chars.t_intr = tiop->tchars.t_intrc;
       _rl_tty_chars.t_quit = tiop->tchars.t_quitc;
       _rl_tty_chars.t_start = tiop->tchars.t_startc;
-      _rl_tty_chars.t_stop = tiop->tchars.t_stopc
+      _rl_tty_chars.t_stop = tiop->tchars.t_stopc;
       _rl_tty_chars.t_eof = tiop->tchars.t_eofc;
       _rl_tty_chars.t_eol = '\n';
       _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
@@ -214,28 +231,28 @@ get_tty_settings (tty, tiop)
      int tty;
      TIOTYPE *tiop;
 {
-#if defined (TIOCGWINSZ)
   set_winsize (tty);
-#endif
 
   tiop->flags = tiop->lflag = 0;
 
-  ioctl (tty, TIOCGETP, &(tiop->sgttyb));
+  errno = 0;
+  if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
+    return -1;
   tiop->flags |= SGTTY_SET;
 
 #if defined (TIOCLGET)
-  ioctl (tty, TIOCLGET, &(tiop->lflag));
-  tiop->flags |= LFLAG_SET;
+  if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
+    tiop->flags |= LFLAG_SET;
 #endif
 
 #if defined (TIOCGETC)
-  ioctl (tty, TIOCGETC, &(tiop->tchars));
-  tiop->flags |= TCHARS_SET;
+  if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
+    tiop->flags |= TCHARS_SET;
 #endif
 
 #if defined (TIOCGLTC)
-  ioctl (tty, TIOCGLTC, &(tiop->ltchars));
-  tiop->flags |= LTCHARS_SET;
+  if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
+    tiop->flags |= LTCHARS_SET;
 #endif
 
   return 0;
@@ -281,23 +298,23 @@ set_tty_settings (tty, tiop)
 }
 
 static void
-prepare_terminal_settings (meta_flag, otio, tiop)
+prepare_terminal_settings (meta_flag, oldtio, tiop)
      int meta_flag;
-     TIOTYPE otio, *tiop;
+     TIOTYPE oldtio, *tiop;
 {
-  readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
+  readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
 
   /* Copy the original settings to the structure we're going to use for
      our settings. */
-  tiop->sgttyb = otio.sgttyb;
-  tiop->lflag = otio.lflag;
+  tiop->sgttyb = oldtio.sgttyb;
+  tiop->lflag = oldtio.lflag;
 #if defined (TIOCGETC)
-  tiop->tchars = otio.tchars;
+  tiop->tchars = oldtio.tchars;
 #endif
 #if defined (TIOCGLTC)
-  tiop->ltchars = otio.ltchars;
+  tiop->ltchars = oldtio.ltchars;
 #endif
-  tiop->flags = otio.flags;
+  tiop->flags = oldtio.flags;
 
   /* First, the basic settings to put us into character-at-a-time, no-echo
      input mode. */
@@ -310,8 +327,8 @@ prepare_terminal_settings (meta_flag, otio, tiop)
 #if !defined (ANYP)
 #  define ANYP (EVENP | ODDP)
 #endif
-  if (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
-      ((otio.sgttyb.sg_flags & ANYP) == 0))
+  if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
+      ((oldtio.sgttyb.sg_flags & ANYP) == 0))
     {
       tiop->sgttyb.sg_flags |= ANYP;
 
@@ -330,13 +347,13 @@ prepare_terminal_settings (meta_flag, otio, tiop)
   tiop->tchars.t_startc = -1; /* C-q */
 
   /* If there is an XON character, bind it to restart the output. */
-  if (otio.tchars.t_startc != -1)
-    rl_bind_key (otio.tchars.t_startc, rl_restart_output);
+  if (oldtio.tchars.t_startc != -1)
+    rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
 #  endif /* USE_XON_XOFF */
 
   /* If there is an EOF char, bind _rl_eof_char to it. */
-  if (otio.tchars.t_eofc != -1)
-    _rl_eof_char = otio.tchars.t_eofc;
+  if (oldtio.tchars.t_eofc != -1)
+    _rl_eof_char = oldtio.tchars.t_eofc;
 
 #  if defined (NO_KILL_INTR)
   /* Get rid of terminal-generated SIGQUIT and SIGINT. */
@@ -375,11 +392,22 @@ prepare_terminal_settings (meta_flag, otio, tiop)
 #  define TIOTYPE struct termio
 #  define DRAIN_OUTPUT(fd)
 #  define GETATTR(tty, tiop)   (ioctl (tty, TCGETA, tiop))
-#  define SETATTR(tty, tiop)   (ioctl (tty, TCSETA, tiop))
+#  define SETATTR(tty, tiop)   (ioctl (tty, TCSETAW, tiop))
 #endif /* !TERMIOS_TTY_DRIVER */
 
 static TIOTYPE otio;
 
+static void save_tty_chars PARAMS((TIOTYPE *));
+static int _get_tty_settings PARAMS((int, TIOTYPE *));
+static int get_tty_settings PARAMS((int, TIOTYPE *));
+static int _set_tty_settings PARAMS((int, TIOTYPE *));
+static int set_tty_settings PARAMS((int, TIOTYPE *));
+
+static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
+
+static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
+static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
+
 #if defined (FLUSHO)
 #  define OUTPUT_BEING_FLUSHED(tp)  (tp->c_lflag & FLUSHO)
 #else
@@ -491,10 +519,9 @@ get_tty_settings (tty, tiop)
      int tty;
      TIOTYPE *tiop;
 {
-#if defined (TIOCGWINSZ)
   set_winsize (tty);
-#endif
 
+  errno = 0;
   if (_get_tty_settings (tty, tiop) < 0)
     return -1;
 
@@ -549,16 +576,16 @@ set_tty_settings (tty, tiop)
 }
 
 static void
-prepare_terminal_settings (meta_flag, otio, tiop)
+prepare_terminal_settings (meta_flag, oldtio, tiop)
      int meta_flag;
-     TIOTYPE otio, *tiop;
+     TIOTYPE oldtio, *tiop;
 {
-  readline_echoing_p = (otio.c_lflag & ECHO);
+  readline_echoing_p = (oldtio.c_lflag & ECHO);
 
   tiop->c_lflag &= ~(ICANON | ECHO);
 
-  if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
-    _rl_eof_char = otio.c_cc[VEOF];
+  if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
+    _rl_eof_char = oldtio.c_cc[VEOF];
 
 #if defined (USE_XON_XOFF)
 #if defined (IXANY)
@@ -589,7 +616,7 @@ prepare_terminal_settings (meta_flag, otio, tiop)
   if (OUTPUT_BEING_FLUSHED (tiop))
     {
       tiop->c_lflag &= ~FLUSHO;
-      otio.c_lflag &= ~FLUSHO;
+      oldtio.c_lflag &= ~FLUSHO;
     }
 #endif
 
@@ -608,9 +635,23 @@ prepare_terminal_settings (meta_flag, otio, tiop)
 
 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
 }
-#endif  /* NEW_TTY_DRIVER */
+#endif  /* !NEW_TTY_DRIVER */
 
 /* Put the terminal in CBREAK mode so that we can detect key presses. */
+#if defined (NO_TTY_DRIVER)
+void
+rl_prep_terminal (meta_flag)
+     int meta_flag;
+{
+  readline_echoing_p = 1;
+}
+
+void
+rl_deprep_terminal ()
+{
+}
+
+#else /* ! NO_TTY_DRIVER */
 void
 rl_prep_terminal (meta_flag)
      int meta_flag;
@@ -622,25 +663,55 @@ rl_prep_terminal (meta_flag)
     return;
 
   /* Try to keep this function from being INTerrupted. */
-  block_sigint ();
+  _rl_block_sigint ();
 
   tty = fileno (rl_instream);
 
   if (get_tty_settings (tty, &tio) < 0)
     {
-      release_sigint ();
+#if defined (ENOTSUP)
+      /* MacOS X, at least, lies about the value of errno if tcgetattr fails. */
+      if (errno == ENOTTY || errno == ENOTSUP)
+#else
+      if (errno == ENOTTY)
+#endif
+       readline_echoing_p = 1;         /* XXX */
+      _rl_release_sigint ();
       return;
     }
 
   otio = tio;
 
+  if (_rl_bind_stty_chars)
+    {
+#if defined (VI_MODE)
+      /* If editing in vi mode, make sure we restore the bindings in the
+        insertion keymap no matter what keymap we ended up in. */
+      if (rl_editing_mode == vi_mode)
+       rl_tty_unset_default_bindings (vi_insertion_keymap);
+      else
+#endif
+       rl_tty_unset_default_bindings (_rl_keymap);
+    }
   save_tty_chars (&otio);
+  RL_SETSTATE(RL_STATE_TTYCSAVED);
+  if (_rl_bind_stty_chars)
+    {
+#if defined (VI_MODE)
+      /* If editing in vi mode, make sure we set the bindings in the
+        insertion keymap no matter what keymap we ended up in. */
+      if (rl_editing_mode == vi_mode)
+       _rl_bind_tty_special_chars (vi_insertion_keymap, tio);  
+      else
+#endif
+       _rl_bind_tty_special_chars (_rl_keymap, tio);
+    }
 
   prepare_terminal_settings (meta_flag, otio, &tio);
 
   if (set_tty_settings (tty, &tio) < 0)
     {
-      release_sigint ();
+      _rl_release_sigint ();
       return;
     }
 
@@ -649,8 +720,9 @@ rl_prep_terminal (meta_flag)
 
   fflush (rl_outstream);
   terminal_prepped = 1;
+  RL_SETSTATE(RL_STATE_TERMPREPPED);
 
-  release_sigint ();
+  _rl_release_sigint ();
 }
 
 /* Restore the terminal's normal settings and modes. */
@@ -663,7 +735,7 @@ rl_deprep_terminal ()
     return;
 
   /* Try to keep this function from being interrupted. */
-  block_sigint ();
+  _rl_block_sigint ();
 
   tty = fileno (rl_instream);
 
@@ -674,14 +746,16 @@ rl_deprep_terminal ()
 
   if (set_tty_settings (tty, &otio) < 0)
     {
-      release_sigint ();
+      _rl_release_sigint ();
       return;
     }
 
   terminal_prepped = 0;
+  RL_UNSETSTATE(RL_STATE_TERMPREPPED);
 
-  release_sigint ();
+  _rl_release_sigint ();
 }
+#endif /* !NO_TTY_DRIVER */
 \f
 /* **************************************************************** */
 /*                                                                 */
@@ -693,6 +767,10 @@ int
 rl_restart_output (count, key)
      int count, key;
 {
+#if defined (__MINGW32__)
+  return 0;
+#else /* !__MING32__ */
+
   int fildes = fileno (rl_outstream);
 #if defined (TIOCSTART)
 #if defined (apollo)
@@ -720,12 +798,17 @@ rl_restart_output (count, key)
 #endif /* !TIOCSTART */
 
   return 0;
+#endif /* !__MINGW32__ */
 }
 
 int
 rl_stop_output (count, key)
      int count, key;
 {
+#if defined (__MINGW32__)
+  return 0;
+#else
+
   int fildes = fileno (rl_instream);
 
 #if defined (TIOCSTOP)
@@ -748,6 +831,7 @@ rl_stop_output (count, key)
 #endif /* !TIOCSTOP */
 
   return 0;
+#endif /* !__MINGW32__ */
 }
 
 /* **************************************************************** */
@@ -755,73 +839,145 @@ rl_stop_output (count, key)
 /*                     Default Key Bindings                        */
 /*                                                                 */
 /* **************************************************************** */
-void
-rltty_set_default_bindings (kmap)
+
+#if !defined (NO_TTY_DRIVER)
+#define SET_SPECIAL(sc, func)  set_special_char(kmap, &ttybuff, sc, func)
+#endif
+
+#if defined (NO_TTY_DRIVER)
+
+#define SET_SPECIAL(sc, func)
+#define RESET_SPECIAL(c)
+
+#elif defined (NEW_TTY_DRIVER)
+static void
+set_special_char (kmap, tiop, sc, func)
      Keymap kmap;
+     TIOTYPE *tiop;
+     int sc;
+     rl_command_func_t *func;
 {
-  TIOTYPE ttybuff;
-  int tty = fileno (rl_instream);
-
-#if defined (NEW_TTY_DRIVER)
+  if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
+    kmap[(unsigned char)sc].function = func;
+}
 
-#define SET_SPECIAL(sc, func) \
-  do \
-    { \
-      int ic; \
-      ic = sc; \
-      if (ic != -1 && kmap[ic].type == ISFUNC) \
-       kmap[ic].function = func; \
-    } \
-  while (0)
+#define RESET_SPECIAL(c) \
+  if (c != -1 && kmap[(unsigned char)c].type == ISFUNC)
+    kmap[(unsigned char)c].function = rl_insert;
 
-  if (get_tty_settings (tty, &ttybuff) == 0)
+static void
+_rl_bind_tty_special_chars (kmap, ttybuff)
+     Keymap kmap;
+     TIOTYPE ttybuff;
+{
+  if (ttybuff.flags & SGTTY_SET)
     {
-      if (ttybuff.flags & SGTTY_SET)
-       {
-         SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
-         SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
-       }
+      SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
+      SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
+    }
 
 #  if defined (TIOCGLTC)
-      if (ttybuff.flags & LTCHARS_SET)
-       {
-         SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
-         SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
-       }
-#  endif /* TIOCGLTC */
+  if (ttybuff.flags & LTCHARS_SET)
+    {
+      SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
+      SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
     }
+#  endif /* TIOCGLTC */
+}
 
 #else /* !NEW_TTY_DRIVER */
+static void
+set_special_char (kmap, tiop, sc, func)
+     Keymap kmap;
+     TIOTYPE *tiop;
+     int sc;
+     rl_command_func_t *func;
+{
+  unsigned char uc;
 
-#define SET_SPECIAL(sc, func) \
-  do \
-    { \
-      unsigned char uc; \
-      uc = ttybuff.c_cc[sc]; \
-      if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
-       kmap[uc].function = func; \
-    } \
-  while (0)
+  uc = tiop->c_cc[sc];
+  if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
+    kmap[uc].function = func;
+}
 
-  if (get_tty_settings (tty, &ttybuff) == 0)
-    {
-      SET_SPECIAL (VERASE, rl_rubout);
-      SET_SPECIAL (VKILL, rl_unix_line_discard);
+/* used later */
+#define RESET_SPECIAL(uc) \
+  if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
+    kmap[uc].function = rl_insert;
+
+static void
+_rl_bind_tty_special_chars (kmap, ttybuff)
+     Keymap kmap;
+     TIOTYPE ttybuff;
+{
+  SET_SPECIAL (VERASE, rl_rubout);
+  SET_SPECIAL (VKILL, rl_unix_line_discard);
 
 #  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
-      SET_SPECIAL (VLNEXT, rl_quoted_insert);
+  SET_SPECIAL (VLNEXT, rl_quoted_insert);
 #  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
 
 #  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
-      SET_SPECIAL (VWERASE, rl_unix_word_rubout);
+  SET_SPECIAL (VWERASE, rl_unix_word_rubout);
 #  endif /* VWERASE && TERMIOS_TTY_DRIVER */
-    }
+}
+
 #endif /* !NEW_TTY_DRIVER */
+
+/* Set the system's default editing characters to their readline equivalents
+   in KMAP.  Should be static, now that we have rl_tty_set_default_bindings. */
+void
+rltty_set_default_bindings (kmap)
+     Keymap kmap;
+{
+#if !defined (NO_TTY_DRIVER)
+  TIOTYPE ttybuff;
+  int tty;
+  static int called = 0;
+
+  tty = fileno (rl_instream);
+
+  if (get_tty_settings (tty, &ttybuff) == 0)
+    _rl_bind_tty_special_chars (kmap, ttybuff);
+#endif
+}
+
+/* New public way to set the system default editing chars to their readline
+   equivalents. */
+void
+rl_tty_set_default_bindings (kmap)
+     Keymap kmap;
+{
+  rltty_set_default_bindings (kmap);
+}
+
+/* Rebind all of the tty special chars that readline worries about back
+   to self-insert.  Call this before saving the current terminal special
+   chars with save_tty_chars().  This only works on POSIX termios or termio
+   systems. */
+void
+rl_tty_unset_default_bindings (kmap)
+     Keymap kmap;
+{
+  /* Don't bother before we've saved the tty special chars at least once. */
+  if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
+    return;
+
+  RESET_SPECIAL (_rl_tty_chars.t_erase);
+  RESET_SPECIAL (_rl_tty_chars.t_kill);
+
+#  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
+  RESET_SPECIAL (_rl_tty_chars.t_lnext);
+#  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
+
+#  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
+  RESET_SPECIAL (_rl_tty_chars.t_werase);
+#  endif /* VWERASE && TERMIOS_TTY_DRIVER */
 }
 
 #if defined (HANDLE_SIGNALS)
 
-#if defined (NEW_TTY_DRIVER)
+#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
 int
 _rl_disable_tty_signals ()
 {
@@ -850,6 +1006,7 @@ _rl_disable_tty_signals ()
   nosigstty = sigstty;
 
   nosigstty.c_lflag &= ~ISIG;
+  nosigstty.c_iflag &= ~IXON;
 
   if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
     return (_set_tty_settings (fileno (rl_instream), &sigstty));
@@ -861,10 +1018,17 @@ _rl_disable_tty_signals ()
 int
 _rl_restore_tty_signals ()
 {
+  int r;
+
   if (tty_sigs_disabled == 0)
     return 0;
 
-  return (_set_tty_settings (fileno (rl_instream), &sigstty));
+  r = _set_tty_settings (fileno (rl_instream), &sigstty);
+
+  if (r == 0)
+    tty_sigs_disabled = 0;
+
+  return r;
 }
 #endif /* !NEW_TTY_DRIVER */
 
This page took 0.032011 seconds and 4 git commands to generate.