#include #if defined(Q_OS_UNIX) # include "common/QLogging.hpp" # include "util/UnixSignalHandler.hpp" # include # include # include # include # include namespace { using namespace chatterino; std::unordered_map> HANDLERS{}; } // namespace namespace chatterino { UnixSignalHandler::UnixSignalHandler(int signal) { if (::socketpair(AF_UNIX, SOCK_STREAM, 0, this->fd.data()) != 0) { qCWarning(chatterinoApp) << "Failed to create UnixSignalHandler for" << signal; return; } this->socketNotifier = new QSocketNotifier(this->fd[1], QSocketNotifier::Read, this); QObject::connect(this->socketNotifier, &QSocketNotifier::activated, this, &UnixSignalHandler::handleSignal); struct sigaction action; action.sa_handler = UnixSignalHandler::fired; sigemptyset(&action.sa_mask); action.sa_flags = 0; action.sa_flags |= SA_RESTART; if (sigaction(signal, &action, nullptr) != 0) { qCWarning(chatterinoApp) << "Failed to listen to signal for" << signal; return; } HANDLERS[signal] = QPointer(this); } void UnixSignalHandler::fired(int signal) { const auto &cls = HANDLERS[signal]; assert(!cls.isNull()); if (cls.isNull()) { qCWarning(chatterinoApp) << "unix signal fired without a registered handler"; return; } char a = 1; ::write(cls->fd[0], &a, sizeof(a)); } void UnixSignalHandler::handleSignal() { this->socketNotifier->setEnabled(false); char tmp{}; ::read(this->fd[1], &tmp, sizeof(tmp)); this->socketNotifier->setEnabled(true); this->signalFired(); } } // namespace chatterino #endif