Skip to content

Instantly share code, notes, and snippets.

@suy
Created January 30, 2014 11:48
Show Gist options
  • Save suy/8706936 to your computer and use it in GitHub Desktop.
Save suy/8706936 to your computer and use it in GitHub Desktop.
#include "unixsignal.h"
#include <signal.h>
#include <sys/signalfd.h>
#include <unistd.h>
#include <QSocketNotifier>
UnixSignal::UnixSignal(int signal, QObject *parent) :
QObject(parent)
{
sigset_t signal_set;
// Mask only the signal number passed as argument.
sigemptyset(&signal_set);
sigaddset(&signal_set, signal);
// SIG_BLOCK means the calling thread will block the already blocked signals
// plus the ones (one actually) we are passing in our signal set.
// SIG_SETMASK would clear other signals, AIUI.
// Note though: "The use of sigprocmask() is unspecified in a multithreaded
// process; see pthread_sigmask(3)."
if (pthread_sigmask(SIG_BLOCK, &signal_set, NULL) != 0) {
qFatal("Could not mask signal %d: %s", signal, strerror(errno));
}
// -1 -> create a new file descriptor instead of reusing an existing one.
// 0 -> flags to the call. Could be SFD_NONBLOCK or SFD_CLOEXEC.
descriptor = signalfd(-1, &signal_set, 0);
if (descriptor < 0) {
qFatal("Invalid descriptor from signalfd: %s", strerror(errno));
}
QSocketNotifier *sn = new QSocketNotifier(descriptor, QSocketNotifier::Read, this);
connect(sn, &QSocketNotifier::activated, this, &UnixSignal::handleSignal);
}
void UnixSignal::handleSignal()
{
struct signalfd_siginfo info;
::read(descriptor, &info, sizeof(info));
emit triggered();
}
#ifndef UNIXSIGNAL_H
#define UNIXSIGNAL_H
#include <QObject>
class UnixSignal : public QObject
{
Q_OBJECT
public:
explicit UnixSignal(int signal, QObject *parent = 0);
signals:
void triggered();
private slots:
void handleSignal();
private:
int descriptor;
};
#endif // UNIXSIGNAL_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment