From cccbe5baa96438fd4668e47f6b732e6fdae3dd0c Mon Sep 17 00:00:00 2001 From: ArthurSonzogni Date: Sat, 2 May 2020 02:02:04 +0200 Subject: [PATCH] Fix non blocking I/O on POSIX. --- src/ftxui/component/screen_interactive.cpp | 36 ++++++++++++++-------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/ftxui/component/screen_interactive.cpp b/src/ftxui/component/screen_interactive.cpp index 58ee31d..2029cc7 100644 --- a/src/ftxui/component/screen_interactive.cpp +++ b/src/ftxui/component/screen_interactive.cpp @@ -26,7 +26,7 @@ #else #include #include - #include + #include #endif // Quick exit is missing in standard CLang headers @@ -93,22 +93,28 @@ void Win32EventListener(std::atomic* quit, #else +int CheckStdinReady(int usec_timeout) { + timeval tv = {0, usec_timeout}; + fd_set fds; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv); + return FD_ISSET(STDIN_FILENO, &fds); +} + // Read char from the terminal. void UnixEventListener(std::atomic* quit, Sender sender) { - fd_set readfds; - FD_ZERO(&readfds); - - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 300000; + const int buffer_size = 100; + const int timeout_usec = 50000; + // short CHAR_AVAILABLE_TO_READ = POLLIN | POLLPRI; while (!*quit) { - FD_SET(STDIN_FILENO, &readfds); - if (!select(1, &readfds, NULL, NULL, &timeout)) + if (!CheckStdinReady(timeout_usec)) continue; - - char c = getchar(); - sender->Send(c); + char buff[buffer_size]; + int l = read(fileno(stdin), buff, buffer_size); + for (int i = 0; i < l; ++i) + sender->Send(buff[i]); } } @@ -211,6 +217,12 @@ void ScreenInteractive::Loop(Component* component) { terminal.c_lflag &= ~ICANON; // Non canonique terminal. terminal.c_lflag &= ~ECHO; // Do not print after a key press. + terminal.c_cc[VMIN] = 0; + terminal.c_cc[VTIME] = 0; + auto oldf = fcntl(STDIN_FILENO, F_GETFL, 0); + fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); + on_exit_functions.push([=] { fcntl(STDIN_FILENO, F_GETFL, oldf); }); + tcsetattr(STDIN_FILENO, TCSANOW, &terminal); // Handle resize.