From cedd61a753785831f71ae5582c134c816c92700d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Bri=C3=A8re?= Date: Sat, 29 Jun 2019 08:29:54 -0400 Subject: Make Readline non-blocking: Relay SIGWINCH to Readline When using Readline's callback interface, signals are (by default) only captured within the duration of the rl_callback_read_char() call. It is therefore expected of the application to capture SIGWINCH on its own, and notify Readline of the fact. (While it's possible to change this with rl_persistent_signal_handlers, some signals, such as SIGHUP, will still only be *processed* during that call, making it a somewhat unappealing solution. This all could be alleviated by calling rl_check_signals() periodically, but that function was only introduced in Readline 8.0, which is far too recent.) Note that we are using signal(2) and not sigaction(2), depite the various warnings that come with it, mostly because it's what is already present in the codebase. --- src/userintf.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/userintf.cpp b/src/userintf.cpp index 772184d..6534e99 100644 --- a/src/userintf.cpp +++ b/src/userintf.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "address_book.h" #include "events.h" #include "line.h" @@ -111,6 +112,14 @@ static void tw_readline_cb(char *line) } } +// SIGWINCH handler to help us relay that information to Readline +static int sigwinch_received; +static void sigwinch_handler(int signum) +{ + sigwinch_received = 1; + signal(SIGWINCH, sigwinch_handler); +} + ///////////////////////////// // Private ///////////////////////////// @@ -2215,13 +2224,20 @@ void t_userintf::run(void) { // Additional stuff for using the Readline callback interface cb_user_intf = this; + signal(SIGWINCH, sigwinch_handler); rl_callback_handler_install(CLI_PROMPT, tw_readline_cb); while (!end_interface) { + // Relay any SIGWINCH to Readline + if (sigwinch_received) { + rl_resize_terminal(); + sigwinch_received = 0; + } rl_callback_read_char(); } rl_callback_handler_remove(); + signal(SIGWINCH, SIG_DFL); // Terminate phone functions write_history(sys_config->get_history_file().c_str()); -- cgit v1.2.3