]> git.ipfire.org Git - thirdparty/readline.git/commitdiff
commit readline-20210311 snapshot
authorChet Ramey <chet.ramey@case.edu>
Thu, 11 Mar 2021 23:44:09 +0000 (18:44 -0500)
committerChet Ramey <chet.ramey@case.edu>
Thu, 11 Mar 2021 23:44:09 +0000 (18:44 -0500)
36 files changed:
MANIFEST
callback.c
config.h.in
configure [changed mode: 0755->0644]
configure.ac
doc/hsuser.texi
doc/rltech.texi
doc/texi2dvi [changed mode: 0755->0644]
doc/texi2html [changed mode: 0755->0644]
doc/version.texi
examples/Makefile.in
examples/rl-test-timeout [new file with mode: 0644]
examples/rl-timeout.c [new file with mode: 0644]
examples/rlfe/configure [changed mode: 0755->0644]
histexpand.c
input.c
isearch.c
parens.c
posixtime.h [new file with mode: 0644]
readline.c
readline.h
rlprivate.h
rltty.c
signals.c
support/config.guess [changed mode: 0755->0644]
support/config.rpath [changed mode: 0755->0644]
support/config.sub [changed mode: 0755->0644]
support/install.sh [changed mode: 0755->0644]
support/mkdirs [changed mode: 0755->0644]
support/mkdist [changed mode: 0755->0644]
support/mkinstalldirs [changed mode: 0755->0644]
support/shlib-install [changed mode: 0755->0644]
support/shobj-conf
text.c
util.c
vi_mode.c

index ad49d6686b06400813a0b26f3bb16a1c75e858a8..5af8d0f8258ee7bd9959d97d9ca58e2e9e8ce5ab 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -32,6 +32,7 @@ posixdir.h    f
 posixjmp.h     f
 posixselect.h  f
 posixstat.h    f
+posixtime.h    f
 readline.h     f
 rlconf.h       f
 rldefs.h       f
@@ -121,6 +122,8 @@ examples/rlevent.c  f
 examples/rlkeymaps.c   f
 examples/rltest.c      f
 examples/rl-callbacktest.c     f
+examples/rl-timeout.c  f
+examples/rl-test-timeout       f
 examples/rl.c          f
 examples/rlptytest.c   f
 examples/rlversion.c   f
index a466cf9b6ef1a5712a00f8837e86c23c55165e34..cfff6502170fd7f0d90e5375380532feaaa8919b 100644 (file)
@@ -147,6 +147,14 @@ rl_callback_read_char (void)
       (*rl_redisplay_function) ();
       _rl_want_redisplay = 0;
       memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
+
+      /* If we longjmped because of a timeout, handle it here. */
+      if (RL_ISSTATE (RL_STATE_TIMEOUT))
+       {
+         RL_SETSTATE (RL_STATE_DONE);
+         rl_done = 1;
+       }
+
       CALLBACK_READ_RETURN ();
     }
 
@@ -278,7 +286,8 @@ rl_callback_read_char (void)
          rl_clear_signals ();
 #endif
          in_handler = 0;
-         (*rl_linefunc) (line);
+         if (rl_linefunc)                      /* just in case */
+           (*rl_linefunc) (line);
 
          /* If the user did not clear out the line, do it for him. */
          if (rl_line_buffer[0])
index 6de47b5874396c2e79acd2080c3d30110898408d..bc6753f8029042c54e13bc8b9c44008798239f46 100644 (file)
@@ -58,6 +58,9 @@
 /* Define if you have the getpwuid function. */
 #undef HAVE_GETPWUID
 
+/* Define if you have the gettimeofday function. */
+#undef HAVE_GETTIMEOFDAY
+
 /* Define if you have the isascii function. */
 #undef HAVE_ISASCII
 
 /* Define if you have the setenv function.  */
 #undef HAVE_SETENV
 
+/* Define if you have the setitimer function.  */
+#undef HAVE_SETITIMER
+
 /* Define if you have the setlocale function. */
 #undef HAVE_SETLOCALE
 
 /* Define if you have the strpbrk function.  */
 #undef HAVE_STRPBRK
 
+/* Define if you have the sysconf function.  */
+#undef HAVE_SYSCONF
+
 /* Define if you have the tcgetattr function.  */
 #undef HAVE_TCGETATTR
 
 /* Define if you have the <sys/stream.h> header file.  */
 #undef HAVE_SYS_STREAM_H
 
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
 /* Define if you have the <termcap.h> header file.  */
 #undef HAVE_TERMCAP_H
 
 /* Define if you have <linux/audit.h> and it defines AUDIT_USER_TTY */
 #undef HAVE_DECL_AUDIT_USER_TTY
 
+#undef TIME_WITH_SYS_TIME
+
 /* Definitions pulled in from aclocal.m4. */
 #undef VOID_SIGHANDLER
 
 
 #undef HAVE_STRUCT_DIRENT_D_NAMLEN
 
+#undef HAVE_TIMEVAL
+
 #undef HAVE_BSD_SIGNALS
 
 #undef HAVE_POSIX_SIGNALS
old mode 100755 (executable)
new mode 100644 (file)
index 5a0bf2f..21deb8c
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.ac for Readline 8.1, version 2.90.
+# From configure.ac for Readline 8.1, version 2.91.
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.69 for readline 8.1.
 #
@@ -4793,8 +4793,43 @@ fi
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_time=yes
+else
+  ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
 
-for ac_func in fcntl kill lstat readlink
+for ac_func in fcntl gettimeofday kill lstat pselect readlink select setitimer
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -4806,8 +4841,8 @@ _ACEOF
 fi
 done
 
-for ac_func in fnmatch memmove pselect putenv select setenv setlocale \
-               strcasecmp strpbrk tcgetattr vsnprintf
+for ac_func in fnmatch memmove putenv setenv setlocale \
+               strcasecmp strpbrk sysconf tcgetattr vsnprintf
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -4994,7 +5029,8 @@ fi
 
 done
 
-for ac_header in sys/ioctl.h sys/pte.h sys/stream.h sys/select.h sys/file.h
+for ac_header in sys/ioctl.h sys/pte.h sys/stream.h sys/select.h \
+               sys/time.h sys/file.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -6086,6 +6122,43 @@ $as_echo "#define HAVE_STRUCT_DIRENT_D_FILENO 1" >>confdefs.h
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct timeval in sys/time.h and time.h" >&5
+$as_echo_n "checking for struct timeval in sys/time.h and time.h... " >&6; }
+if ${bash_cv_struct_timeval+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if HAVE_SYS_TIME_H
+                 #include <sys/time.h>
+                 #endif
+                 #include <time.h>
+
+int
+main ()
+{
+static struct timeval x; x.tv_sec = x.tv_usec;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  bash_cv_struct_timeval=yes
+else
+  bash_cv_struct_timeval=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bash_cv_struct_timeval" >&5
+$as_echo "$bash_cv_struct_timeval" >&6; }
+if test $bash_cv_struct_timeval = yes; then
+  $as_echo "#define HAVE_TIMEVAL 1" >>confdefs.h
+
+fi
+
 
 for ac_header in libaudit.h
 do :
index 147bae577334826ae6d32038b89dccd28043dee8..93d9a9a99ebb2e1205f05b0484750f8a13e471a8 100644 (file)
@@ -20,7 +20,7 @@ dnl Process this file with autoconf to produce a configure script.
 #   You should have received a copy of the GNU General Public License
 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-AC_REVISION([for Readline 8.1, version 2.90])
+AC_REVISION([for Readline 8.1, version 2.91])
 
 AC_INIT(readline, 8.1, bug-readline@gnu.org)
 
@@ -145,10 +145,11 @@ AC_HEADER_STDC
 
 AC_HEADER_STAT
 AC_HEADER_DIRENT
+AC_HEADER_TIME
 
-AC_CHECK_FUNCS(fcntl kill lstat readlink)
-AC_CHECK_FUNCS(fnmatch memmove pselect putenv select setenv setlocale \
-               strcasecmp strpbrk tcgetattr vsnprintf)
+AC_CHECK_FUNCS(fcntl gettimeofday kill lstat pselect readlink select setitimer)
+AC_CHECK_FUNCS(fnmatch memmove putenv setenv setlocale \
+               strcasecmp strpbrk sysconf tcgetattr vsnprintf)
 AC_CHECK_FUNCS(isascii isxdigit)
 AC_CHECK_FUNCS(getpwent getpwnam getpwuid)
 
@@ -158,7 +159,8 @@ AC_FUNC_STRCOLL
 AC_CHECK_HEADERS(fcntl.h unistd.h stdlib.h varargs.h stdarg.h stdbool.h \
                string.h strings.h \
                limits.h locale.h pwd.h memory.h termcap.h termios.h termio.h)
-AC_CHECK_HEADERS(sys/ioctl.h sys/pte.h sys/stream.h sys/select.h sys/file.h)
+AC_CHECK_HEADERS(sys/ioctl.h sys/pte.h sys/stream.h sys/select.h \
+               sys/time.h sys/file.h)
 
 AC_CHECK_HEADERS(sys/ptem.h,,,
 [[
@@ -190,6 +192,7 @@ BASH_CHECK_SPEED_T
 BASH_STRUCT_WINSIZE
 BASH_STRUCT_DIRENT_D_INO
 BASH_STRUCT_DIRENT_D_FILENO
+BASH_STRUCT_TIMEVAL
 
 AC_CHECK_HEADERS(libaudit.h)
 AC_CHECK_DECLS([AUDIT_USER_TTY],,, [[#include <linux/audit.h>]])
index b8fedf331f10a9577cf195a95c69ce7c6b089fbb..0a81c46e932f1821187948487064a8fe343d742a 100644 (file)
@@ -214,8 +214,9 @@ end of the history, and an index of @samp{-1} refers to the current
 @code{history -d} command.
 
 @item -d @var{start}-@var{end}
-Delete the history entries between positions @var{start} and @var{end},
-inclusive.  Positive and negative values for @var{start} and @var{end}
+Delete the range of history entries between positions @var{start} and
+@var{end}, inclusive.
+Positive and negative values for @var{start} and @var{end}
 are interpreted as described above.
 
 @item -a
@@ -250,6 +251,11 @@ used, if @var{filename}
 is given, then it is used as the history file.  If not, then
 the value of the @env{HISTFILE} variable is used.
 
+The return value is 0 unless an invalid option is encountered, an
+error occurs while reading or writing the history file, an invalid
+@var{offset} or range is supplied as an argument to @option{-d}, or the
+history expansion supplied as an argument to @option{-p} fails.
+
 @end table
 @end ifset
 
index bbf57c239c92fad7286aa15ee3508ca08fc277b3..a440225668d961f9c4d6961c7ee998e1575f68b6 100644 (file)
@@ -455,6 +455,11 @@ If non-zero, this is the address of a function to call if a read system
 call is interrupted when Readline is reading terminal input.
 @end deftypevar
 
+@deftypevar {rl_hook_func_t *} rl_timeout_event_hook
+If non-zero, this is the address of a function to call if Readline times
+out while reading input.
+@end deftypevar
+
 @deftypevar {rl_hook_func_t *} rl_input_available_hook
 If non-zero, Readline will use this function's return value when it needs
 to determine whether or not there is available input on the current input
@@ -588,6 +593,10 @@ the current call to @code{readline()}.
 @item RL_STATE_DONE
 Readline has read a key sequence bound to @code{accept-line}
 and is about to return the line to the caller.
+@item RL_STATE_TIMEOUT
+Readline has timed out (it did not receive a line or specified number of
+characters before the timeout duration specified by @code{rl_set_timeout}
+elapsed) and is returning that status to the caller.
 @end table
 
 @end deftypevar
@@ -1151,6 +1160,27 @@ The default waiting period is one-tenth of a second.
 Returns the old timeout value.
 @end deftypefun
 
+@deftypefun int rl_set_timeout (unsigned int secs, unsigned int usecs)
+Set a timeout for subsequent calls to @code{readline()}. If Readline does
+not read a complete line, or the number of characters specified by
+@code{rl_num_chars_to_read}, before the duration specfied by @var{secs}
+(in seconds) and @var{usecs} (microseconds), it returns and sets
+@code{RL_STATE_TIMEOUT} in @code{rl_readline_state}.
+Passing 0 for @code{secs} and @code{usecs} cancels any previously set
+timeout; the convenience macro @code{rl_clear_timeout()} is shorthand
+for this.
+Returns 0 if the timeout is set successfully.
+@end deftypefun
+
+@deftypefun int rl_timeout_remaining (unsigned int *secs, unsigned int *usecs)
+Return the number of seconds and microseconds remaining in the current
+timeout duration in @code{*secs} and @code{*usecs}, respectively.
+Returns -1 on error or when there is no timeout set, 0 when the timeout has
+expired (leaving @code{*secs} and @code{*usecs} unchanged), and 1 if the
+timeout has not expired. If @code{secs} and @code{usecs} are @code{NULL},
+the return value indicates whether the timeout has expired.
+@end deftypefun
+
 @node Terminal Management
 @subsection Terminal Management
 
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index abb9cb6ba573493530f878612d271b4c80848fce..a935f8353f21ae51e1dec62552094a7c0bef32ad 100644 (file)
@@ -1,10 +1,10 @@
 @ignore
-Copyright (C) 1988-2020 Free Software Foundation, Inc. 
+Copyright (C) 1988-2021 Free Software Foundation, Inc. 
 @end ignore
 
 @set EDITION 8.1
 @set VERSION 8.1
-@set UPDATED 29 October 2020
-@set UPDATED-MONTH October 2020
+@set UPDATED 10 March 2021
+@set UPDATED-MONTH March 2021
 
-@set LASTCHANGE Thu Oct 29 16:49:01 EDT 2020
+@set LASTCHANGE Wed Mar 10 15:43:49 EST 2021
index 4a7c39e0a4fb306dd2b1e3f1c10fc080183fd885..291c6b7adf8256de95e0ab47a806c199bd284cc3 100644 (file)
@@ -72,17 +72,17 @@ TERMCAP_LIB = @TERMCAP_LIB@
 SOURCES = excallback.c fileman.c histexamp.c manexamp.c rl-fgets.c rl.c \
                rlbasic.c rlcat.c rlevent.c rlptytest.c rltest.c rlversion.c \
                rltest2.c rl-callbacktest.c hist_erasedups.c hist_purgecmd.c \
-               rlkeymaps.c
+               rlkeymaps.c rl-timeout.c
 
 EXECUTABLES = fileman$(EXEEXT) rltest$(EXEEXT) rl$(EXEEXT) rlcat$(EXEEXT) \
                rlevent$(EXEEXT) rlversion$(EXEEXT) histexamp$(EXEEXT) \
                rl-callbacktest$(EXEEXT) rlbasic$(EXEEXT) \
                hist_erasedups$(EXEEXT) hist_purgecmd$(EXEEXT) \
-               rlkeymaps$(EXEEXT)
+               rlkeymaps$(EXEEXT) rl-timeout$(EXEEXT)
 
 OBJECTS = fileman.o rltest.o rl.o rlevent.o rlcat.o rlversion.o histexamp.o \
          rltest2.o rl-callbacktest.o rlbasic.o hist_erasedups.o hist_purgecmd.o \
-         rlkeymaps.o
+         rlkeymaps.o rl-timeout.o
 
 OTHEREXE = rlptytest$(EXEEXT)
 OTHEROBJ = rlptytest.o
@@ -141,6 +141,9 @@ rl-callbacktest$(EXEEXT): rl-callbacktest.o $(READLINE_LIB)
 rlptytest$(EXEEXT): rlptytest.o $(READLINE_LIB)
        $(CC) $(LDFLAGS) -o $@ rlptytest.o $(READLINE_LIB) $(TERMCAP_LIB) $(LIBUTIL)
 
+rl-timeout$(EXEEXT): rl-timeout.o $(READLINE_LIB)
+       $(CC) $(LDFLAGS) -o $@ rl-timeout.o $(READLINE_LIB) $(TERMCAP_LIB)
+
 rlversion$(EXEEXT): rlversion.o $(READLINE_LIB)
        $(CC) $(LDFLAGS) -o $@ rlversion.o $(READLINE_LIB) $(TERMCAP_LIB)
 
@@ -173,6 +176,7 @@ rlkeymaps.o: rlkeymaps.c
 rlcat.o: rlcat.c
 rlptytest.o: rlptytest.c
 rl-callbacktest.o: rl-callbacktest.c
+rl-timeout.o: rl-timeout.c
 
 fileman.o: $(top_srcdir)/readline.h
 rltest.o: $(top_srcdir)/readline.h
@@ -186,3 +190,4 @@ rlbasic.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
 rlcat.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
 rlptytest.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
 rl-callbacktest.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
+rl-timeout.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
diff --git a/examples/rl-test-timeout b/examples/rl-test-timeout
new file mode 100644 (file)
index 0000000..2c9de1a
--- /dev/null
@@ -0,0 +1,6 @@
+./rl-timeout readline1 0.5
+./rl-timeout readline2 0.25
+
+./rl-timeout callback1 0.5
+./rl-timeout callback2 0.5
+
diff --git a/examples/rl-timeout.c b/examples/rl-timeout.c
new file mode 100644 (file)
index 0000000..b8a24ba
--- /dev/null
@@ -0,0 +1,245 @@
+/* rl-timeout: test various readline builtin timeouts. */
+
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+   This file is part of the GNU Readline Library (Readline), a library for
+   reading lines of text with interactive input and history editing.
+
+   Readline 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 3 of the License, or
+   (at your option) any later version.
+
+   Readline is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with readline.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Standard include files. stdio.h is required. */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+
+/* Used for select(2) */
+#include <sys/types.h>
+#include <sys/select.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+/* Standard readline include files. */
+#if defined (READLINE_LIBRARY)
+#  include "readline.h"
+#  include "history.h"
+#else
+#  include <readline/readline.h>
+#  include <readline/history.h>
+#endif
+
+extern int errno;
+
+static void cb_linehandler (char *);
+
+int timeout_secs = 1, timeout_usecs = 0;
+int running;
+const char *prompt = "rl-timeout$ ";
+
+/* **************************************************************** */
+/*                                                                 */
+/* Example 1: readline () with rl_readline_state                   */
+/*                                                                 */
+/* **************************************************************** */
+
+void
+rltest_timeout_readline1 ()
+{
+  const char *temp;
+
+  rl_set_timeout (timeout_secs, timeout_usecs);
+  temp = readline (prompt);
+  if (RL_ISSTATE (RL_STATE_TIMEOUT))
+    printf ("timeout\n");
+  else if (temp == NULL)
+    printf ("no input line\n");
+  else
+    printf ("input line: %s\n", temp);
+  free ((void *) temp);
+}
+
+/* **************************************************************** */
+/*                                                                 */
+/* Example 2: readline () with rl_timeout_event_hook               */
+/*                                                                 */
+/* **************************************************************** */
+
+static int
+timeout_handler ()
+{
+  printf ("timeout\n");
+  return READERR;
+}
+
+void
+rltest_timeout_readline2 ()
+{
+  const char *temp;
+
+  rl_set_timeout (timeout_secs, timeout_usecs);
+  rl_timeout_event_hook = timeout_handler;
+  temp = readline (prompt);
+  if (temp == NULL)
+    printf ("no input line\n");
+  else
+    printf ("input line: %s\n", temp);
+  free ((void *)temp);
+}
+
+/* **************************************************************** */
+/*                                                                 */
+/* Example 3: rl_callback_* () with rl_timeout_remaining           */
+/*                                                                 */
+/* **************************************************************** */
+
+/* Callback function called for each line when accept-line executed, EOF
+   seen, or EOF character read.  This sets a flag and returns; it could
+   also call exit(3). */
+static void
+cb_linehandler (char *line)
+{
+  /* Can use ^D (stty eof) or `exit' to exit. */
+  if (line == NULL || strcmp (line, "exit") == 0)
+    {
+      if (line == 0)
+       printf ("\n");
+      printf ("exit\n");
+      /* This function needs to be called to reset the terminal settings,
+        and calling it from the line handler keeps one extra prompt from
+        being displayed. */
+      rl_callback_handler_remove ();
+
+      running = 0;
+    }
+  else
+    {
+      if (*line)
+       add_history (line);
+      printf ("input line: %s\n", line);
+      free (line);
+    }
+}
+
+void
+rltest_timeout_callback1 ()
+{
+  fd_set fds;
+  int r;
+  unsigned sec, usec;
+
+  rl_set_timeout (timeout_secs, timeout_usecs);
+  rl_callback_handler_install (prompt, cb_linehandler);
+  running = 1;
+  while (running)
+    {
+      FD_ZERO (&fds);
+      FD_SET (fileno (rl_instream), &fds);
+      r = rl_timeout_remaining (&sec, &usec);
+      if (r == 1)
+       {
+         struct timeval timeout = {sec, usec};
+         r = select (FD_SETSIZE, &fds, NULL, NULL, &timeout);
+       }
+      if (r < 0 && errno != EINTR)
+       {
+         perror ("rl-timeout: select");
+         rl_callback_handler_remove ();
+         break;
+       }
+      else if (r == 0)
+       {
+         printf ("rl-timeout: timeout\n");
+         rl_callback_handler_remove ();
+         break;
+       }
+
+      if (FD_ISSET (fileno (rl_instream), &fds))
+       rl_callback_read_char ();
+    }
+
+  printf ("rl-timeout: Event loop has exited\n");
+}
+
+/* **************************************************************** */
+/*                                                                 */
+/* Example 4: rl_callback_* () with rl_timeout_event_hook          */
+/*                                                                 */
+/* **************************************************************** */
+
+static int
+cb_timeouthandler ()
+{
+  printf ("timeout\n");
+  rl_callback_handler_remove ();
+  running = 0;
+  return READERR;
+}
+
+void
+rltest_timeout_callback2 ()
+{
+  int r;
+
+  rl_set_timeout (timeout_secs, timeout_usecs);
+  rl_timeout_event_hook = cb_timeouthandler;
+  rl_callback_handler_install (prompt, cb_linehandler);
+  running = 1;
+  while (running)
+    rl_callback_read_char ();
+
+  printf ("rl-timeout: Event loop has exited\n");
+}
+
+int
+main (int argc, char **argv)
+{
+  if (argc >= 2)
+    {
+      if (argc >= 3)
+       {
+         double timeout = atof (argv[2]);
+         if (timeout <= 0.0)
+           {
+             fprintf (stderr, "rl-timeout: specify a positive number for timeout.\n");
+             return 2;
+           }
+         else if (timeout > UINT_MAX)
+           {
+             fprintf (stderr, "rl-timeout: timeout too large.\n");
+             return 2;
+           }
+         timeout_secs = (unsigned) timeout;
+         timeout_usecs = (unsigned) ((timeout - timeout_secs) * 1000000 + 0.5);
+       }
+
+      if (strcmp (argv[1], "readline1") == 0)
+       rltest_timeout_readline1 ();
+      else if (strcmp (argv[1], "readline2") == 0)
+       rltest_timeout_readline2 ();
+      else if (strcmp (argv[1], "callback1") == 0)
+       rltest_timeout_callback1 ();
+      else if (strcmp (argv[1], "callback2") == 0)
+       rltest_timeout_callback2 ();
+      else
+       return 2;
+    }
+  else
+    {
+      fprintf (stderr, "usage: rl-timeout [readline1 | readline2 | callback1 | callback2] [timeout]\n");
+      return 2;
+    }
+  return 0;
+}
old mode 100755 (executable)
new mode 100644 (file)
index 34506da9d3df7e27cda697bc776c484dad292c35..8ab68091e64cd750c58d785f2aa1a05a061a3d9b 100644 (file)
@@ -1207,13 +1207,36 @@ history_expand (char *hstring, char **output)
             characters in history_no_expand_chars, then it is not a
             candidate for expansion of any kind. */
          if (cc == 0 || member (cc, history_no_expand_chars) ||
-                        (dquote && cc == '"') ||
-                        (history_inhibit_expansion_function && (*history_inhibit_expansion_function) (string, i)))
+                        (dquote && cc == '"'))
            {
              ADD_CHAR (string[i]);
              break;
            }
 
+         /* If the application has defined a function to determine whether
+            or not a history expansion should be performed, call it here. */
+         /* We check against what we've expanded so far, with the current
+            expansion appended, because that seems to be what csh does. We
+            decide to expand based on what we have to this point, not what
+            we started with. */
+         if (history_inhibit_expansion_function)
+           {
+             int save_j, temp;
+
+             save_j = j;
+             ADD_CHAR (string[i]);
+             ADD_CHAR (cc);
+
+             temp = (*history_inhibit_expansion_function) (result, save_j);
+             if (temp)
+               {
+                 result[--j] = '\0';   /* `unadd' cc, leaving ADD_CHAR(string[i]) */
+                 break;
+               }
+             else
+               result[j = save_j] = '\0';
+           }
+
 #if defined (NO_BANG_HASH_MODIFIERS)
          /* There is something that is listed as a `word specifier' in csh
             documentation which means `the expanded text to this point'.
diff --git a/input.c b/input.c
index f514d8c5c17f097f6c3b47589ca83cf6eac7ae74..930efa4fce8e832742040aec43b3ec4fb7e7caa1 100644 (file)
--- a/input.c
+++ b/input.c
@@ -50,6 +50,7 @@
 #include <signal.h>
 
 #include "posixselect.h"
+#include "posixtime.h"
 
 #if defined (FIONREAD_IN_SYS_IOCTL)
 #  include <sys/ioctl.h>
@@ -89,6 +90,9 @@ rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
 /* A function to call if a read(2) is interrupted by a signal. */
 rl_hook_func_t *rl_signal_event_hook = (rl_hook_func_t *)NULL;
 
+/* A function to call when readline times out after a time is specified. */
+rl_hook_func_t *rl_timeout_event_hook = (rl_hook_func_t *)NULL;
+
 /* A function to replace _rl_input_available for applications using the
    callback interface. */
 rl_hook_func_t *rl_input_available_hook = (rl_hook_func_t *)NULL;
@@ -132,6 +136,36 @@ win32_isatty (int fd)
 #define isatty(x)      win32_isatty(x)
 #endif
 
+/* Readline timeouts */
+
+/* I don't know how to set a timeout for _getch() in MinGW32, so we use
+   SIGALRM. */
+#if (defined (HAVE_PSELECT) || defined (HAVE_SELECT)) && !defined (__MINGW32__)
+#  define RL_TIMEOUT_USE_SELECT
+#else
+#  define RL_TIMEOUT_USE_SIGALRM
+#endif
+
+int rl_set_timeout (unsigned int, unsigned int);
+int rl_timeout_remaining (unsigned int *, unsigned int *);
+
+int _rl_timeout_init (void);
+int _rl_timeout_sigalrm_handler (void);
+int _rl_timeout_select (int, fd_set *, fd_set *, fd_set *, const struct timeval *, const sigset_t *);
+
+static void _rl_timeout_handle (void);
+#if defined (RL_TIMEOUT_USE_SIGALRM)
+static int set_alarm (unsigned int *, unsigned int *);
+static void reset_alarm (void);
+#endif
+
+/* We implement timeouts as a future time using a supplied interval
+   (timeout_duration) from when the timeout is set (timeout_point).
+   That allows us to easily determine whether the timeout has occurred
+   and compute the time remaining until it does. */
+static struct timeval timeout_point;
+static struct timeval timeout_duration;
+
 /* **************************************************************** */
 /*                                                                 */
 /*                     Character Input Buffering                   */
@@ -223,13 +257,17 @@ rl_gather_tyi (void)
   input = 0;
   tty = fileno (rl_instream);
 
-#if defined (HAVE_SELECT)
+#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
   FD_ZERO (&readfds);
   FD_ZERO (&exceptfds);
   FD_SET (tty, &readfds);
   FD_SET (tty, &exceptfds);
   USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout);
+#if defined (RL_TIMEOUT_USE_SELECT)
+  result = _rl_timeout_select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout, NULL);
+#else
   result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
+#endif
   if (result <= 0)
     return 0;  /* Nothing to read. */
 #endif
@@ -330,11 +368,11 @@ rl_set_keyboard_input_timeout (int u)
 int
 _rl_input_available (void)
 {
-#if defined(HAVE_SELECT)
+#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
   fd_set readfds, exceptfds;
   struct timeval timeout;
 #endif
-#if !defined (HAVE_SELECT) && defined(FIONREAD)
+#if !defined (HAVE_SELECT) && defined (FIONREAD)
   int chars_avail;
 #endif
   int tty;
@@ -344,13 +382,17 @@ _rl_input_available (void)
 
   tty = fileno (rl_instream);
 
-#if defined (HAVE_SELECT)
+#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
   FD_ZERO (&readfds);
   FD_ZERO (&exceptfds);
   FD_SET (tty, &readfds);
   FD_SET (tty, &exceptfds);
   USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout);
+#  if defined (RL_TIMEOUT_USE_SELECT)
+  return (_rl_timeout_select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout, NULL) > 0);
+#  else
   return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
+#  endif
 #else
 
 #if defined (FIONREAD)
@@ -463,6 +505,242 @@ rl_clear_pending_input (void)
   return 0;
 }
 
+/* **************************************************************** */
+/*                                                                 */
+/*                         Timeout utility                         */
+/*                                                                 */
+/* **************************************************************** */
+
+#if defined (RL_TIMEOUT_USE_SIGALRM)
+#  if defined (HAVE_SETITIMER)
+
+static int
+set_alarm (unsigned int *secs, unsigned int *usecs)
+{
+  struct itimerval it;
+
+  timerclear (&it.it_interval);
+  timerset (&it.it_value, *secs, *usecs);
+  return setitimer (ITIMER_REAL, &it, NULL);
+}
+
+static void
+reset_alarm ()
+{
+  struct itimerval it;
+
+  timerclear (&it.it_interval);
+  timerclear (&it.it_value);
+  setitimer (ITIMER_REAL, &it, NULL);
+}
+#  else
+static int
+set_alarm (unsigned int *secs, unsigned int *usecs)
+{
+  if (*secs == 0 || *usecs >= USEC_PER_SEC / 2)
+    (*secs)++;
+  *usecs = 0;
+
+  return alarm (*secs);
+}
+static void
+reset_alarm ()
+{
+  alarm (0);
+}
+#  endif
+#endif
+
+/* Set a timeout which will be used for the next call of `readline
+   ()'.  When (0, 0) are specified the timeout is cleared.  */
+int
+rl_set_timeout (unsigned int secs, unsigned int usecs)
+{
+  timeout_duration.tv_sec = secs + usecs / USEC_PER_SEC;
+  timeout_duration.tv_usec = usecs % USEC_PER_SEC;
+
+  return 0;
+}
+
+/* Start measuring the time.  Returns 0 on success.  Returns -1 on
+   error. */
+int
+_rl_timeout_init (void)
+{
+  unsigned int secs, usecs;
+
+  /* Clear the timeout state of the previous edit */
+  RL_UNSETSTATE(RL_STATE_TIMEOUT);
+  timerclear (&timeout_point);
+
+  /* Return 0 when timeout is unset. */
+  if (timerisunset (&timeout_duration))
+    return 0;
+
+  /* Return -1 on gettimeofday error. */
+  if (gettimeofday(&timeout_point, 0) != 0)
+    {
+      timerclear (&timeout_point);
+      return -1;
+    }
+
+  secs = timeout_duration.tv_sec;
+  usecs = timeout_duration.tv_usec;
+
+#if defined (RL_TIMEOUT_USE_SIGALRM)
+  /* If select(2)/pselect(2) is unavailable, use SIGALRM. */
+  if (set_alarm (&secs, &usecs) < 0)
+    return -1;
+#endif
+
+  timeout_point.tv_sec += secs;
+  timeout_point.tv_usec += usecs;
+  if (timeout_point.tv_usec >= USEC_PER_SEC)
+    {
+      timeout_point.tv_sec++;
+      timeout_point.tv_usec -= USEC_PER_SEC;
+    }
+
+  return 0;
+}
+
+/* Get the remaining time until the scheduled timeout.  Returns -1 on
+   error or no timeout set with secs and usecs unchanged.  Returns 0
+   on an expired timeout with secs and usecs unchanged.  Returns 1
+   when the timeout has not yet expired.  The remaining time is stored
+   in secs and usecs.  When NULL is specified to either of the
+   arguments, just the expiration is tested. */
+int
+rl_timeout_remaining (unsigned int *secs, unsigned int *usecs)
+{
+  struct timeval current_time;
+
+  /* Return -1 when timeout is unset. */
+  if (timerisunset (&timeout_point))
+    {
+      errno = 0;
+      return -1;
+    }
+
+  /* Return -1 on error. errno is set by gettimeofday. */
+  if (gettimeofday(&current_time, 0) != 0)
+    return -1;
+
+  /* Return 0 when timeout has already expired. */
+  /* could use timercmp (&timeout_point, &current_time, <) here */
+  if (current_time.tv_sec > timeout_point.tv_sec ||
+       (current_time.tv_sec == timeout_point.tv_sec &&
+        current_time.tv_usec >= timeout_point.tv_usec))
+    return 0;
+
+  if (secs && usecs)
+    {
+      *secs = timeout_point.tv_sec - current_time.tv_sec;
+      *usecs = timeout_point.tv_usec - current_time.tv_usec;
+      if (timeout_point.tv_usec < current_time.tv_usec)
+       {
+         (*secs)--;
+         *usecs += USEC_PER_SEC;
+       }
+    }
+
+  return 1;
+}
+
+/* This should only be called if RL_TIMEOUT_USE_SELECT is defined. */
+
+#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
+int
+_rl_timeout_select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout, const sigset_t *sigmask)
+{
+  int result;
+#if defined (HAVE_PSELECT)
+  struct timespec ts;
+#else
+  sigset_t origmask;
+  struct timeval tv;
+#endif
+  int tmout_status;
+  struct timeval tmout;
+  unsigned int sec, usec;
+
+  /* When the remaining time for rl_timeout is shorter than the
+     keyboard input timeout, replace `timeout' with the remaining time
+     for `rl_timeout' and set `tmout_status = 1'. */
+  tmout_status = rl_timeout_remaining (&sec, &usec);
+  tmout.tv_sec = sec;
+  tmout.tv_usec = usec;
+
+  if (tmout_status == 0)
+    _rl_timeout_handle ();
+  else if (tmout_status == 1)
+    {
+      if (timeout == NULL || timercmp (&tmout, timeout, <))
+       timeout = &tmout;
+      else
+       tmout_status = -1;
+    }
+
+#if defined (HAVE_PSELECT)
+  if (timeout)
+    {
+      TIMEVAL_TO_TIMESPEC (timeout, &ts);
+      result = pselect (nfds, readfds, writefds, exceptfds, &ts, sigmask);
+    }
+  else
+    result = pselect (nfds, readfds, writefds, exceptfds, NULL, sigmask);
+#else
+  if (sigmask)
+    sigprocmask (SIG_SETMASK, sigmask, &origmask);
+
+  if (timeout)
+    {
+      tv.tv_sec = timeout->tv_sec;
+      tv.tv_usec = timeout->tv_usec;
+      result = select (nfds, readfds, writefds, exceptfds, &tv);
+    }
+  else
+    result = select (nfds, readfds, writefds, exceptfds, NULL);
+
+  if (sigmask)
+    sigprocmask (SIG_SETMASK, &origmask, NULL);
+#endif
+
+  if (tmout_status == 1 && result == 0)
+    _rl_timeout_handle ();
+
+  return result;
+}
+#endif
+
+static void
+_rl_timeout_handle ()
+{
+  if (rl_timeout_event_hook)
+    (*rl_timeout_event_hook) ();
+
+  RL_SETSTATE(RL_STATE_TIMEOUT);
+  _rl_abort_internal ();
+}
+
+int
+_rl_timeout_handle_sigalrm ()
+{
+#if defined (RL_TIMEOUT_USE_SIGALRM)
+  if (timerisunset (&timeout_point))
+    return -1;
+
+  /* Reset `timeout_point' to the current time to ensure that later
+     calls of `rl_timeout_pending ()' return 0 (timeout expired). */
+  if (gettimeofday(&timeout_point, 0) != 0)
+    timerclear (&timeout_point);
+
+  reset_alarm ();
+
+  _rl_timeout_handle ();
+#endif
+  return -1;
+}
 /* **************************************************************** */
 /*                                                                 */
 /*                          Character Input                        */
@@ -497,6 +775,7 @@ rl_read_key (void)
              if ((r = rl_gather_tyi ()) < 0)   /* XXX - EIO */
                {
                  rl_done = 1;
+                 RL_SETSTATE (RL_STATE_DONE);
                  return (errno == EIO ? (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF) : '\n');
                }
              else if (r > 0)                   /* read something */
@@ -525,11 +804,13 @@ rl_getc (FILE *stream)
 {
   int result;
   unsigned char c;
+  int fd;
 #if defined (HAVE_PSELECT)
   sigset_t empty_set;
   fd_set readfds;
 #endif
 
+  fd = fileno (stream);
   while (1)
     {
       RL_CHECK_SIGNALS ();
@@ -537,23 +818,27 @@ rl_getc (FILE *stream)
       /* We know at this point that _rl_caught_signal == 0 */
 
 #if defined (__MINGW32__)
-      if (isatty (fileno (stream)))
+      if (isatty (fd)
        return (_getch ());     /* "There is no error return." */
 #endif
       result = 0;
-#if defined (HAVE_PSELECT)
+#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
+      /* At this point, if we have pselect, we're using select/pselect for the
+        timeouts. We handled MinGW above. */
       FD_ZERO (&readfds);
-      FD_SET (fileno (stream), &readfds);
+      FD_SET (fd, &readfds);
 #  if defined (HANDLE_SIGNALS)
-      result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &_rl_orig_sigset);
+      result = _rl_timeout_select (fd + 1, &readfds, NULL, NULL, NULL, &_rl_orig_sigset);
 #  else
       sigemptyset (&empty_set);
       sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &empty_set);
-      result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &empty_set);
+      result = _rl_timeout_select (fd + 1, &readfds, NULL, NULL, NULL, &empty_set);
 #  endif /* HANDLE_SIGNALS */
+      if (result == 0)
+        _rl_timeout_handle ();         /* check the timeout */
 #endif
       if (result >= 0)
-       result = read (fileno (stream), &c, sizeof (unsigned char));
+       result = read (fd, &c, sizeof (unsigned char));
 
       if (result == sizeof (unsigned char))
        return (c);
@@ -582,7 +867,7 @@ rl_getc (FILE *stream)
 
       if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
        {
-         if (sh_unset_nodelay_mode (fileno (stream)) < 0)
+         if (sh_unset_nodelay_mode (fd) < 0)
            return (EOF);
          continue;
        }
index fdd18bbee5453b450a56f6ce28d76c06929767da..33f67d3d4b9a35654e7b232352ccf6d3ed33b41c 100644 (file)
--- a/isearch.c
+++ b/isearch.c
@@ -318,7 +318,7 @@ _rl_search_getchar (_rl_search_cxt *cxt)
 #if defined (HANDLE_MULTIBYTE)
   /* This ends up with C (and LASTC) being set to the last byte of the
      multibyte character.  In most cases c == lastc == mb[0] */
-  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
+  if (c >= 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
 #endif
 
index b8c5ac846e49119328d7d39f361d7f9b4c75d08a..57ce70458dad86f8532d009a5d2a1a9643067470 100644 (file)
--- a/parens.c
+++ b/parens.c
@@ -135,7 +135,11 @@ rl_insert_close (int count, int invoking_key)
       orig_point = rl_point;
       rl_point = match_point;
       (*rl_redisplay_function) ();
+#  if defined (RL_TIMEOUT_USE_SELECT)
+      ready = _rl_timeout_select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer, NULL);
+#  else
       ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
+#  endif
       rl_point = orig_point;
 #else /* !HAVE_SELECT */
       _rl_insert_char (count, invoking_key);
diff --git a/posixtime.h b/posixtime.h
new file mode 100644 (file)
index 0000000..1d50ab6
--- /dev/null
@@ -0,0 +1,90 @@
+/* posixtime.h -- wrapper for time.h, sys/times.h mess. */
+
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+
+   This file is part of GNU Bash, the Bourne Again SHell.
+
+   Bash 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 3 of the License, or
+   (at your option) any later version.
+
+   Bash is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _POSIXTIME_H_
+#define _POSIXTIME_H_
+
+/* include this after config.h */
+/* Some systems require this, mostly for the definition of `struct timezone'.
+   For example, Dynix/ptx has that definition in <time.h> rather than
+      sys/time.h */
+#if defined (TIME_WITH_SYS_TIME)
+#  include <sys/time.h>
+#  include <time.h>
+#else
+#  if defined (HAVE_SYS_TIME_H)
+#    include <sys/time.h>
+#  else
+#    include <time.h>
+#  endif
+#endif
+
+#if !defined (HAVE_SYSCONF) || !defined (_SC_CLK_TCK)
+#  if !defined (CLK_TCK)
+#    if defined (HZ)
+#      define CLK_TCK  HZ
+#    else
+#      define CLK_TCK  60                      /* 60HZ */
+#    endif
+#  endif /* !CLK_TCK */
+#endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */
+
+#if !HAVE_TIMEVAL
+struct timeval
+{
+  time_t tv_sec;
+  long int tv_usec;
+};
+#endif
+
+#if !HAVE_GETTIMEOFDAY
+extern int gettimeofday PARAMS((struct timeval *, void *));
+#endif
+
+/* These exist on BSD systems, at least. */
+#if !defined (timerclear)
+#  define timerclear(tvp)      do { (tvp)->tv_sec = 0; (tvp)->tv_usec = 0; } while (0)
+#endif
+#if !defined (timerisset)
+#  define timerisset(tvp)      ((tvp)->tv_sec || (tvp)->tv_usec)
+#endif
+#if !defined (timercmp)
+#  define timercmp(a, b, CMP) \
+       (((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_usec CMP (b)->tv_usec) \
+                                     : ((a)->tv_sec CMP (b)->tv_sec))
+#endif
+
+/* These are non-standard. */
+#if !defined (timerisunset)
+#  define timerisunset(tvp)    ((tvp)->tv_sec == 0 && (tvp)->tv_usec == 0)
+#endif
+#if !defined (timerset)
+#  define timerset(tvp, s, u)  do { tvp->tv_sec = s; tvp->tv_usec = u; } while (0)
+#endif
+
+#ifndef TIMEVAL_TO_TIMESPEC
+#  define TIMEVAL_TO_TIMESPEC(tv, ts) \
+  do { \
+    (ts)->tv_sec = (tv)->tv_sec; \
+    (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+  } while (0)
+#endif
+
+#endif /* _POSIXTIME_H_ */
index de06af1d67edf5a453a5fd72263ec5780637c804..4002fe511de779e1b379de5ec8ece54177f05c78 100644 (file)
@@ -577,6 +577,15 @@ readline_internal_charloop (void)
        {
          (*rl_redisplay_function) ();
          _rl_want_redisplay = 0;
+
+         /* If we longjmped because of a timeout, handle it here. */
+         if (RL_ISSTATE (RL_STATE_TIMEOUT))
+           {
+             RL_SETSTATE (RL_STATE_DONE);
+             rl_done = 1;
+             return 1;
+           }
+
          /* If we get here, we're not being called from something dispatched
             from _rl_callback_read_char(), which sets up its own value of
             _rl_top_level (saving and restoring the old, of course), so
@@ -1148,6 +1157,9 @@ _rl_subseq_result (int r, Keymap map, int key, int got_subseq)
 int
 rl_initialize (void)
 {
+  /* Initialize the timeout first to get the precise start time. */
+  _rl_timeout_init ();
+
   /* If we have never been called before, initialize the
      terminal and data structures. */
   if (rl_initialized == 0)
index 90b538927e82c96e35d304395847d938004f956a..ab33823d96443c27bcebd0bd4d77be2501870768 100644 (file)
@@ -448,6 +448,13 @@ extern int rl_read_key (void);
 extern int rl_getc (FILE *);
 extern int rl_set_keyboard_input_timeout (int);
 
+/* Functions to set and reset timeouts. */
+extern int rl_set_timeout (unsigned int, unsigned int);
+extern int rl_timeout_remaining (unsigned int *, unsigned int *);
+
+#undef rl_clear_timeout
+#define rl_clear_timeout() rl_set_timeout (0, 0)
+
 /* `Public' utility functions . */
 extern void rl_extend_line_buffer (int);
 extern int rl_ding (void);
@@ -599,6 +606,8 @@ extern rl_hook_func_t *rl_event_hook;
 /* The address of a function to call if a read is interrupted by a signal. */
 extern rl_hook_func_t *rl_signal_event_hook;
 
+extern rl_hook_func_t *rl_timeout_event_hook;
+
 /* The address of a function to call if Readline needs to know whether or not
    there is data available from the current input source. */
 extern rl_hook_func_t *rl_input_available_hook;
@@ -906,6 +915,7 @@ extern int rl_persistent_signal_handlers;
 #define RL_STATE_REDISPLAYING  0x1000000       /* updating terminal display */
 
 #define RL_STATE_DONE          0x2000000       /* done; accepted line */
+#define RL_STATE_TIMEOUT       0x4000000
 
 #define RL_SETSTATE(x)         (rl_readline_state |= (x))
 #define RL_UNSETSTATE(x)       (rl_readline_state &= ~(x))
index 7d7c381974acff9624299e9e5b65786356b5a87a..86a29127a5149849fa6f708e09316e4922fcd243 100644 (file)
@@ -4,7 +4,7 @@
 /* Copyright (C) 1999-2021 Free Software Foundation, Inc.
 
    This file is part of the GNU Readline Library (Readline), a library
-   for reading lines of text with interactive input and history editing.      
+   for reading lines of text with interactive input and history editing.
 
    Readline is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -78,7 +78,7 @@ typedef struct  __rl_search_context
   int search_string_size;
 
   char **lines;
-  char *allocated_line;    
+  char *allocated_line;
   int hlen;
   int hindex;
 
@@ -169,7 +169,7 @@ typedef struct __rl_vimotion_context
 
 /* fill in more as needed */
 /* `Generic' callback data and functions */
-typedef struct __rl_callback_generic_arg 
+typedef struct __rl_callback_generic_arg
 {
   int count;
   int i1, i2;
@@ -259,7 +259,7 @@ extern void _rl_keyseq_cxt_dispose (_rl_keyseq_cxt *);
 extern void _rl_keyseq_chain_dispose (void);
 
 extern int _rl_dispatch_callback (_rl_keyseq_cxt *);
-     
+
 /* callback.c */
 extern _rl_callback_generic_arg *_rl_callback_data_alloc (int);
 extern void _rl_callback_data_dispose (_rl_callback_generic_arg *);
@@ -301,6 +301,13 @@ extern void _rl_insert_typein (int);
 extern int _rl_unget_char (int);
 extern int _rl_pushed_input_available (void);
 
+extern int _rl_timeout_init (void);
+extern int _rl_timeout_handle_sigalrm (void);
+#if defined (_POSIXSELECT_H_)
+/* use as a sentinel for fd_set, struct timeval,  and sigset_t definitions */
+extern int _rl_timeout_select (int, fd_set *, fd_set *, fd_set *, const struct timeval *, const sigset_t *);
+#endif
+
 /* isearch.c */
 extern _rl_search_cxt *_rl_scxt_alloc (int, int);
 extern void _rl_scxt_dispose (_rl_search_cxt *, int);
@@ -371,7 +378,7 @@ extern void _rl_internal_char_cleanup (void);
 extern void _rl_init_executing_keyseq (void);
 extern void _rl_term_executing_keyseq (void);
 extern void _rl_end_executing_keyseq (void);
-extern void _rl_add_executing_keyseq (int); 
+extern void _rl_add_executing_keyseq (int);
 
 /* rltty.c */
 extern int _rl_disable_tty_signals (void);
@@ -469,7 +476,7 @@ extern int _rl_vi_domove_motion_cleanup (int, _rl_vimotion_cxt *);
 /* Use HS_HISTORY_VERSION as the sentinel to see if we've included history.h
    and so can use HIST_ENTRY */
 #if defined (HS_HISTORY_VERSION)
-extern void _rl_free_history_entry (HIST_ENTRY *); 
+extern void _rl_free_history_entry (HIST_ENTRY *);
 #endif
 
 /*************************************************************************
diff --git a/rltty.c b/rltty.c
index e96fa8fb71d7e3400eb1f8a2f1cc737c4412b6a5..4a49200148e8831c136d282a98f1b78995d4cdcd 100644 (file)
--- a/rltty.c
+++ b/rltty.c
@@ -692,7 +692,7 @@ rl_deprep_terminal (void)
   if (terminal_prepped & TPX_BRACKPASTE)
     {
       fprintf (rl_outstream, BRACK_PASTE_FINI);
-      if (_rl_eof_found)
+      if (_rl_eof_found && (RL_ISSTATE (RL_STATE_TIMEOUT) == 0))
        fprintf (rl_outstream, "\n");
     }
 
index 0943c643b27df8d2bcc26a46c5dbbd96e2c78846..2bbec3ec14c57133459d2150b2ec94cea6dc7497 100644 (file)
--- a/signals.c
+++ b/signals.c
@@ -222,6 +222,9 @@ _rl_handle_signal (int sig)
   switch (sig)
     {
     case SIGINT:
+      /* We will end up blocking SIGTTOU while we are resetting the tty, so
+        watch out for this if it causes problems. We could prevent this by
+        setting block_sig to 1 without modifying SET. */
       _rl_reset_completion_state ();
       rl_free_line_state ();
 #if defined (READLINE_CALLBACKS)
@@ -242,8 +245,11 @@ _rl_handle_signal (int sig)
         this even if we've been stopped on SIGTTOU, since we handle signals
         when we have returned from the signal handler and the signal is no
         longer blocked. */
-      sigaddset (&set, SIGTTOU);
-      block_sig = 1;
+      if (block_sig == 0)
+       {
+         sigaddset (&set, SIGTTOU);
+         block_sig = 1;
+       }
 #  endif
 #endif /* SIGTSTP */
    /* Any signals that should be blocked during cleanup should go here. */
@@ -261,13 +267,17 @@ _rl_handle_signal (int sig)
     case SIGTERM:
 #if defined (SIGALRM)
     case SIGALRM:
+      if (sig == SIGALRM)
+       _rl_timeout_handle_sigalrm ();
 #endif
 #if defined (SIGQUIT)
     case SIGQUIT:
 #endif
 
+#if defined (HAVE_POSIX_SIGNALS)
       if (block_sig)
        sigprocmask (SIG_BLOCK, &set, &oset);
+#endif
 
       rl_echo_signal_char (sig);
       rl_cleanup_after_signal ();
@@ -283,19 +293,6 @@ _rl_handle_signal (int sig)
 
       /* We don't have to bother unblocking the signal because we are not
         running in a signal handler context. */
-#if 0
-#if defined (HAVE_POSIX_SIGNALS)
-      /* Make sure this signal is not blocked when we resend it to the
-        calling application. */
-      sigemptyset (&set);
-      sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
-      sigdelset (&set, sig);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-      omask = sigblock (0);
-#  endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-#endif
 
 #if defined (__EMX__)
       signal (sig, SIG_ACK);
@@ -309,16 +306,6 @@ _rl_handle_signal (int sig)
 
       /* We don't need to modify the signal mask now that this is not run in
         a signal handler context. */
-#if 0
-      /* Let the signal that we just sent through if it is blocked.  */
-#if defined (HAVE_POSIX_SIGNALS)
-      sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
-#else /* !HAVE_POSIX_SIGNALS */
-#  if defined (HAVE_BSD_SIGNALS)
-      sigsetmask (omask & ~(sigmask (sig)));
-#  endif /* HAVE_BSD_SIGNALS */
-#endif /* !HAVE_POSIX_SIGNALS */
-#endif
 
       rl_reset_after_signal ();      
     }
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 282431d..133566f
@@ -96,6 +96,10 @@ do
 
        if [ -n "$mode" ]; then
                chmod $mode $newdir/$fname
+       elif [ "$type" = "f" ]; then
+               chmod $filmode $newdir/$fname
+       elif [ "$type" = "d" ]; then
+               chmod $dirmode $newdir/$fname
        fi
 
 done < $MANIFEST
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 45e157cdcb3827c7805d440f8d16034f637154fa..729d847b23f460a1ba1aee61d4cd1922866d40a9 100644 (file)
@@ -151,13 +151,13 @@ darwin*)
        darwin[1-7].*)
                SHOBJ_STATUS=unsupported
                SHOBJ_LDFLAGS='-dynamic'
-               SHLIB_XLDFLAGS='-arch_only `/usr/bin/arch` -install_name $(libdir)/`echo $@ | sed "s:\\..*::"`.$(SHLIB_MAJOR).$(SHLIB_LIBSUFF) -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -v'
+               SHLIB_XLDFLAGS='-install_name $(libdir)/`echo $@ | sed "s:\\..*::"`.$(SHLIB_MAJOR).$(SHLIB_LIBSUFF) -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -v'
                ;;
        # Darwin 8 == Mac OS X 10.4; Mac OS X 10.N == Darwin N+4
        *)
                case "${host_os}" in
                darwin[89]*|darwin1[012]*)
-                       SHOBJ_ARCHFLAGS='-arch_only `/usr/bin/arch`'
+                       SHOBJ_ARCHFLAGS=
                        ;;
                 *)     # Mac OS X 10.9 (Mavericks) and later
                        SHOBJ_ARCHFLAGS=
diff --git a/text.c b/text.c
index 828555de1cc6005178acfd6f17857eb4a1ca7d6a..e9de7523acc5dd54d635971942faa7583d6f8413 100644 (file)
--- a/text.c
+++ b/text.c
@@ -919,8 +919,11 @@ _rl_overwrite_char (int count, int c)
   int k;
 
   /* Read an entire multibyte character sequence to insert COUNT times. */
+  k = 1;
   if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
+  if (k < 0)
+    return 1;
 #endif
 
   rl_begin_undo_group ();
diff --git a/util.c b/util.c
index 1576b55d50d53cf2a61b32a879697b9a338f5647..2cd7b3ce0c631ae581d6f791cb7cf820c7ba623f 100644 (file)
--- a/util.c
+++ b/util.c
@@ -98,7 +98,8 @@ _rl_walphabetic (wchar_t wc)
 int
 _rl_abort_internal (void)
 {
-  rl_ding ();
+  if (RL_ISSTATE (RL_STATE_TIMEOUT) == 0)
+    rl_ding ();                        /* Don't ring the bell on a timeout */
   rl_clear_message ();
   _rl_reset_argument ();
   rl_clear_pending_input ();
index 80f82b96ff5d8d69c2cb0b287cb4866c7469c279..da7350d289cb0624a4207c2a9e4c540e5e3852bd 100644 (file)
--- a/vi_mode.c
+++ b/vi_mode.c
@@ -2036,6 +2036,9 @@ _rl_vi_callback_change_char (_rl_callback_generic_arg *data)
   char mb[MB_LEN_MAX+1];
 
   c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+  if (c < 0)
+    return -1;
+
 #if defined (HANDLE_MULTIBYTE)
   if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
     strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
@@ -2044,9 +2047,6 @@ _rl_vi_callback_change_char (_rl_callback_generic_arg *data)
     _rl_vi_last_replacement[0] = c;
   _rl_vi_last_replacement[MB_LEN_MAX] = '\0';  /* XXX */
 
-  if (c < 0)
-    return -1;
-
   _rl_callback_func = 0;
   _rl_want_redisplay = 1;
 
@@ -2077,6 +2077,8 @@ rl_vi_change_char (int count, int key)
   else
     {
       c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
+      if (c < 0)
+       return -1;
 #ifdef HANDLE_MULTIBYTE
       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
        strncpy (_rl_vi_last_replacement, mb, MB_LEN_MAX);
@@ -2113,7 +2115,8 @@ rl_vi_overstrike (int count, int key)
 
   if (count > 0)
     {
-      _rl_overwrite_char (count, key);
+      if (_rl_overwrite_char (count, key) != 0)
+       return (1);
       vi_replace_count += count;
     }