Servatrice: refactor signal handling and permit config reloading
This commit is contained in:
parent
9947af7be9
commit
6cf3db7e6b
12 changed files with 163 additions and 95 deletions
|
@ -58,10 +58,13 @@ TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool
|
||||||
connect(updateServerMessageButton, SIGNAL(clicked()), this, SLOT(actUpdateServerMessage()));
|
connect(updateServerMessageButton, SIGNAL(clicked()), this, SLOT(actUpdateServerMessage()));
|
||||||
shutdownServerButton = new QPushButton;
|
shutdownServerButton = new QPushButton;
|
||||||
connect(shutdownServerButton, SIGNAL(clicked()), this, SLOT(actShutdownServer()));
|
connect(shutdownServerButton, SIGNAL(clicked()), this, SLOT(actShutdownServer()));
|
||||||
|
reloadConfigButton = new QPushButton;
|
||||||
|
connect(reloadConfigButton, SIGNAL(clicked()), this, SLOT(actReloadConfig()));
|
||||||
|
|
||||||
QVBoxLayout *vbox = new QVBoxLayout;
|
QVBoxLayout *vbox = new QVBoxLayout;
|
||||||
vbox->addWidget(updateServerMessageButton);
|
vbox->addWidget(updateServerMessageButton);
|
||||||
vbox->addWidget(shutdownServerButton);
|
vbox->addWidget(shutdownServerButton);
|
||||||
|
vbox->addWidget(reloadConfigButton);
|
||||||
vbox->addStretch();
|
vbox->addStretch();
|
||||||
|
|
||||||
adminGroupBox = new QGroupBox;
|
adminGroupBox = new QGroupBox;
|
||||||
|
@ -87,6 +90,7 @@ void TabAdmin::retranslateUi()
|
||||||
{
|
{
|
||||||
updateServerMessageButton->setText(tr("Update server &message"));
|
updateServerMessageButton->setText(tr("Update server &message"));
|
||||||
shutdownServerButton->setText(tr("&Shut down server"));
|
shutdownServerButton->setText(tr("&Shut down server"));
|
||||||
|
reloadConfigButton->setText(tr("&Reload configuration"));
|
||||||
adminGroupBox->setTitle(tr("Server administration functions"));
|
adminGroupBox->setTitle(tr("Server administration functions"));
|
||||||
|
|
||||||
unlockButton->setText(tr("&Unlock functions"));
|
unlockButton->setText(tr("&Unlock functions"));
|
||||||
|
@ -110,6 +114,12 @@ void TabAdmin::actShutdownServer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabAdmin::actReloadConfig()
|
||||||
|
{
|
||||||
|
Command_ReloadConfig cmd;
|
||||||
|
client->sendCommand(client->prepareAdminCommand(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
void TabAdmin::actUnlock()
|
void TabAdmin::actUnlock()
|
||||||
{
|
{
|
||||||
if (QMessageBox::question(this, tr("Unlock administration functions"), tr("Do you really want to unlock the administration functions?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
if (QMessageBox::question(this, tr("Unlock administration functions"), tr("Do you really want to unlock the administration functions?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ private:
|
||||||
bool locked;
|
bool locked;
|
||||||
AbstractClient *client;
|
AbstractClient *client;
|
||||||
bool fullAdmin;
|
bool fullAdmin;
|
||||||
QPushButton *updateServerMessageButton, *shutdownServerButton;
|
QPushButton *updateServerMessageButton, *shutdownServerButton, *reloadConfigButton;
|
||||||
QGroupBox *adminGroupBox;
|
QGroupBox *adminGroupBox;
|
||||||
QPushButton *unlockButton, *lockButton;
|
QPushButton *unlockButton, *lockButton;
|
||||||
signals:
|
signals:
|
||||||
|
@ -36,6 +36,7 @@ signals:
|
||||||
private slots:
|
private slots:
|
||||||
void actUpdateServerMessage();
|
void actUpdateServerMessage();
|
||||||
void actShutdownServer();
|
void actShutdownServer();
|
||||||
|
void actReloadConfig();
|
||||||
|
|
||||||
void actUnlock();
|
void actUnlock();
|
||||||
void actLock();
|
void actLock();
|
||||||
|
|
|
@ -2,6 +2,7 @@ message AdminCommand {
|
||||||
enum AdminCommandType {
|
enum AdminCommandType {
|
||||||
UPDATE_SERVER_MESSAGE = 1000;
|
UPDATE_SERVER_MESSAGE = 1000;
|
||||||
SHUTDOWN_SERVER = 1001;
|
SHUTDOWN_SERVER = 1001;
|
||||||
|
RELOAD_CONFIG = 1002;
|
||||||
}
|
}
|
||||||
extensions 100 to max;
|
extensions 100 to max;
|
||||||
}
|
}
|
||||||
|
@ -19,3 +20,9 @@ message Command_ShutdownServer {
|
||||||
optional string reason = 1;
|
optional string reason = 1;
|
||||||
optional uint32 minutes = 2;
|
optional uint32 minutes = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Command_ReloadConfig {
|
||||||
|
extend AdminCommand {
|
||||||
|
optional Command_ReloadConfig ext = 1002;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ SET(servatrice_SOURCES
|
||||||
src/serversocketinterface.cpp
|
src/serversocketinterface.cpp
|
||||||
src/settingscache.cpp
|
src/settingscache.cpp
|
||||||
src/isl_interface.cpp
|
src/isl_interface.cpp
|
||||||
|
src/signalhandler.cpp
|
||||||
${VERSION_STRING_CPP}
|
${VERSION_STRING_CPP}
|
||||||
src/smtp/emailaddress.cpp
|
src/smtp/emailaddress.cpp
|
||||||
src/smtp/mimeattachment.cpp
|
src/smtp/mimeattachment.cpp
|
||||||
|
|
|
@ -28,21 +28,16 @@
|
||||||
#include "servatrice.h"
|
#include "servatrice.h"
|
||||||
#include "server_logger.h"
|
#include "server_logger.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
|
#include "signalhandler.h"
|
||||||
#include "rng_sfmt.h"
|
#include "rng_sfmt.h"
|
||||||
#include "version_string.h"
|
#include "version_string.h"
|
||||||
#include <google/protobuf/stubs/common.h>
|
#include <google/protobuf/stubs/common.h>
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
#include <signal.h>
|
|
||||||
#include <execinfo.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SIGSEGV_TRACE_LINES 40
|
|
||||||
|
|
||||||
RNG_Abstract *rng;
|
RNG_Abstract *rng;
|
||||||
ServerLogger *logger;
|
ServerLogger *logger;
|
||||||
QThread *loggerThread;
|
QThread *loggerThread;
|
||||||
SettingsCache *settingsCache;
|
SettingsCache *settingsCache;
|
||||||
|
SignalHandler *signalhandler;
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
|
|
||||||
|
@ -55,9 +50,6 @@ void myMessageOutput2(QtMsgType type, const char *msg);
|
||||||
void myMessageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg);
|
void myMessageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg);
|
||||||
void myMessageOutput2(QtMsgType type, const QMessageLogContext &, const QString &msg);
|
void myMessageOutput2(QtMsgType type, const QMessageLogContext &, const QString &msg);
|
||||||
#endif
|
#endif
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
void sigSegvHandler(int sig);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Implementations */
|
/* Implementations */
|
||||||
|
|
||||||
|
@ -130,32 +122,6 @@ void myMessageOutput2(QtMsgType /*type*/, const QMessageLogContext &, const QStr
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
void sigSegvHandler(int sig)
|
|
||||||
{
|
|
||||||
void *array[SIGSEGV_TRACE_LINES];
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
// get void*'s for all entries on the stack
|
|
||||||
size = backtrace(array, SIGSEGV_TRACE_LINES);
|
|
||||||
|
|
||||||
// print out all the frames to stderr
|
|
||||||
fprintf(stderr, "Error: signal %d:\n", sig);
|
|
||||||
backtrace_symbols_fd(array, size, STDERR_FILENO);
|
|
||||||
|
|
||||||
if (sig == SIGSEGV)
|
|
||||||
logger->logMessage("CRASH: SIGSEGV");
|
|
||||||
else if (sig == SIGABRT)
|
|
||||||
logger->logMessage("CRASH: SIGABRT");
|
|
||||||
|
|
||||||
logger->deleteLater();
|
|
||||||
loggerThread->wait();
|
|
||||||
delete loggerThread;
|
|
||||||
|
|
||||||
raise(sig);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
@ -202,23 +168,8 @@ int main(int argc, char *argv[])
|
||||||
qInstallMessageHandler(myMessageOutput2);
|
qInstallMessageHandler(myMessageOutput2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
signalhandler = new SignalHandler();
|
||||||
struct sigaction hup;
|
|
||||||
hup.sa_handler = ServerLogger::hupSignalHandler;
|
|
||||||
sigemptyset(&hup.sa_mask);
|
|
||||||
hup.sa_flags = 0;
|
|
||||||
hup.sa_flags |= SA_RESTART;
|
|
||||||
sigaction(SIGHUP, &hup, 0);
|
|
||||||
|
|
||||||
struct sigaction segv;
|
|
||||||
segv.sa_handler = sigSegvHandler;
|
|
||||||
segv.sa_flags = SA_RESETHAND;
|
|
||||||
sigemptyset(&segv.sa_mask);
|
|
||||||
sigaction(SIGSEGV, &segv, 0);
|
|
||||||
sigaction(SIGABRT, &segv, 0);
|
|
||||||
|
|
||||||
signal(SIGPIPE, SIG_IGN);
|
|
||||||
#endif
|
|
||||||
rng = new RNG_SFMT;
|
rng = new RNG_SFMT;
|
||||||
|
|
||||||
std::cerr << "Servatrice " << VERSION_STRING << " starting." << std::endl;
|
std::cerr << "Servatrice " << VERSION_STRING << " starting." << std::endl;
|
||||||
|
@ -250,6 +201,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
delete rng;
|
delete rng;
|
||||||
|
delete signalhandler;
|
||||||
delete settingsCache;
|
delete settingsCache;
|
||||||
|
|
||||||
logger->deleteLater();
|
logger->deleteLater();
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
#define MAIN_H
|
#define MAIN_H
|
||||||
|
|
||||||
class ServerLogger;
|
class ServerLogger;
|
||||||
|
class QThread;
|
||||||
|
class SettingsCache;
|
||||||
|
|
||||||
extern ServerLogger *logger;
|
extern ServerLogger *logger;
|
||||||
|
extern QThread *loggerThread;
|
||||||
|
extern SettingsCache *settingsCache;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
#include "server_logger.h"
|
#include "server_logger.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
#include <QSocketNotifier>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <sys/socket.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ServerLogger::ServerLogger(bool _logToConsole, QObject *parent)
|
ServerLogger::ServerLogger(bool _logToConsole, QObject *parent)
|
||||||
: QObject(parent), logToConsole(_logToConsole), flushRunning(false)
|
: QObject(parent), logToConsole(_logToConsole), flushRunning(false)
|
||||||
|
@ -44,13 +38,6 @@ void ServerLogger::startLog(const QString &logFileName)
|
||||||
logFile = 0;
|
logFile = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD);
|
|
||||||
|
|
||||||
snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this);
|
|
||||||
connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup()));
|
|
||||||
#endif
|
|
||||||
} else
|
} else
|
||||||
logFile = 0;
|
logFile = 0;
|
||||||
|
|
||||||
|
@ -119,35 +106,13 @@ void ServerLogger::flushBuffer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerLogger::hupSignalHandler(int /*unused*/)
|
void ServerLogger::rotateLogs()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
if (!logFile)
|
if (!logFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char a = 1;
|
|
||||||
ssize_t writeValue = ::write(sigHupFD[0], &a, sizeof(a));
|
|
||||||
Q_UNUSED(writeValue);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerLogger::handleSigHup()
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
if (!logFile)
|
|
||||||
return;
|
|
||||||
|
|
||||||
snHup->setEnabled(false);
|
|
||||||
char tmp;
|
|
||||||
ssize_t readValue = ::read(sigHupFD[1], &tmp, sizeof(tmp));
|
|
||||||
Q_UNUSED(readValue);
|
|
||||||
|
|
||||||
logFile->close();
|
logFile->close();
|
||||||
logFile->open(QIODevice::Append);
|
logFile->open(QIODevice::Append);
|
||||||
|
|
||||||
snHup->setEnabled(true);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile *ServerLogger::logFile;
|
QFile *ServerLogger::logFile;
|
||||||
int ServerLogger::sigHupFD[2];
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
class QSocketNotifier;
|
|
||||||
class QFile;
|
class QFile;
|
||||||
class Server_ProtocolHandler;
|
class Server_ProtocolHandler;
|
||||||
|
|
||||||
|
@ -16,19 +15,16 @@ class ServerLogger : public QObject {
|
||||||
public:
|
public:
|
||||||
ServerLogger(bool _logToConsole, QObject *parent = 0);
|
ServerLogger(bool _logToConsole, QObject *parent = 0);
|
||||||
~ServerLogger();
|
~ServerLogger();
|
||||||
static void hupSignalHandler(int unused);
|
|
||||||
public slots:
|
public slots:
|
||||||
void startLog(const QString &logFileName);
|
void startLog(const QString &logFileName);
|
||||||
void logMessage(QString message, void *caller = 0);
|
void logMessage(QString message, void *caller = 0);
|
||||||
|
void rotateLogs();
|
||||||
private slots:
|
private slots:
|
||||||
void handleSigHup();
|
|
||||||
void flushBuffer();
|
void flushBuffer();
|
||||||
signals:
|
signals:
|
||||||
void sigFlushBuffer();
|
void sigFlushBuffer();
|
||||||
private:
|
private:
|
||||||
bool logToConsole;
|
bool logToConsole;
|
||||||
static int sigHupFD[2];
|
|
||||||
QSocketNotifier *snHup;
|
|
||||||
static QFile *logFile;
|
static QFile *logFile;
|
||||||
bool flushRunning;
|
bool flushRunning;
|
||||||
QStringList buffer;
|
QStringList buffer;
|
||||||
|
|
|
@ -289,6 +289,7 @@ Response::ResponseCode ServerSocketInterface::processExtendedAdminCommand(int cm
|
||||||
switch ((AdminCommand::AdminCommandType) cmdType) {
|
switch ((AdminCommand::AdminCommandType) cmdType) {
|
||||||
case AdminCommand::SHUTDOWN_SERVER: return cmdShutdownServer(cmd.GetExtension(Command_ShutdownServer::ext), rc);
|
case AdminCommand::SHUTDOWN_SERVER: return cmdShutdownServer(cmd.GetExtension(Command_ShutdownServer::ext), rc);
|
||||||
case AdminCommand::UPDATE_SERVER_MESSAGE: return cmdUpdateServerMessage(cmd.GetExtension(Command_UpdateServerMessage::ext), rc);
|
case AdminCommand::UPDATE_SERVER_MESSAGE: return cmdUpdateServerMessage(cmd.GetExtension(Command_UpdateServerMessage::ext), rc);
|
||||||
|
case AdminCommand::RELOAD_CONFIG: return cmdReloadConfig(cmd.GetExtension(Command_ReloadConfig::ext), rc);
|
||||||
default: return Response::RespFunctionNotAllowed;
|
default: return Response::RespFunctionNotAllowed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -956,3 +957,9 @@ Response::ResponseCode ServerSocketInterface::cmdShutdownServer(const Command_Sh
|
||||||
QMetaObject::invokeMethod(server, "scheduleShutdown", Q_ARG(QString, QString::fromStdString(cmd.reason())), Q_ARG(int, cmd.minutes()));
|
QMetaObject::invokeMethod(server, "scheduleShutdown", Q_ARG(QString, QString::fromStdString(cmd.reason())), Q_ARG(int, cmd.minutes()));
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Response::ResponseCode ServerSocketInterface::cmdReloadConfig(const Command_ReloadConfig &cmd, ResponseContainer & /*rc*/)
|
||||||
|
{
|
||||||
|
settingsCache->sync();
|
||||||
|
return Response::RespOk;
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ class Command_ReplayDeleteMatch;
|
||||||
class Command_BanFromServer;
|
class Command_BanFromServer;
|
||||||
class Command_UpdateServerMessage;
|
class Command_UpdateServerMessage;
|
||||||
class Command_ShutdownServer;
|
class Command_ShutdownServer;
|
||||||
|
class Command_ReloadConfig;
|
||||||
|
|
||||||
class ServerSocketInterface : public Server_ProtocolHandler
|
class ServerSocketInterface : public Server_ProtocolHandler
|
||||||
{
|
{
|
||||||
|
@ -94,6 +95,7 @@ private:
|
||||||
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /* rc */);
|
Response::ResponseCode cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /* rc */);
|
||||||
|
Response::ResponseCode cmdReloadConfig(const Command_ReloadConfig &cmd, ResponseContainer & /*rc*/);
|
||||||
|
|
||||||
Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc);
|
Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc);
|
Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc);
|
||||||
|
|
98
servatrice/src/signalhandler.cpp
Normal file
98
servatrice/src/signalhandler.cpp
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
#include <QSocketNotifier>
|
||||||
|
|
||||||
|
#include "signalhandler.h"
|
||||||
|
#include "server_logger.h"
|
||||||
|
#include "settingscache.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdio>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SIGSEGV_TRACE_LINES 40
|
||||||
|
|
||||||
|
int SignalHandler::sigHupFD[2];
|
||||||
|
|
||||||
|
SignalHandler::SignalHandler(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
::socketpair(AF_UNIX, SOCK_STREAM, 0, sigHupFD);
|
||||||
|
|
||||||
|
snHup = new QSocketNotifier(sigHupFD[1], QSocketNotifier::Read, this);
|
||||||
|
connect(snHup, SIGNAL(activated(int)), this, SLOT(internalSigHupHandler()));
|
||||||
|
|
||||||
|
struct sigaction hup;
|
||||||
|
hup.sa_handler = SignalHandler::sigHupHandler;
|
||||||
|
sigemptyset(&hup.sa_mask);
|
||||||
|
hup.sa_flags = 0;
|
||||||
|
hup.sa_flags |= SA_RESTART;
|
||||||
|
sigaction(SIGHUP, &hup, 0);
|
||||||
|
|
||||||
|
struct sigaction segv;
|
||||||
|
segv.sa_handler = SignalHandler::sigSegvHandler;
|
||||||
|
segv.sa_flags = SA_RESETHAND;
|
||||||
|
sigemptyset(&segv.sa_mask);
|
||||||
|
sigaction(SIGSEGV, &segv, 0);
|
||||||
|
sigaction(SIGABRT, &segv, 0);
|
||||||
|
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalHandler::sigHupHandler(int /* sig */)
|
||||||
|
{
|
||||||
|
char a = 1;
|
||||||
|
ssize_t writeValue = ::write(sigHupFD[0], &a, sizeof(a));
|
||||||
|
Q_UNUSED(writeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalHandler::internalSigHupHandler()
|
||||||
|
{
|
||||||
|
snHup->setEnabled(false);
|
||||||
|
char tmp;
|
||||||
|
ssize_t readValue = ::read(sigHupFD[1], &tmp, sizeof(tmp));
|
||||||
|
Q_UNUSED(readValue);
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
std::cerr << "Received SIGHUP" << std::endl;
|
||||||
|
#endif
|
||||||
|
logger->logMessage("Received SIGHUP");
|
||||||
|
logger->rotateLogs();
|
||||||
|
|
||||||
|
settingsCache->sync();
|
||||||
|
|
||||||
|
snHup->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalHandler::sigSegvHandler(int sig)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
void *array[SIGSEGV_TRACE_LINES];
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
// get void*'s for all entries on the stack
|
||||||
|
size = backtrace(array, SIGSEGV_TRACE_LINES);
|
||||||
|
|
||||||
|
// print out all the frames to stderr
|
||||||
|
fprintf(stderr, "Error: signal %d:\n", sig);
|
||||||
|
backtrace_symbols_fd(array, size, STDERR_FILENO);
|
||||||
|
#endif
|
||||||
|
if (sig == SIGSEGV)
|
||||||
|
logger->logMessage("CRASH: SIGSEGV");
|
||||||
|
else if (sig == SIGABRT)
|
||||||
|
logger->logMessage("CRASH: SIGABRT");
|
||||||
|
|
||||||
|
logger->deleteLater();
|
||||||
|
loggerThread->wait();
|
||||||
|
delete loggerThread;
|
||||||
|
|
||||||
|
raise(sig);
|
||||||
|
}
|
||||||
|
|
24
servatrice/src/signalhandler.h
Normal file
24
servatrice/src/signalhandler.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef SIGNALHANDLER_H
|
||||||
|
#define SIGNALHANDLER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class QSocketNotifier;
|
||||||
|
|
||||||
|
class SignalHandler: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SignalHandler(QObject *parent = 0);
|
||||||
|
~SignalHandler() { };
|
||||||
|
static void sigHupHandler(int /* sig */);
|
||||||
|
static void sigSegvHandler(int sig);
|
||||||
|
private:
|
||||||
|
static int sigHupFD[2];
|
||||||
|
QSocketNotifier *snHup;
|
||||||
|
private slots:
|
||||||
|
void internalSigHupHandler();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue