2020-05-30 06:06:16 +02:00
|
|
|
#pragma once
|
|
|
|
#include <csignal>
|
2023-04-13 15:50:13 +02:00
|
|
|
#include <cstring>
|
2020-05-30 06:06:16 +02:00
|
|
|
#include <functional>
|
|
|
|
#include <mutex>
|
2023-04-13 15:50:13 +02:00
|
|
|
|
2022-09-23 01:27:12 +02:00
|
|
|
#include "logging/oxen_logger.h"
|
2022-09-26 04:09:54 +02:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include "windows.h"
|
|
|
|
#endif
|
|
|
|
|
2020-05-30 06:06:16 +02:00
|
|
|
namespace tools {
|
|
|
|
|
2023-04-13 15:50:13 +02:00
|
|
|
/*! \brief Defines a singleton signal handler for win32 and *nix
|
|
|
|
*/
|
|
|
|
class signal_handler {
|
2020-05-30 06:06:16 +02:00
|
|
|
public:
|
|
|
|
/*! \brief installs a signal handler */
|
2023-04-13 15:50:13 +02:00
|
|
|
template <typename T>
|
|
|
|
static bool install(T t) {
|
2022-09-26 04:09:54 +02:00
|
|
|
#ifdef _WIN32
|
2023-04-13 15:50:13 +02:00
|
|
|
bool r = TRUE == ::SetConsoleCtrlHandler(&win_handler, TRUE);
|
|
|
|
if (r) {
|
|
|
|
m_handler = t;
|
|
|
|
}
|
|
|
|
return r;
|
2020-05-30 06:06:16 +02:00
|
|
|
#else
|
2023-04-13 15:50:13 +02:00
|
|
|
static struct sigaction sa;
|
|
|
|
memset(&sa, 0, sizeof(struct sigaction));
|
|
|
|
sa.sa_handler = posix_handler;
|
|
|
|
sa.sa_flags = 0;
|
|
|
|
/* Only blocks SIGINT, SIGTERM and SIGPIPE */
|
|
|
|
sigaction(SIGINT, &sa, NULL);
|
|
|
|
signal(SIGTERM, posix_handler);
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
m_handler = t;
|
|
|
|
return true;
|
2020-05-30 06:06:16 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
#if defined(WIN32)
|
|
|
|
/*! \brief Handler for win */
|
2023-04-13 15:50:13 +02:00
|
|
|
static BOOL WINAPI win_handler(DWORD type) {
|
|
|
|
if (CTRL_C_EVENT == type || CTRL_BREAK_EVENT == type) {
|
|
|
|
handle_signal(type);
|
|
|
|
} else {
|
|
|
|
log::info(
|
|
|
|
globallogcat,
|
|
|
|
fg(fmt::terminal_color::red),
|
|
|
|
"Got control signal {}. Exiting without saving...",
|
|
|
|
type);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
2020-05-30 06:06:16 +02:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
/*! \brief handler for NIX */
|
2023-04-13 15:50:13 +02:00
|
|
|
static void posix_handler(int type) {
|
|
|
|
handle_signal(type);
|
2020-05-30 06:06:16 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*! \brief calles m_handler */
|
2023-04-13 15:50:13 +02:00
|
|
|
static void handle_signal(int type) {
|
|
|
|
static std::mutex m_mutex;
|
|
|
|
std::unique_lock lock{m_mutex};
|
|
|
|
m_handler(type);
|
2020-05-30 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*! \brief where the installed handler is stored */
|
|
|
|
static inline std::function<void(int)> m_handler;
|
2023-04-13 15:50:13 +02:00
|
|
|
};
|
2020-05-30 06:06:16 +02:00
|
|
|
|
2023-04-13 15:50:13 +02:00
|
|
|
} // namespace tools
|