mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-10-31 18:48:11 +08:00 
			
		
		
		
	Do not throw SIGINT after catching SIGINT signal (#128)
This fixes: https://github.com/ArthurSonzogni/FTXUI/issues/117
This commit is contained in:
		| @@ -226,6 +226,7 @@ if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4") | ||||
|     src/ftxui/component/input_test.cpp | ||||
|     src/ftxui/component/radiobox_test.cpp | ||||
|     src/ftxui/component/receiver_test.cpp | ||||
|     src/ftxui/component/screen_interactive_test.cpp | ||||
|     src/ftxui/component/terminal_input_parser_test.cpp | ||||
|     src/ftxui/component/toggle_test.cpp | ||||
|     src/ftxui/dom/gauge_test.cpp | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| #include <stdio.h>    // for fileno, stdin | ||||
| #include <algorithm>  // for copy, max, min | ||||
| #include <csignal>    // for signal, SIGINT, SIGWINCH | ||||
| #include <cstdlib>    // for exit, NULL | ||||
| #include <csignal>  // for signal, SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM, SIGWINCH | ||||
| #include <cstdlib>           // for NULL | ||||
| #include <initializer_list>  // for initializer_list | ||||
| #include <iostream>  // for cout, ostream, basic_ostream, operator<<, endl, flush | ||||
| #include <stack>     // for stack | ||||
| #include <thread>    // for thread | ||||
| @@ -12,7 +13,7 @@ | ||||
| #include "ftxui/component/component_base.hpp"  // for ComponentBase | ||||
| #include "ftxui/component/event.hpp"           // for Event | ||||
| #include "ftxui/component/mouse.hpp"           // for Mouse | ||||
| #include "ftxui/component/receiver.hpp"  // for ReceiverImpl, SenderImpl, MakeReceiver | ||||
| #include "ftxui/component/receiver.hpp"  // for ReceiverImpl, MakeReceiver, Sender, SenderImpl, Receiver | ||||
| #include "ftxui/component/screen_interactive.hpp" | ||||
| #include "ftxui/component/terminal_input_parser.hpp"  // for TerminalInputParser | ||||
| #include "ftxui/dom/node.hpp"                         // for Node, Render | ||||
| @@ -31,8 +32,8 @@ | ||||
| #endif | ||||
| #else | ||||
| #include <sys/select.h>  // for select, FD_ISSET, FD_SET, FD_ZERO, fd_set | ||||
| #include <termios.h>     // for tcsetattr, tcgetattr, cc_t | ||||
| #include <unistd.h>      // for STDIN_FILENO, read | ||||
| #include <termios.h>  // for tcsetattr, termios, tcgetattr, TCSANOW, cc_t, ECHO, ICANON, VMIN, VTIME | ||||
| #include <unistd.h>  // for STDIN_FILENO, read | ||||
| #endif | ||||
|  | ||||
| // Quick exit is missing in standard CLang headers | ||||
| @@ -201,12 +202,11 @@ const std::string DeviceStatusReport(DSRMode ps) { | ||||
| using SignalHandler = void(int); | ||||
| std::stack<std::function<void()>> on_exit_functions; | ||||
| void OnExit(int signal) { | ||||
|   (void)signal; | ||||
|   while (!on_exit_functions.empty()) { | ||||
|     on_exit_functions.top()(); | ||||
|     on_exit_functions.pop(); | ||||
|   } | ||||
|   if (signal) | ||||
|     std::raise(signal); | ||||
| } | ||||
|  | ||||
| auto install_signal_handler = [](int sig, SignalHandler handler) { | ||||
| @@ -279,12 +279,12 @@ CapturedMouse ScreenInteractive::CaptureMouse() { | ||||
| void ScreenInteractive::Loop(Component component) { | ||||
|   on_exit_functions.push([this] { ExitLoopClosure()(); }); | ||||
|  | ||||
|   // Install a SIGINT handler and restore the old handler on exit. | ||||
|   auto old_sigint_handler = std::signal(SIGINT, OnExit); | ||||
|   on_exit_functions.push( | ||||
|       [old_sigint_handler]() { std::signal(SIGINT, old_sigint_handler); }); | ||||
|   // Install signal handlers to restore the terminal state on exit. The default | ||||
|   // signal handlers are restored on exit. | ||||
|   for (int signal : {SIGTERM, SIGSEGV, SIGINT, SIGILL, SIGABRT, SIGFPE}) | ||||
|     install_signal_handler(signal, OnExit); | ||||
|  | ||||
|   // Save the old terminal configuration and restore it on exit. | ||||
|     // Save the old terminal configuration and restore it on exit. | ||||
| #if defined(_WIN32) | ||||
|   // Enable VT processing on stdout and stdin | ||||
|   auto stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); | ||||
|   | ||||
							
								
								
									
										52
									
								
								src/ftxui/component/screen_interactive_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/ftxui/component/screen_interactive_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| #include <gtest/gtest-message.h>    // for Message | ||||
| #include <gtest/gtest-test-part.h>  // for TestPartResult | ||||
| #include <csignal> | ||||
|  | ||||
| #include "ftxui/component/component.hpp" | ||||
| #include "ftxui/component/screen_interactive.hpp" | ||||
| #include "ftxui/dom/elements.hpp" | ||||
| #include "gtest/gtest_pred_impl.h"  // for AssertionResult, Test, EXPECT_EQ | ||||
|  | ||||
| using namespace ftxui; | ||||
|  | ||||
| namespace { | ||||
| bool TestSignal(int signal) { | ||||
|   int called = 0; | ||||
|   // The tree of components. This defines how to navigate using the keyboard. | ||||
|   auto component = Renderer([&] { | ||||
|     called++; | ||||
|     std::raise(signal); | ||||
|     called++; | ||||
|     return text(L""); | ||||
|   }); | ||||
|  | ||||
|   auto screen = ScreenInteractive::FitComponent(); | ||||
|   screen.Loop(component); | ||||
|  | ||||
|   EXPECT_EQ(called, 2); | ||||
|   return true; | ||||
| } | ||||
| }  // namespace | ||||
|  | ||||
| TEST(ScreenInteractive, Signal_SIGTERM) { | ||||
|   TestSignal(SIGTERM); | ||||
| } | ||||
| TEST(ScreenInteractive, Signal_SIGSEGV) { | ||||
|   TestSignal(SIGSEGV); | ||||
| } | ||||
| TEST(ScreenInteractive, Signal_SIGINT) { | ||||
|   TestSignal(SIGINT); | ||||
| } | ||||
| TEST(ScreenInteractive, Signal_SIGILL) { | ||||
|   TestSignal(SIGILL); | ||||
| } | ||||
| TEST(ScreenInteractive, Signal_SIGABRT) { | ||||
|   TestSignal(SIGABRT); | ||||
| } | ||||
| TEST(ScreenInteractive, Signal_SIGFPE) { | ||||
|   TestSignal(SIGFPE); | ||||
| } | ||||
|  | ||||
| // Copyright 2021 Arthur Sonzogni. All rights reserved. | ||||
| // Use of this source code is governed by the MIT license that can be found in | ||||
| // the LICENSE file. | ||||
		Reference in New Issue
	
	Block a user
	 Arthur Sonzogni
					Arthur Sonzogni