From f5f7bc80e8e16680622e5244b083560848257e9c Mon Sep 17 00:00:00 2001 From: Daniel Robertson Date: Sun, 20 Dec 2015 15:27:34 -0500 Subject: [PATCH] Add a signal function using sigaction Use a wrapper for sigaction in place of signal to ensure that the SA_RESTART flag is set for all signals used. Signed-off-by: Daniel Robertson --- src/event_manager.cc | 10 ++++++++++ src/event_manager.hh | 4 ++++ src/main.cc | 29 ++++++++++++++--------------- src/ncurses_ui.cc | 8 ++++---- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/event_manager.cc b/src/event_manager.cc index e1a4accd..0399283c 100644 --- a/src/event_manager.cc +++ b/src/event_manager.cc @@ -133,4 +133,14 @@ void EventManager::force_signal(int fd) FD_SET(fd, &m_forced_fd); } +SignalHandler set_signal_wrapper(int signum, SignalHandler handler) +{ + struct sigaction new_action, old_action; + + sigemptyset(&new_action.sa_mask); + new_action.sa_handler = handler; + new_action.sa_flags = SA_RESTART; + sigaction(signum, &new_action, &old_action); + return old_action.sa_handler; +} } diff --git a/src/event_manager.hh b/src/event_manager.hh index 3bc3f192..d6b8412a 100644 --- a/src/event_manager.hh +++ b/src/event_manager.hh @@ -14,6 +14,8 @@ namespace Kakoune { +typedef void(*SignalHandler)(int); + enum class EventMode { Normal, @@ -92,6 +94,8 @@ private: TimePoint m_last; }; +SignalHandler set_signal_wrapper(int signum, SignalHandler handler); + } #endif // event_manager_hh_INCLUDED diff --git a/src/main.cc b/src/main.cc index 6e99e12d..7696b5f1 100644 --- a/src/main.cc +++ b/src/main.cc @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -292,16 +291,16 @@ std::unique_ptr create_local_ui(bool dummy_ui) { LocalUI() { - m_old_sighup = signal(SIGHUP, [](int) { + m_old_sighup = set_signal_wrapper(SIGHUP, [](int) { ClientManager::instance().remove_client(*local_client, false); }); - m_old_sigtstp = signal(SIGTSTP, [](int) { + m_old_sigtstp = set_signal_wrapper(SIGTSTP, [](int) { if (ClientManager::instance().count() == 1 and *ClientManager::instance().begin() == local_client) { // Suspend normally if we are the only client - auto current = signal(SIGTSTP, static_cast(local_client->ui()).m_old_sigtstp); + auto current = set_signal_wrapper(SIGTSTP, static_cast(local_client->ui()).m_old_sigtstp); sigset_t unblock_sigtstp, old_mask; sigemptyset(&unblock_sigtstp); @@ -312,7 +311,7 @@ std::unique_ptr create_local_ui(bool dummy_ui) sigprocmask(SIG_SETMASK, &old_mask, nullptr); - signal(SIGTSTP, current); + set_signal_wrapper(SIGTSTP, current); } else convert_to_client_pending = true; @@ -321,8 +320,8 @@ std::unique_ptr create_local_ui(bool dummy_ui) ~LocalUI() { - signal(SIGHUP, m_old_sighup); - signal(SIGTSTP, m_old_sigtstp); + set_signal_wrapper(SIGHUP, m_old_sighup); + set_signal_wrapper(SIGTSTP, m_old_sigtstp); local_client = nullptr; if (not convert_to_client_pending and not ClientManager::instance().empty()) @@ -430,7 +429,7 @@ int run_server(StringView session, StringView init_command, session, child)); exit(0); } - signal(SIGTERM, [](int) { terminate = true; }); + set_signal_wrapper(SIGTERM, [](int) { terminate = true; }); } StringRegistry string_registry; @@ -652,13 +651,13 @@ int main(int argc, char* argv[]) { setlocale(LC_ALL, ""); - signal(SIGSEGV, signal_handler); - signal(SIGFPE, signal_handler); - signal(SIGQUIT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGPIPE, SIG_IGN); - signal(SIGINT, [](int){}); - signal(SIGCHLD, [](int){}); + set_signal_wrapper(SIGSEGV, signal_handler); + set_signal_wrapper(SIGFPE, signal_handler); + set_signal_wrapper(SIGQUIT, signal_handler); + set_signal_wrapper(SIGTERM, signal_handler); + set_signal_wrapper(SIGPIPE, SIG_IGN); + set_signal_wrapper(SIGINT, [](int){}); + set_signal_wrapper(SIGCHLD, [](int){}); Vector params; for (size_t i = 1; i < argc; ++i) diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc index 5f39260f..6ffa72d7 100644 --- a/src/ncurses_ui.cc +++ b/src/ncurses_ui.cc @@ -250,8 +250,8 @@ NCursesUI::NCursesUI() enable_mouse(true); - signal(SIGWINCH, on_term_resize); - signal(SIGCONT, on_term_resize); + set_signal_wrapper(SIGWINCH, on_term_resize); + set_signal_wrapper(SIGCONT, on_term_resize); check_resize(true); @@ -262,8 +262,8 @@ NCursesUI::~NCursesUI() { enable_mouse(false); endwin(); - signal(SIGWINCH, SIG_DFL); - signal(SIGCONT, SIG_DFL); + set_signal_wrapper(SIGWINCH, SIG_DFL); + set_signal_wrapper(SIGCONT, SIG_DFL); } void NCursesUI::Window::create(const CharCoord& p, const CharCoord& s)