3#include <QSocketNotifier>
4#include <QCoreApplication>
15#include <sys/socket.h>
29static const std::array<
const int, 6
38 SIGINT, SIGTERM, SIGSEGV, SIGABRT, SIGFPE, SIGILL,
50std::array<std::string,SIG_STR_COUNT>
sig_str;
57 sig_str[sig] = qPrintable(QString(
"Handling %1\n").arg(name));
62 for (
size_t i = 0; i <
sig_str.size(); i++)
63 sig_str_init(i, qPrintable(QString(
"Signal %1").arg(i)));
78 stack.ss_size = SIGSTKSZ;
81 if (sigaltstack(&stack,
nullptr) == -1)
83 std::cerr <<
"Couldn't create signal stack!" << std::endl;
88 if (::socketpair(AF_UNIX, SOCK_STREAM, 0,
s_sigFd.data()))
90 std::cerr <<
"Couldn't create socketpair" << std::endl;
120 int signum = it.key();
121 signal(signum, SIG_DFL);
156 const char *signame = strsignal(signum);
157 QString signal_name = signame ?
158 QString(signame) : QString(
"Unknown(%1)").arg(signum);
160 bool sa_handler_already_set =
false;
163 sa_handler_already_set =
m_sigMap.contains(signum);
164 if (
m_sigMap.value(signum,
nullptr) && (handler !=
nullptr))
166 LOG(VB_GENERAL, LOG_WARNING,
167 QString(
"Warning %1 signal handler overridden")
173 if (!sa_handler_already_set)
175 struct sigaction sa {};
177 sigemptyset(&sa.sa_mask);
178 sa.sa_flags = SA_RESTART | SA_SIGINFO;
180 sa.sa_flags |= SA_ONSTACK;
184 sigaction(signum, &sa,
nullptr);
187 LOG(VB_GENERAL, LOG_INFO, QString(
"Setup %1 handler").arg(signal_name));
201 [[maybe_unused]]
void *context)
207 signalInfo.m_code = 0;
208 signalInfo.m_pid = 0;
209 signalInfo.m_uid = 0;
210 signalInfo.m_value = 0;
212 signalInfo.m_code = (
info ?
info->si_code : 0);
213 signalInfo.m_pid = (
info ? (int)
info->si_pid : 0);
214 signalInfo.m_uid = (
info ? (int)
info->si_uid : 0);
215 signalInfo.m_value = (
info ?
info->si_value.sival_int : 0);
221 char *buffer = (
char *)&signalInfo;
252 signal(signum, SIG_DFL);
266 if (signum <
static_cast<int>(
sig_str.size()))
277 signal(signum, SIG_DFL);
289 bool infoComplete = (ret ==
sizeof(
SignalInfo));
290 int signum = (infoComplete ? signalInfo.m_signum : 0);
294 QString signame = strsignal(signum);
295 if (signame.isEmpty())
296 signame =
"Unknown Signal";
297 LOG(VB_GENERAL, LOG_CRIT,
298 QString(
"Received %1: Code %2, PID %3, UID %4, Value 0x%5")
299 .arg(signame) .arg(signalInfo.m_code) .arg(signalInfo.m_pid)
300 .arg(signalInfo.m_uid) .arg(signalInfo.m_value,8,16,QChar(
'0')));
304 bool allowNullHandler =
false;
307 if (signum == SIGRTMIN)
312 allowNullHandler =
true;
321 handler =
m_sigMap.value(signum,
nullptr);
327 QCoreApplication::exit(0);
340 handler =
m_sigMap.value(signum,
nullptr);
346 else if (!allowNullHandler)
348 LOG(VB_GENERAL, LOG_CRIT, QString(
"Received unexpected signal %1")
A container object to handle UNIX signals in the Qt space correctly.
static QMutex s_singletonLock
static std::array< int, 2 > s_sigFd
static SignalHandler * s_singleton
void SetHandlerPrivate(int signum, SigHandlerFunc handler)
QSocketNotifier * m_notifier
~SignalHandler() override
static void SetHandler(int signum, SigHandlerFunc handler)
static void signalHandler(int signum, siginfo_t *info, void *context)
QMap< int, SigHandlerFunc > m_sigMap
SignalHandler(QObject *parent)
static volatile bool s_exit_program
static void Init(QObject *parent=nullptr)
static const iso6937table * d
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
def read(device=None, features=[])
def write(text, progress=True)
static constexpr size_t SIG_STR_COUNT
static const std::array< const int, 6 > kDefaultSignalList
static void sig_str_init(size_t sig, const char *name)
std::array< std::string, SIG_STR_COUNT > sig_str
void(*)(void) SigHandlerFunc