Skip to content

Instantly share code, notes, and snippets.

@ajakubek
Created December 31, 2016 01:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajakubek/f6c02bc5bd3096ad47b5bce6fcd66d84 to your computer and use it in GitHub Desktop.
Save ajakubek/f6c02bc5bd3096ad47b5bce6fcd66d84 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <signal.h>
#include "signal_guard.hpp"
int main()
{
signal_guard sg(SIGINT);
while (!sg.timed_wait(std::chrono::milliseconds(500)))
std::cout << '.' << std::flush;
std::cout << "\nSignal received\n";
return 0;
}
#ifndef SIGNAL_GUARD_HPP
#define SIGNAL_GUARD_HPP
#include <chrono>
#include <system_error>
#include <errno.h>
#include <signal.h>
class signal_guard
{
public:
explicit signal_guard(int sig_num)
{
sigemptyset(&current_mask);
if (sigaddset(&current_mask, sig_num) < 0)
throw_system_error();
if (sigprocmask(SIG_SETMASK, &current_mask, &old_mask) < 0)
throw_system_error();
}
~signal_guard()
{
sigprocmask(SIG_SETMASK, &old_mask, nullptr);
}
bool timed_wait(std::chrono::nanoseconds duration)
{
const struct timespec ts = { 0, duration.count() };
if (sigtimedwait(&current_mask, nullptr, &ts) >= 0)
return true;
if (errno == EAGAIN)
return false;
throw_system_error();
}
private:
static [[noreturn]] void throw_system_error() const
{
throw std::system_error(errno, std::system_category());
}
sigset_t current_mask;
sigset_t old_mask;
};
#endif // SIGNAL_GUARD_HPP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment