#include "signalhandle.h" #include #include #include #include #include int CatchSignals(const int signals[], size_t count, void (* signal_handler)(int)) { if (nullptr == signals || 0 == count || nullptr == signal_handler) { return EINVAL; // Invalid argument (POSIX.1) } struct sigaction action = {0}; action.sa_handler = signal_handler; action.sa_flags = 0; sigemptyset(&action.sa_mask); for (size_t i = 0; i < count; ++ i) { if (0 != sigaction(signals[i], &action, nullptr)) { return errno; } } return 0; } int CatchSignals(const int signals[], const size_t count, SigFunc f) { struct _ { typedef std::map SFMap; static SFMap &Funcs() { static SFMap m; return m; } static void OnSig(int sig) { auto pf = Funcs().find(sig); if (pf != Funcs().end() && pf->second) { pf->second(sig); } } }; for (int i = 0; i < int(count); ++i) { _::Funcs()[signals[i]] = f; } return CatchSignals(signals, count, &_::OnSig); } int WaitForSignals(const int signals[], const size_t count, SigFunc f) { std::mutex mtx; std::condition_variable cv; auto OnSig = [&](int sig) { static std::atomic first(true); if (first.exchange(false)) { std::unique_lock guard(mtx); if (f) { f(sig); } cv.notify_one(); } }; std::unique_lock guard(mtx); const int r = CatchSignals(signals, count, OnSig); if (r == 0) { // register handler. cv.wait(guard); } return r; }