@@ -0,0 +1,141 @@
2+ * Copyright (C) 2015 Canonical, Ltd.
4+ * This program is free software: you can redistribute it and/or modify it
5+ * under the terms of the GNU General Public License version 3, as published
6+ * by the Free Software Foundation.
8+ * This program is distributed in the hope that it will be useful, but
9+ * WITHOUT ANY WARRANTY; without even the implied warranties of
10+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11+ * PURPOSE. See the GNU General Public License for more details.
13+ * You should have received a copy of the GNU General Public License along
14+ * with this program. If not, see <http://www.gnu.org/licenses/>.
16+ * Author: Marcus Tomlinson <marcus.tomlinson@canonical.com>
19+#include "unix-signal-handler.h"
24+#include <sys/socket.h>
27+int UnixSignalHandler::sighupFd[2];
28+int UnixSignalHandler::sigintFd[2];
29+int UnixSignalHandler::sigtermFd[2];
31+UnixSignalHandler::UnixSignalHandler(const std::function<void()>& f, QObject *parent)
35+ if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sighupFd))
37+ qFatal("Couldn't create HUP socketpair");
39+ if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigintFd))
41+ qFatal("Couldn't create INT socketpair");
43+ if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigtermFd))
45+ qFatal("Couldn't create TERM socketpair");
48+ m_socketNotifierHup = new QSocketNotifier(sighupFd[1], QSocketNotifier::Read, this);
49+ connect(m_socketNotifierHup, &QSocketNotifier::activated, this, &UnixSignalHandler::handleSigHup);
50+ m_socketNotifierInt = new QSocketNotifier(sigintFd[1], QSocketNotifier::Read, this);
51+ connect(m_socketNotifierInt, &QSocketNotifier::activated, this, &UnixSignalHandler::handleSigInt);
52+ m_socketNotifierTerm = new QSocketNotifier(sigtermFd[1], QSocketNotifier::Read, this);
53+ connect(m_socketNotifierTerm, &QSocketNotifier::activated, this, &UnixSignalHandler::handleSigTerm);
56+void UnixSignalHandler::hupSignalHandler(int)
59+ ::write(sighupFd[0], &a, sizeof(a));
62+void UnixSignalHandler::intSignalHandler(int)
65+ ::write(sigintFd[0], &a, sizeof(a));
68+void UnixSignalHandler::termSignalHandler(int)
71+ ::write(sigtermFd[0], &a, sizeof(a));
74+int UnixSignalHandler::setupUnixSignalHandlers()
76+ struct sigaction sighup, sigint, sigterm;
78+ sighup.sa_handler = UnixSignalHandler::hupSignalHandler;
79+ sigemptyset(&sighup.sa_mask);
81+ sighup.sa_flags |= SA_RESTART;
83+ if (sigaction(SIGHUP, &sighup, 0) > 0)
88+ sigint.sa_handler = UnixSignalHandler::intSignalHandler;
89+ sigemptyset(&sigint.sa_mask);
91+ sigint.sa_flags |= SA_RESTART;
93+ if (sigaction(SIGINT, &sigint, 0) > 0)
98+ sigterm.sa_handler = UnixSignalHandler::termSignalHandler;
99+ sigemptyset(&sigterm.sa_mask);
100+ sigterm.sa_flags |= SA_RESTART;
102+ if (sigaction(SIGTERM, &sigterm, 0) > 0)
110+void UnixSignalHandler::handleSigHup()
112+ m_socketNotifierHup->setEnabled(false);
114+ ::read(sighupFd[1], &tmp, sizeof(tmp));
118+ m_socketNotifierHup->setEnabled(true);
121+void UnixSignalHandler::handleSigInt()
123+ m_socketNotifierInt->setEnabled(false);
125+ ::read(sigintFd[1], &tmp, sizeof(tmp));
129+ m_socketNotifierInt->setEnabled(true);
132+void UnixSignalHandler::handleSigTerm()
134+ m_socketNotifierTerm->setEnabled(false);
136+ ::read(sigtermFd[1], &tmp, sizeof(tmp));
140+ m_socketNotifierTerm->setEnabled(true);