X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcommon%2Fquassel.cpp;h=b7a6fbfb51c31205655c5e2b13b94e8875573233;hb=877a724cbb82479a3a260cf291a1d46b32cc0fa6;hp=646e8edddb2d5afe4df4924252b9f8d321594ad3;hpb=1f2784bfa1c1ce90defa32f13c78afd72c227bfd;p=quassel.git diff --git a/src/common/quassel.cpp b/src/common/quassel.cpp index 646e8edd..b7a6fbfb 100644 --- a/src/common/quassel.cpp +++ b/src/common/quassel.cpp @@ -23,13 +23,6 @@ #include #include -#include -#if !defined Q_OS_WIN && !defined Q_OS_MAC -# include -# include -# include -#endif - #include #include #include @@ -52,6 +45,12 @@ #include "syncableobject.h" #include "types.h" +#ifndef Q_OS_WIN +# include "posixsignalwatcher.h" +#else +# include "windowssignalwatcher.h" +#endif + #include "../../version.h" Quassel::Quassel() @@ -61,48 +60,15 @@ Quassel::Quassel() } -bool Quassel::init() +void Quassel::init(RunMode runMode) { - if (instance()->_initialized) - return true; // allow multiple invocations because of MonolithicApplication + _runMode = runMode; - // Setup signal handling - // TODO: Don't use unsafe methods, see handleSignal() - - // We catch SIGTERM and SIGINT (caused by Ctrl+C) to graceful shutdown Quassel. - signal(SIGTERM, handleSignal); - signal(SIGINT, handleSignal); -#ifndef Q_OS_WIN - // SIGHUP is used to reload configuration (i.e. SSL certificates) - // Windows does not support SIGHUP - signal(SIGHUP, handleSignal); -#endif - - if (instance()->_handleCrashes) { - // we have crashhandler for win32 and unix (based on execinfo). -#if defined(Q_OS_WIN) || defined(HAVE_EXECINFO) -# ifndef Q_OS_WIN - // we only handle crashes ourselves if coredumps are disabled - struct rlimit *limit = (rlimit *)malloc(sizeof(struct rlimit)); - int rc = getrlimit(RLIMIT_CORE, limit); - - if (rc == -1 || !((long)limit->rlim_cur > 0 || limit->rlim_cur == RLIM_INFINITY)) { -# endif /* Q_OS_WIN */ - signal(SIGABRT, handleSignal); - signal(SIGSEGV, handleSignal); -# ifndef Q_OS_WIN - signal(SIGBUS, handleSignal); - } - free(limit); -# endif /* Q_OS_WIN */ -#endif /* Q_OS_WIN || HAVE_EXECINFO */ - } - - instance()->_initialized = true; qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); - instance()->setupEnvironment(); - instance()->registerMetaTypes(); + setupSignalHandling(); + setupEnvironment(); + registerMetaTypes(); Network::setDefaultCodecForServer("UTF-8"); Network::setDefaultCodecForEncoding("UTF-8"); @@ -110,16 +76,16 @@ bool Quassel::init() if (isOptionSet("help")) { instance()->_cliParser->usage(); - return false; + return; } if (isOptionSet("version")) { std::cout << qPrintable("Quassel IRC: " + Quassel::buildInfo().plainVersionString) << std::endl; - return false; + return; } // Don't keep a debug log on the core - return instance()->logger()->setup(runMode() != RunMode::CoreOnly); + logger()->setup(runMode != RunMode::CoreOnly); } @@ -139,6 +105,7 @@ void Quassel::quit() // Protect against multiple invocations (e.g. triggered by MainWin::closeEvent()) if (!_quitting) { _quitting = true; + quInfo() << "Quitting..."; if (_quitHandlers.empty()) { QCoreApplication::quit(); } @@ -322,44 +289,41 @@ const Quassel::BuildInfo &Quassel::buildInfo() } -//! Signal handler for graceful shutdown. -//! @todo: Ensure this doesn't use unsafe methods (it does currently) -//! cf. QSocketNotifier, UnixSignalWatcher -void Quassel::handleSignal(int sig) +void Quassel::setupSignalHandling() { - switch (sig) { - case SIGTERM: - case SIGINT: - qWarning("%s", qPrintable(QString("Caught signal %1 - exiting.").arg(sig))); - instance()->quit(); - break; #ifndef Q_OS_WIN -// Windows does not support SIGHUP - case SIGHUP: - // Most applications use this as the 'configuration reload' command, e.g. nginx uses it for - // graceful reloading of processes. - quInfo() << "Caught signal" << SIGHUP << "- reloading configuration"; - if (instance()->reloadConfig()) { - quInfo() << "Successfully reloaded configuration"; - } - break; -#endif - case SIGABRT: - case SIGSEGV: -#ifndef Q_OS_WIN - case SIGBUS: + _signalWatcher = new PosixSignalWatcher(this); +#else + _signalWatcher = new WindowsSignalWatcher(this); #endif - instance()->logBacktrace(instance()->coreDumpFileName()); - exit(EXIT_FAILURE); - default: - ; - } + connect(_signalWatcher, SIGNAL(handleSignal(AbstractSignalWatcher::Action)), this, SLOT(handleSignal(AbstractSignalWatcher::Action))); } -void Quassel::disableCrashHandler() +void Quassel::handleSignal(AbstractSignalWatcher::Action action) { - instance()->_handleCrashes = false; + switch (action) { + case AbstractSignalWatcher::Action::Reload: + // Most applications use this as the 'configuration reload' command, e.g. nginx uses it for graceful reloading of processes. + if (!_reloadHandlers.empty()) { + quInfo() << "Reloading configuration"; + if (reloadConfig()) { + quInfo() << "Successfully reloaded configuration"; + } + } + break; + case AbstractSignalWatcher::Action::Terminate: + if (!_quitting) { + quit(); + } + else { + quInfo() << "Already shutting down, ignoring signal"; + } + break; + case AbstractSignalWatcher::Action::HandleCrash: + logBacktrace(instance()->coreDumpFileName()); + exit(EXIT_FAILURE); + } } @@ -368,12 +332,6 @@ Quassel::RunMode Quassel::runMode() { } -void Quassel::setRunMode(RunMode runMode) -{ - instance()->_runMode = runMode; -} - - void Quassel::setCliParser(std::shared_ptr parser) { instance()->_cliParser = std::move(parser); @@ -458,22 +416,13 @@ QString Quassel::configDirPath() } -void Quassel::setDataDirPaths(const QStringList &paths) { - instance()->_dataDirPaths = paths; -} - - QStringList Quassel::dataDirPaths() { - return instance()->_dataDirPaths; -} + if (!instance()->_dataDirPaths.isEmpty()) + return instance()->_dataDirPaths; - -QStringList Quassel::findDataDirPaths() -{ - // TODO Qt5 - // We don't use QStandardPaths for now, as we still need to provide fallbacks for Qt4 and - // want to stay consistent. + // TODO: Migrate to QStandardPaths (will require moving of the sqlite database, + // or a fallback for it being in the config dir) QStringList dataDirNames; #ifdef Q_OS_WIN @@ -527,6 +476,7 @@ QStringList Quassel::findDataDirPaths() dataDirNames.removeDuplicates(); + instance()->_dataDirPaths = dataDirNames; return dataDirNames; } @@ -592,7 +542,7 @@ void Quassel::loadTranslation(const QLocale &locale) quasselTranslator->setObjectName("QuasselTr"); qApp->installTranslator(quasselTranslator); -#if QT_VERSION >= 0x040800 && !defined Q_OS_MAC +#ifndef Q_OS_MAC bool success = qtTranslator->load(locale, QString("qt_"), translationDirPath()); if (!success) qtTranslator->load(locale, QString("qt_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath));