Integrated signal handler from qpdfview
[pulseview.git] / signalhandler.cpp
1 /*
2
3 Copyright 2013 Adam Reichold
4
5 This file is part of qpdfview.
6
7 qpdfview is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
11
12 qpdfview is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with qpdfview.  If not, see <http://www.gnu.org/licenses/>.
19
20 */
21
22 #include "signalhandler.h"
23
24 #include <signal.h>
25 #include <sys/socket.h>
26 #include <unistd.h>
27
28 #include <QSocketNotifier>
29
30 int SignalHandler::s_sockets[2];
31
32 bool SignalHandler::prepareSignals()
33 {
34     if(socketpair(AF_UNIX, SOCK_STREAM, 0, s_sockets) != 0)
35     {
36         return false;
37     }
38
39     struct sigaction sigAction;
40
41     sigAction.sa_handler = SignalHandler::handleSignals;
42     sigemptyset(&sigAction.sa_mask);
43     sigAction.sa_flags = SA_RESTART;
44
45     if(sigaction(SIGINT, &sigAction, 0) != 0)
46     {
47         close(s_sockets[0]);
48         close(s_sockets[1]);
49
50         return false;
51     }
52
53     if(sigaction(SIGTERM, &sigAction, 0) != 0)
54     {
55         close(s_sockets[0]);
56         close(s_sockets[1]);
57
58         return false;
59     }
60
61     return true;
62 }
63
64 SignalHandler::SignalHandler(QObject* parent) : QObject(parent),
65     m_socketNotifier(0)
66 {
67     m_socketNotifier = new QSocketNotifier(s_sockets[1], QSocketNotifier::Read, this);
68     connect(m_socketNotifier, SIGNAL(activated(int)), SLOT(on_socketNotifier_activated()));
69 }
70
71 void SignalHandler::on_socketNotifier_activated()
72 {
73     m_socketNotifier->setEnabled(false);
74
75     int sigNumber;
76     read(s_sockets[1], &sigNumber, sizeof(int));
77
78     switch(sigNumber)
79     {
80     case SIGINT:
81         emit sigIntReceived();
82         break;
83     case SIGTERM:
84         emit sigTermReceived();
85         break;
86     }
87
88     m_socketNotifier->setEnabled(true);
89 }
90
91 void SignalHandler::handleSignals(int sigNumber)
92 {
93     write(s_sockets[0], &sigNumber, sizeof(int));
94 }