]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #23735: Add SIGWINCH handler for Readline 6.3+ support, by Eric Price
authorMartin Panter <vadmium+py@gmail.com>
Sun, 3 Apr 2016 02:54:58 +0000 (02:54 +0000)
committerMartin Panter <vadmium+py@gmail.com>
Sun, 3 Apr 2016 02:54:58 +0000 (02:54 +0000)
Misc/ACKS
Misc/NEWS
Modules/readline.c
configure
configure.ac
pyconfig.h.in

index 3a9cd6f53b4b1c6bc6a58fb2335bbadf7baa460b..01b42f4f3e8ef4de6f2d9b31778da5cfbb32508f 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1155,6 +1155,7 @@ Florian Preinstorfer
 Amrit Prem
 Paul Prescod
 Donovan Preston
+Eric Price
 Paul Price
 Iuliia Proskurnia
 Dorian Pula
index 9682b409d1415bdc030eb14976cdb7889dce2d0d..6d43666b56d94446b621d685a43050712c197fc7 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -99,6 +99,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #23735: Handle terminal resizing with Readline 6.3+ by installing our
+  own SIGWINCH handler.  Patch by Eric Price.
+
 - Issue #26586: In http.server, respond with "413 Request header fields too
   large" if there are too many header fields to parse, rather than killing
   the connection and raising an unhandled exception.  Patch by Xiang Zhang.
index 401300395dee68d60e2b6afd1e86e5702542a66a..82daa52b2d50c106f20521436cbdce121d543b32 100644 (file)
@@ -928,6 +928,26 @@ on_completion_display_matches_hook(char **matches,
 
 #endif
 
+#ifdef HAVE_RL_RESIZE_TERMINAL
+static volatile sig_atomic_t sigwinch_received;
+static sighandler_t sigwinch_ohandler;
+
+static void
+readline_sigwinch_handler(int signum)
+{
+    sigwinch_received = 1;
+    if (sigwinch_ohandler &&
+            sigwinch_ohandler != SIG_IGN && sigwinch_ohandler != SIG_DFL)
+        sigwinch_ohandler(signum);
+
+#ifndef HAVE_SIGACTION
+    /* If the handler was installed with signal() rather than sigaction(),
+    we need to reinstall it. */
+    PyOS_setsig(SIGWINCH, readline_sigwinch_handler);
+#endif
+}
+#endif
+
 /* C function to call the Python completer. */
 
 static char *
@@ -1033,6 +1053,10 @@ setup_readline(readlinestate *mod_state)
     /* Bind both ESC-TAB and ESC-ESC to the completion function */
     rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
     rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
+#ifdef HAVE_RL_RESIZE_TERMINAL
+    /* Set up signal handler for window resize */
+    sigwinch_ohandler = PyOS_setsig(SIGWINCH, readline_sigwinch_handler);
+#endif
     /* Set our hook functions */
     rl_startup_hook = on_startup_hook;
 #ifdef HAVE_RL_PRE_INPUT_HOOK
@@ -1118,6 +1142,13 @@ readline_until_enter_or_signal(const char *prompt, int *signal)
             struct timeval *timeoutp = NULL;
             if (PyOS_InputHook)
                 timeoutp = &timeout;
+#ifdef HAVE_RL_RESIZE_TERMINAL
+            /* Update readline's view of the window size after SIGWINCH */
+            if (sigwinch_received) {
+                sigwinch_received = 0;
+                rl_resize_terminal();
+            }
+#endif
             FD_SET(fileno(rl_instream), &selectset);
             /* select resets selectset if no input was available */
             has_input = select(fileno(rl_instream) + 1, &selectset,
index 9ff548f8d14fdb431bcbc752b7b7aac32bc820ee..6f26a36b65725a365d0bd1e9d40d29e9d8a8d822 100755 (executable)
--- a/configure
+++ b/configure
@@ -14929,6 +14929,50 @@ $as_echo "#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1" >>confdefs.h
 fi
 
 
+# also in 4.0, but not in editline
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_resize_terminal in -lreadline" >&5
+$as_echo_n "checking for rl_resize_terminal in -lreadline... " >&6; }
+if ${ac_cv_lib_readline_rl_resize_terminal+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $READLINE_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char rl_resize_terminal ();
+int
+main ()
+{
+return rl_resize_terminal ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_readline_rl_resize_terminal=yes
+else
+  ac_cv_lib_readline_rl_resize_terminal=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_rl_resize_terminal" >&5
+$as_echo "$ac_cv_lib_readline_rl_resize_terminal" >&6; }
+if test "x$ac_cv_lib_readline_rl_resize_terminal" = xyes; then :
+
+$as_echo "#define HAVE_RL_RESIZE_TERMINAL 1" >>confdefs.h
+
+fi
+
+
 # check for readline 4.2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_matches in -lreadline" >&5
 $as_echo_n "checking for rl_completion_matches in -lreadline... " >&6; }
index 282610a3dc163b2375335ba18cd501553dcaa3bb..e7d7bfce2f52ec7053720fc5f44e09d0bb9e0037 100644 (file)
@@ -4527,6 +4527,11 @@ AC_CHECK_LIB(readline, rl_completion_display_matches_hook,
        AC_DEFINE(HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK, 1,
         [Define if you have readline 4.0]), ,$READLINE_LIBS)
 
+# also in 4.0, but not in editline
+AC_CHECK_LIB(readline, rl_resize_terminal,
+       AC_DEFINE(HAVE_RL_RESIZE_TERMINAL, 1,
+        [Define if you have readline 4.0]), ,$READLINE_LIBS)
+
 # check for readline 4.2
 AC_CHECK_LIB(readline, rl_completion_matches,
        AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1,
index e017d4ea316cf652487d467dbfd0916804fbef57..d432a821a575c32d61fea9cab87dfaf3a9c111af 100644 (file)
 /* Define if you have readline 4.0 */
 #undef HAVE_RL_PRE_INPUT_HOOK
 
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_RESIZE_TERMINAL
+
 /* Define to 1 if you have the `round' function. */
 #undef HAVE_ROUND