File indexing completed on 2024-04-21 03:56:50

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org>
0004     SPDX-FileCopyrightText: 2002-2003 Waldo Bastian <bastian@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #include <kbuildsycoca_p.h>
0010 
0011 #include <kservice_version.h>
0012 
0013 #include <KAboutData>
0014 #include <KLocalizedString>
0015 
0016 #include <QCommandLineOption>
0017 #include <QCommandLineParser>
0018 #include <QCoreApplication>
0019 #include <QDateTime>
0020 #include <QDebug>
0021 #include <QDir>
0022 #include <QFile>
0023 #include <QFileInfo>
0024 #include <QStandardPaths>
0025 
0026 #include <qplatformdefs.h> // for unlink
0027 #ifdef Q_OS_WIN
0028 #include <qt_windows.h>
0029 #endif
0030 
0031 static void crashHandler(int)
0032 {
0033     // If we crash while reading sycoca, we delete the database
0034     // in an attempt to recover.
0035     if (KBuildSycoca::sycocaPath()) {
0036         unlink(KBuildSycoca::sycocaPath());
0037     }
0038 }
0039 
0040 #if defined(Q_OS_WIN)
0041 // glue function for calling the unix signal handler from the windows unhandled exception filter
0042 // Inspired from KCrash, but heavily simplified
0043 LONG WINAPI win32UnhandledExceptionFilter(_EXCEPTION_POINTERS *)
0044 {
0045     crashHandler(0);
0046     return EXCEPTION_EXECUTE_HANDLER; // allow windows to do the default action (terminate)
0047 }
0048 #endif
0049 
0050 void setCrashHandler()
0051 {
0052 #if defined(Q_OS_WIN)
0053     SetUnhandledExceptionFilter(win32UnhandledExceptionFilter);
0054 #elif !defined(Q_OS_ANDROID)
0055     sigset_t mask;
0056     sigemptyset(&mask);
0057 
0058 #ifdef SIGSEGV
0059     signal(SIGSEGV, crashHandler);
0060     sigaddset(&mask, SIGSEGV);
0061 #endif
0062 #ifdef SIGBUS
0063     signal(SIGBUS, crashHandler);
0064     sigaddset(&mask, SIGBUS);
0065 #endif
0066 #ifdef SIGFPE
0067     signal(SIGFPE, crashHandler);
0068     sigaddset(&mask, SIGFPE);
0069 #endif
0070 #ifdef SIGILL
0071     signal(SIGILL, crashHandler);
0072     sigaddset(&mask, SIGILL);
0073 #endif
0074 #ifdef SIGABRT
0075     signal(SIGABRT, crashHandler);
0076     sigaddset(&mask, SIGABRT);
0077 #endif
0078 
0079     sigprocmask(SIG_UNBLOCK, &mask, nullptr);
0080 #endif
0081 }
0082 
0083 int main(int argc, char **argv)
0084 {
0085     QCoreApplication app(argc, argv);
0086 
0087     KLocalizedString::setApplicationDomain("kservice6");
0088 
0089     KAboutData about(QStringLiteral(KBUILDSYCOCA_EXENAME),
0090                      i18nc("application name", "KBuildSycoca"),
0091                      QStringLiteral(KSERVICE_VERSION_STRING),
0092                      i18nc("application description", "Rebuilds the system configuration cache."),
0093                      KAboutLicense::GPL,
0094                      i18nc("@info:credit", "Copyright 1999-2014 KDE Developers"));
0095     about.addAuthor(i18nc("@info:credit", "David Faure"), i18nc("@info:credit", "Author"), QStringLiteral("faure@kde.org"));
0096     about.addAuthor(i18nc("@info:credit", "Waldo Bastian"), i18nc("@info:credit", "Author"), QStringLiteral("bastian@kde.org"));
0097     KAboutData::setApplicationData(about);
0098 
0099     QCommandLineParser parser;
0100     about.setupCommandLine(&parser);
0101     parser.addOption(
0102         QCommandLineOption(QStringLiteral("noincremental"), i18nc("@info:shell command-line option", "Disable incremental update, re-read everything")));
0103     parser.addOption(QCommandLineOption(QStringLiteral("menutest"), i18nc("@info:shell command-line option", "Perform menu generation test run only")));
0104     parser.addOption(
0105         QCommandLineOption(QStringLiteral("track"), i18nc("@info:shell command-line option", "Track menu id for debug purposes"), QStringLiteral("menu-id")));
0106     parser.addOption(
0107         QCommandLineOption(QStringLiteral("testmode"), i18nc("@info:shell command-line option", "Switch QStandardPaths to test mode, for unit tests only")));
0108     parser.process(app);
0109     about.processCommandLine(&parser);
0110 
0111     const bool bMenuTest = parser.isSet(QStringLiteral("menutest"));
0112 
0113     if (parser.isSet(QStringLiteral("testmode"))) {
0114         QStandardPaths::setTestModeEnabled(true);
0115     }
0116 
0117     setCrashHandler();
0118 
0119     fprintf(stderr, "%s running...\n", KBUILDSYCOCA_EXENAME);
0120 
0121     const bool incremental = !parser.isSet(QStringLiteral("noincremental"));
0122 
0123     KBuildSycoca sycoca; // Build data base
0124     if (parser.isSet(QStringLiteral("track"))) {
0125         sycoca.setTrackId(parser.value(QStringLiteral("track")));
0126     }
0127     sycoca.setMenuTest(bMenuTest);
0128     if (!sycoca.recreate(incremental)) {
0129         return -1;
0130     }
0131 
0132     return 0;
0133 }