1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org>
4 SPDX-FileCopyrightText: 2002-2003 Waldo Bastian <bastian@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-only
7*/
8
9#include <kbuildsycoca_p.h>
10
11#include <kservice_version.h>
12
13#include <KAboutData>
14#include <KLocalizedString>
15
16#include <QCommandLineOption>
17#include <QCommandLineParser>
18#include <QCoreApplication>
19#include <QDateTime>
20#include <QDebug>
21#include <QDir>
22#include <QFile>
23#include <QFileInfo>
24#include <QStandardPaths>
25
26#include <qplatformdefs.h> // for unlink
27#ifdef Q_OS_WIN
28#include <qt_windows.h>
29#endif
30
31static void crashHandler(int)
32{
33 // If we crash while reading sycoca, we delete the database
34 // in an attempt to recover.
35 if (KBuildSycoca::sycocaPath()) {
36 unlink(name: KBuildSycoca::sycocaPath());
37 }
38}
39
40#if defined(Q_OS_WIN)
41// glue function for calling the unix signal handler from the windows unhandled exception filter
42// Inspired from KCrash, but heavily simplified
43LONG WINAPI win32UnhandledExceptionFilter(_EXCEPTION_POINTERS *)
44{
45 crashHandler(0);
46 return EXCEPTION_EXECUTE_HANDLER; // allow windows to do the default action (terminate)
47}
48#endif
49
50void setCrashHandler()
51{
52#if defined(Q_OS_WIN)
53 SetUnhandledExceptionFilter(win32UnhandledExceptionFilter);
54#elif !defined(Q_OS_ANDROID)
55 sigset_t mask;
56 sigemptyset(set: &mask);
57
58#ifdef SIGSEGV
59 signal(SIGSEGV, handler: crashHandler);
60 sigaddset(set: &mask, SIGSEGV);
61#endif
62#ifdef SIGBUS
63 signal(SIGBUS, handler: crashHandler);
64 sigaddset(set: &mask, SIGBUS);
65#endif
66#ifdef SIGFPE
67 signal(SIGFPE, handler: crashHandler);
68 sigaddset(set: &mask, SIGFPE);
69#endif
70#ifdef SIGILL
71 signal(SIGILL, handler: crashHandler);
72 sigaddset(set: &mask, SIGILL);
73#endif
74#ifdef SIGABRT
75 signal(SIGABRT, handler: crashHandler);
76 sigaddset(set: &mask, SIGABRT);
77#endif
78
79 sigprocmask(SIG_UNBLOCK, set: &mask, oset: nullptr);
80#endif
81}
82
83int main(int argc, char **argv)
84{
85 QCoreApplication app(argc, argv);
86
87 KLocalizedString::setApplicationDomain("kservice6");
88
89 KAboutData about(QStringLiteral(KBUILDSYCOCA_EXENAME),
90 i18nc("application name", "KBuildSycoca"),
91 QStringLiteral(KSERVICE_VERSION_STRING),
92 i18nc("application description", "Rebuilds the system configuration cache."),
93 KAboutLicense::GPL,
94 i18nc("@info:credit", "Copyright 1999-2014 KDE Developers"));
95 about.addAuthor(i18nc("@info:credit", "David Faure"), i18nc("@info:credit", "Author"), QStringLiteral("faure@kde.org"));
96 about.addAuthor(i18nc("@info:credit", "Waldo Bastian"), i18nc("@info:credit", "Author"), QStringLiteral("bastian@kde.org"));
97 KAboutData::setApplicationData(about);
98
99 QCommandLineParser parser;
100 about.setupCommandLine(&parser);
101 parser.addOption(
102 commandLineOption: QCommandLineOption(QStringLiteral("noincremental"), i18nc("@info:shell command-line option", "Disable incremental update, re-read everything")));
103 parser.addOption(commandLineOption: QCommandLineOption(QStringLiteral("menutest"), i18nc("@info:shell command-line option", "Perform menu generation test run only")));
104 parser.addOption(
105 commandLineOption: QCommandLineOption(QStringLiteral("track"), i18nc("@info:shell command-line option", "Track menu id for debug purposes"), QStringLiteral("menu-id")));
106 parser.addOption(
107 commandLineOption: QCommandLineOption(QStringLiteral("testmode"), i18nc("@info:shell command-line option", "Switch QStandardPaths to test mode, for unit tests only")));
108 parser.process(app);
109 about.processCommandLine(parser: &parser);
110
111 const bool bMenuTest = parser.isSet(QStringLiteral("menutest"));
112
113 if (parser.isSet(QStringLiteral("testmode"))) {
114 QStandardPaths::setTestModeEnabled(true);
115 }
116
117 setCrashHandler();
118
119 fprintf(stderr, format: "%s running...\n", KBUILDSYCOCA_EXENAME);
120
121 const bool incremental = !parser.isSet(QStringLiteral("noincremental"));
122
123 KBuildSycoca sycoca; // Build data base
124 if (parser.isSet(QStringLiteral("track"))) {
125 sycoca.setTrackId(parser.value(QStringLiteral("track")));
126 }
127 sycoca.setMenuTest(bMenuTest);
128 if (!sycoca.recreate(incremental)) {
129 return -1;
130 }
131
132 return 0;
133}
134

source code of kservice/src/kbuildsycoca/kbuildsycoca_main.cpp