mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-10-31 00:17:44 +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:
parent
1fc86d31db
commit
93922f102f
@ -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.
|
Loading…
Reference in New Issue
Block a user