[ dejagnu/ChangeLog ]
[deliverable/binutils-gdb.git] / readline / rltty.c
index c8a00fdf09240cdfad93800b8aa1e95f578d0e53..1d943639f1acadd87af66224dc035928e589c10a 100644 (file)
@@ -8,7 +8,7 @@
 
    The GNU Readline Library is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
-   as published by the Free Software Foundation; either version 1, or
+   as published by the Free Software Foundation; either version 2, or
    (at your option) any later version.
 
    The GNU Readline Library is distributed in the hope that it will be
    The GNU General Public License is often shipped with GNU software, and
    is generally kept in a file called COPYING or LICENSE.  If you do not
    have a copy of the license, write to the Free Software Foundation,
-   675 Mass Ave, Cambridge, MA 02139, USA. */
+   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+#  include <config.h>
+#endif
+
 #include <sys/types.h>
 #include <signal.h>
 #include <errno.h>
 #endif /* HAVE_UNISTD_H */
 
 #include "rldefs.h"
+
+#if defined (GWINSZ_IN_SYS_IOCTL)
+#  include <sys/ioctl.h>
+#endif /* GWINSZ_IN_SYS_IOCTL */
+
+#include "rltty.h"
 #include "readline.h"
+#include "rlprivate.h"
 
 #if !defined (errno)
 extern int errno;
 #endif /* !errno */
 
-extern int readline_echoing_p;
-extern int _rl_eof_char;
-
-#if defined (_GO32_)
-#  include <sys/pc.h>
-#  undef HANDLE_SIGNALS
-#endif /* _GO32_ */
+VFunction *rl_prep_term_function = rl_prep_terminal;
+VFunction *rl_deprep_term_function = rl_deprep_terminal;
 
 /* **************************************************************** */
 /*                                                                 */
@@ -58,7 +66,7 @@ static int sigint_oldmask;
 #  endif /* HAVE_BSD_SIGNALS */
 #endif /* !HAVE_POSIX_SIGNALS */
 
-static int sigint_blocked = 0;
+static int sigint_blocked;
 
 /* Cause SIGINT to not be delivered until the corresponding call to
    release_sigint(). */
@@ -82,6 +90,7 @@ block_sigint ()
 #    endif /* HAVE_USG_SIGHOLD */
 #  endif /* !HAVE_BSD_SIGNALS */
 #endif /* !HAVE_POSIX_SIGNALS */
+
   sigint_blocked = 1;
 }
 
@@ -89,7 +98,7 @@ block_sigint ()
 static void
 release_sigint ()
 {
-  if (!sigint_blocked)
+  if (sigint_blocked == 0)
     return;
 
 #if defined (HAVE_POSIX_SIGNALS)
@@ -106,38 +115,7 @@ release_sigint ()
 
   sigint_blocked = 0;
 }
-\f
-/* **************************************************************** */
-/*                                                                 */
-/*                   Controlling the Meta Key                      */
-/*                                                                 */
-/* **************************************************************** */
 
-extern int term_has_meta;
-extern char *term_mm;
-extern char *term_mo;
-
-static void
-outchar (c)
-     int c;
-{
-  putc (c, rl_outstream);
-}
-
-/* Turn on/off the meta key depending on ON. */
-static void
-control_meta_key (on)
-     int on;
-{
-  if (term_has_meta)
-    {
-      if (on && term_mm)
-       tputs (term_mm, 1, outchar);
-      else if (!on && term_mo)
-       tputs (term_mo, 1, outchar);
-    }
-}
-\f
 /* **************************************************************** */
 /*                                                                 */
 /*                   Saving and Restoring the TTY                  */
@@ -145,13 +123,30 @@ control_meta_key (on)
 /* **************************************************************** */
 
 /* Non-zero means that the terminal is in a prepped state. */
-static int terminal_prepped = 0;
+static int terminal_prepped;
+
+static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
 
 /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
    and output is suspended. */
 #if defined (__ksr1__)
-static int ksrflow = 0;
+static int ksrflow;
 #endif
+
+/* Dummy call to force a backgrounded readline to stop before it tries
+   to get the tty settings. */
+static void
+set_winsize (tty)
+     int tty;
+{
+#if defined (TIOCGWINSZ)
+  struct winsize w;
+
+  if (ioctl (tty, TIOCGWINSZ, &w) == 0)
+      (void) ioctl (tty, TIOCSWINSZ, &w);
+#endif /* TIOCGWINSZ */
+}
+
 #if defined (NEW_TTY_DRIVER)
 
 /* Values for the `flags' field of a struct bsdtty.  This tells which
@@ -178,11 +173,51 @@ struct bsdtty {
 
 static TIOTYPE otio;
 
+static void
+save_tty_chars (tiop)
+     TIOTYPE *tiop;
+{
+  _rl_last_tty_chars = _rl_tty_chars;
+
+  if (tiop->flags & SGTTY_SET)
+    {
+      _rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
+      _rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
+    }
+
+  if (tiop->flags & TCHARS_SET)
+    {
+      _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_eof = tiop->tchars.t_eofc;
+      _rl_tty_chars.t_eol = '\n';
+      _rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
+    }
+
+  if (tiop->flags & LTCHARS_SET)
+    {
+      _rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
+      _rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
+      _rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
+      _rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
+      _rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
+      _rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
+    }
+
+  _rl_tty_chars.t_status = -1;
+}
+
 static int
 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));
@@ -206,6 +241,7 @@ get_tty_settings (tty, tiop)
   return 0;
 }
 
+static int
 set_tty_settings (tty, tiop)
      int tty;
      TIOTYPE *tiop;
@@ -249,7 +285,6 @@ prepare_terminal_settings (meta_flag, otio, tiop)
      int meta_flag;
      TIOTYPE otio, *tiop;
 {
-#if !defined (_GO32_)
   readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
 
   /* Copy the original settings to the structure we're going to use for
@@ -315,11 +350,9 @@ prepare_terminal_settings (meta_flag, otio, tiop)
   tiop->ltchars.t_dsuspc = -1; /* C-y */
   tiop->ltchars.t_lnextc = -1; /* C-v */
 #endif /* TIOCGLTC */
-#endif /* !_GO32_ */
 }
-#endif /* defined (NEW_TTY_DRIVER) */
 
-#if !defined (NEW_TTY_DRIVER) && !defined(_GO32_)
+#else  /* !defined (NEW_TTY_DRIVER) */
 
 #if !defined (VMIN)
 #  define VMIN VEOF
@@ -333,7 +366,11 @@ prepare_terminal_settings (meta_flag, otio, tiop)
 #  define TIOTYPE struct termios
 #  define DRAIN_OUTPUT(fd)     tcdrain (fd)
 #  define GETATTR(tty, tiop)   (tcgetattr (tty, tiop))
-#  define SETATTR(tty, tiop)   (tcsetattr (tty, TCSANOW, tiop))
+#  ifdef M_UNIX
+#    define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
+#  else
+#    define SETATTR(tty, tiop) (tcsetattr (tty, TCSADRAIN, tiop))
+#  endif /* !M_UNIX */
 #else
 #  define TIOTYPE struct termio
 #  define DRAIN_OUTPUT(fd)
@@ -343,22 +380,133 @@ prepare_terminal_settings (meta_flag, otio, tiop)
 
 static TIOTYPE otio;
 
+#if defined (FLUSHO)
+#  define OUTPUT_BEING_FLUSHED(tp)  (tp->c_lflag & FLUSHO)
+#else
+#  define OUTPUT_BEING_FLUSHED(tp)  0
+#endif
+
+static void
+save_tty_chars (tiop)
+     TIOTYPE *tiop;
+{
+  _rl_last_tty_chars = _rl_tty_chars;
+
+  _rl_tty_chars.t_eof = tiop->c_cc[VEOF];
+  _rl_tty_chars.t_eol = tiop->c_cc[VEOL];
+#ifdef VEOL2
+  _rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
+#endif
+  _rl_tty_chars.t_erase = tiop->c_cc[VERASE];
+#ifdef VWERASE
+  _rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
+#endif
+  _rl_tty_chars.t_kill = tiop->c_cc[VKILL];
+#ifdef VREPRINT
+  _rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
+#endif
+  _rl_tty_chars.t_intr = tiop->c_cc[VINTR];
+  _rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
+#ifdef VSUSP
+  _rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
+#endif
+#ifdef VDSUSP
+  _rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
+#endif
+#ifdef VSTART
+  _rl_tty_chars.t_start = tiop->c_cc[VSTART];
+#endif
+#ifdef VSTOP
+  _rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
+#endif
+#ifdef VLNEXT
+  _rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
+#endif
+#ifdef VDISCARD
+  _rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
+#endif
+#ifdef VSTATUS
+  _rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
+#endif
+}
+
+#if defined (_AIX) || defined (_AIX41)
+/* Currently this is only used on AIX */
+static void
+rltty_warning (msg)
+     char *msg;
+{
+  fprintf (stderr, "readline: warning: %s\n", msg);
+}
+#endif
+
+#if defined (_AIX)
+void
+setopost(tp)
+TIOTYPE *tp;
+{
+  if ((tp->c_oflag & OPOST) == 0)
+    {
+      rltty_warning ("turning on OPOST for terminal\r");
+      tp->c_oflag |= OPOST|ONLCR;
+    }
+}
+#endif
+
 static int
-get_tty_settings (tty, tiop)
+_get_tty_settings (tty, tiop)
      int tty;
      TIOTYPE *tiop;
 {
-  while (GETATTR (tty, tiop) < 0)
+  int ioctl_ret;
+
+  while (1)
     {
-      if (errno != EINTR)
-       return -1;
-      errno = 0;
+      ioctl_ret = GETATTR (tty, tiop);
+      if (ioctl_ret < 0)
+       {
+         if (errno != EINTR)
+           return -1;
+         else
+           continue;
+       }
+      if (OUTPUT_BEING_FLUSHED (tiop))
+       {
+#if defined (FLUSHO) && defined (_AIX41)
+         rltty_warning ("turning off output flushing");
+         tiop->c_lflag &= ~FLUSHO;
+         break;
+#else
+         continue;
+#endif
+       }
+      break;
     }
+
   return 0;
 }
 
 static int
-set_tty_settings (tty, tiop)
+get_tty_settings (tty, tiop)
+     int tty;
+     TIOTYPE *tiop;
+{
+#if defined (TIOCGWINSZ)
+  set_winsize (tty);
+#endif
+
+  if (_get_tty_settings (tty, tiop) < 0)
+    return -1;
+
+#if defined (_AIX)
+  setopost(tiop);
+#endif
+
+  return 0;
+}
+
+static int
+_set_tty_settings (tty, tiop)
      int tty;
      TIOTYPE *tiop;
 {
@@ -368,7 +516,17 @@ set_tty_settings (tty, tiop)
        return -1;
       errno = 0;
     }
+  return 0;
+}
 
+static int
+set_tty_settings (tty, tiop)
+     int tty;
+     TIOTYPE *tiop;
+{
+  if (_set_tty_settings (tty, tiop) < 0)
+    return -1;
+    
 #if 0
 
 #if defined (TERMIOS_TTY_DRIVER)
@@ -385,7 +543,7 @@ set_tty_settings (tty, tiop)
   ioctl (tty, TCXONC, 1);      /* Simulate a ^Q. */
 #endif /* !TERMIOS_TTY_DRIVER */
 
-#endif
+#endif /* 0 */
 
   return 0;
 }
@@ -427,6 +585,14 @@ prepare_terminal_settings (meta_flag, otio, tiop)
   tiop->c_cc[VMIN] = 1;
   tiop->c_cc[VTIME] = 0;
 
+#if defined (FLUSHO)
+  if (OUTPUT_BEING_FLUSHED (tiop))
+    {
+      tiop->c_lflag &= ~FLUSHO;
+      otio.c_lflag &= ~FLUSHO;
+    }
+#endif
+
   /* Turn off characters that we need on Posix systems with job control,
      just to be sure.  This includes ^Y and ^V.  This should not really
      be necessary.  */
@@ -442,15 +608,14 @@ prepare_terminal_settings (meta_flag, otio, tiop)
 
 #endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
 }
-#endif /* !defined (NEW_TTY_DRIVER) && !defined(_GO32_) */
+#endif  /* NEW_TTY_DRIVER */
 
 /* Put the terminal in CBREAK mode so that we can detect key presses. */
 void
 rl_prep_terminal (meta_flag)
      int meta_flag;
 {
-#if !defined (_GO32_)
-  int tty = fileno (rl_instream);
+  int tty;
   TIOTYPE tio;
 
   if (terminal_prepped)
@@ -459,6 +624,8 @@ rl_prep_terminal (meta_flag)
   /* Try to keep this function from being INTerrupted. */
   block_sigint ();
 
+  tty = fileno (rl_instream);
+
   if (get_tty_settings (tty, &tio) < 0)
     {
       release_sigint ();
@@ -467,6 +634,8 @@ rl_prep_terminal (meta_flag)
 
   otio = tio;
 
+  save_tty_chars (&otio);
+
   prepare_terminal_settings (meta_flag, otio, &tio);
 
   if (set_tty_settings (tty, &tio) < 0)
@@ -475,37 +644,43 @@ rl_prep_terminal (meta_flag)
       return;
     }
 
-  control_meta_key (1);
+  if (_rl_enable_keypad)
+    _rl_control_keypad (1);
+
+  fflush (rl_outstream);
   terminal_prepped = 1;
 
   release_sigint ();
-#endif /* !_GO32_ */
 }
 
 /* Restore the terminal's normal settings and modes. */
 void
 rl_deprep_terminal ()
 {
-#if !defined (_GO32_)
-  int tty = fileno (rl_instream);
+  int tty;
 
   if (!terminal_prepped)
     return;
 
-  /* Try to keep this function from being INTerrupted. */
+  /* Try to keep this function from being interrupted. */
   block_sigint ();
 
+  tty = fileno (rl_instream);
+
+  if (_rl_enable_keypad)
+    _rl_control_keypad (0);
+
+  fflush (rl_outstream);
+
   if (set_tty_settings (tty, &otio) < 0)
     {
       release_sigint ();
       return;
     }
 
-  control_meta_key (0);
   terminal_prepped = 0;
 
   release_sigint ();
-#endif /* !_GO32_ */
 }
 \f
 /* **************************************************************** */
@@ -514,6 +689,7 @@ rl_deprep_terminal ()
 /*                                                                 */
 /* **************************************************************** */
 
+int
 rl_restart_output (count, key)
      int count, key;
 {
@@ -542,8 +718,11 @@ rl_restart_output (count, key)
 #    endif /* TCXONC */
 #  endif /* !TERMIOS_TTY_DRIVER */
 #endif /* !TIOCSTART */
+
+  return 0;
 }
 
+int
 rl_stop_output (count, key)
      int count, key;
 {
@@ -567,8 +746,10 @@ rl_stop_output (count, key)
 #   endif /* TCXONC */
 # endif /* !TERMIOS_TTY_DRIVER */
 #endif /* !TIOCSTOP */
+
+  return 0;
 }
-\f
+
 /* **************************************************************** */
 /*                                                                 */
 /*                     Default Key Bindings                        */
@@ -583,80 +764,108 @@ rltty_set_default_bindings (kmap)
 
 #if defined (NEW_TTY_DRIVER)
 
+#define SET_SPECIAL(sc, func) \
+  do \
+    { \
+      int ic; \
+      ic = sc; \
+      if (ic != -1 && kmap[ic].type == ISFUNC) \
+       kmap[ic].function = func; \
+    } \
+  while (0)
+
   if (get_tty_settings (tty, &ttybuff) == 0)
     {
       if (ttybuff.flags & SGTTY_SET)
        {
-         int erase, kill;
-
-         erase = ttybuff.sgttyb.sg_erase;
-         kill  = ttybuff.sgttyb.sg_kill;
-
-         if (erase != -1 && kmap[erase].type == ISFUNC)
-           kmap[erase].function = rl_rubout;
-
-         if (kill != -1 && kmap[kill].type == ISFUNC)
-           kmap[kill].function = 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)
        {
-         int werase, nextc;
-
-         werase = ttybuff.ltchars.t_werasc;
-         nextc = ttybuff.ltchars.t_lnextc;
-
-         if (werase != -1 && kmap[werase].type == ISFUNC)
-           kmap[werase].function = rl_unix_word_rubout;
-
-         if (nextc != -1 && kmap[nextc].type == ISFUNC)
-           kmap[nextc].function = rl_quoted_insert;
+         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 */
 
+#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)
+
   if (get_tty_settings (tty, &ttybuff) == 0)
     {
-      unsigned char erase, kill;
+      SET_SPECIAL (VERASE, rl_rubout);
+      SET_SPECIAL (VKILL, rl_unix_line_discard);
 
-      erase = ttybuff.c_cc[VERASE];
-      kill = ttybuff.c_cc[VKILL];
+#  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
+      SET_SPECIAL (VLNEXT, rl_quoted_insert);
+#  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
 
-      if (erase != (unsigned char)_POSIX_VDISABLE &&
-         kmap[erase].type == ISFUNC)
-       kmap[erase].function = rl_rubout;
+#  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
+      SET_SPECIAL (VWERASE, rl_unix_word_rubout);
+#  endif /* VWERASE && TERMIOS_TTY_DRIVER */
+    }
+#endif /* !NEW_TTY_DRIVER */
+}
 
-      if (kill != (unsigned char)_POSIX_VDISABLE &&
-         kmap[kill].type == ISFUNC)
-       kmap[kill].function = rl_unix_line_discard;
+#if defined (HANDLE_SIGNALS)
 
-#  if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
-      {
-       unsigned char nextc;
+#if defined (NEW_TTY_DRIVER)
+int
+_rl_disable_tty_signals ()
+{
+  return 0;
+}
 
-       nextc = ttybuff.c_cc[VLNEXT];
+int
+_rl_restore_tty_signals ()
+{
+  return 0;
+}
+#else
 
-       if (nextc != (unsigned char)_POSIX_VDISABLE &&
-           kmap[nextc].type == ISFUNC)
-         kmap[nextc].function = rl_quoted_insert;
-      }
-#  endif /* VLNEXT && TERMIOS_TTY_DRIVER */
+static TIOTYPE sigstty, nosigstty;
+static int tty_sigs_disabled = 0;
 
-#  if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
-      {
-       unsigned char werase;
+int
+_rl_disable_tty_signals ()
+{
+  if (tty_sigs_disabled)
+    return 0;
 
-       werase = ttybuff.c_cc[VWERASE];
+  if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
+    return -1;
 
-       if (werase != (unsigned char)_POSIX_VDISABLE &&
-           kmap[werase].type == ISFUNC)
-         kmap[werase].function = rl_unix_word_rubout;
-      }
-#  endif /* VWERASE && TERMIOS_TTY_DRIVER */
-    }
-#endif /* !NEW_TTY_DRIVER */
+  nosigstty = sigstty;
+
+  nosigstty.c_lflag &= ~ISIG;
+
+  if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
+    return (_set_tty_settings (fileno (rl_instream), &sigstty));
+
+  tty_sigs_disabled = 1;
+  return 0;
 }
+
+int
+_rl_restore_tty_signals ()
+{
+  if (tty_sigs_disabled == 0)
+    return 0;
+
+  return (_set_tty_settings (fileno (rl_instream), &sigstty));
+}
+#endif /* !NEW_TTY_DRIVER */
+
+#endif /* HANDLE_SIGNALS */
This page took 0.033599 seconds and 4 git commands to generate.