35 #include <QtCore/QDataStream>
36 #include <QtCore/QCoreApplication>
37 #include <QtCore/QFile>
38 #include <QtCore/QBuffer>
40 #include <QtDBus/QtDBus>
58 #define KSYCOCA_VERSION 220
63 #define KSYCOCA_FILENAME "ksycoca4"
70 #define MAP_FAILED ((void *) -1)
84 Q_DECLARE_OPERATORS_FOR_FLAGS(KSycocaPrivate::BehaviorsIfNotFound)
87 : databaseStatus( DatabaseNotOpen ),
102 m_sycocaStrategy = StrategyMemFile;
104 m_sycocaStrategy = StrategyMmap;
107 setStrategyFromString(config.
readEntry(
"strategy"));
111 if (strategy == QLatin1String(
"mmap"))
113 else if (strategy == QLatin1String(
"file"))
115 else if (strategy == QLatin1String(
"sharedmem"))
117 else if (!strategy.isEmpty())
118 kWarning(7011) <<
"Unknown sycoca strategy:" << strategy;
126 const bool canRead = m_mmapFile->open(QIODevice::ReadOnly);
129 fcntl(m_mmapFile->handle(), F_SETFD, FD_CLOEXEC);
130 sycoca_size = m_mmapFile->size();
131 sycoca_mmap = (
const char *) mmap(0, sycoca_size,
132 PROT_READ, MAP_SHARED,
133 m_mmapFile->handle(), 0);
136 if (sycoca_mmap == (
const char*)
MAP_FAILED || sycoca_mmap == 0) {
137 kDebug(7011) <<
"mmap failed. (length = " << sycoca_size <<
")";
142 (void) posix_madvise((
void*)sycoca_mmap, sycoca_size, POSIX_MADV_WILLNEED);
143 #endif // HAVE_MADVISE
155 class KSycocaSingleton
158 KSycocaSingleton() { }
159 ~KSycocaSingleton() { }
161 bool hasSycoca()
const {
162 return m_threadSycocas.hasLocalData();
165 if (!m_threadSycocas.hasLocalData())
166 m_threadSycocas.setLocalData(
new KSycoca);
167 return m_threadSycocas.localData();
170 m_threadSycocas.setLocalData(s);
174 QThreadStorage<KSycoca*> m_threadSycocas;
184 QString::fromLatin1(
"org.kde.KSycoca"),
185 QString::fromLatin1(
"notifyDatabaseChanged"),
193 delete m_device; m_device = 0;
197 kDebug(7011) <<
"Trying to open ksycoca from" << path;
200 if (!path.isEmpty()) {
201 kDebug(7011) <<
"Trying to open global ksycoca from " << path;
211 kDebug(7011) <<
"Could not open ksycoca";
214 if (openDummyIfNotFound) {
219 QDataStream* str =
stream();
239 device->
device()->open(QIODevice::ReadOnly);
243 device =
new KSycocaMmapDevice(sycoca_mmap,
245 if (!device->device()->open(QIODevice::ReadOnly)) {
246 delete device; device = 0;
250 #ifndef QT_NO_SHAREDMEMORY
253 if (!device->device()->open(QIODevice::ReadOnly)) {
254 delete device; device = 0;
260 if (!device->device()->open(QIODevice::ReadOnly)) {
282 return m_device->
stream();
290 ksycocaInstance->setSycoca(
this);
295 KSycoca* s = ksycocaInstance->sycoca();
323 qDeleteAll(m_factories);
331 munmap(const_cast<char*>(sycoca_mmap), sycoca_size);
334 delete m_mmapFile; m_mmapFile = 0;
346 #ifndef KDE_NO_DEPRECATED
349 return self()->d->
changeList.contains(QString::fromLatin1(type));
353 void KSycoca::notifyDatabaseChanged(
const QStringList &changeList)
364 #ifndef KDE_NO_DEPRECATED
372 QDataStream* str =
stream();
375 str->device()->seek(offset);
378 type = KSycocaType(aType);
393 m_str->device()->seek(0);
419 const bool kdeinitRunning = QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(
"org.kde.klauncher"));
432 if (!kdeinitRunning) {
433 kDebug(7011) <<
"We have no database.... launching kdeinit";
439 qWarning(
"ERROR: Running KSycoca failed.");
446 kDebug(7011) <<
"Still no database...";
450 kDebug(7011) <<
"Still outdated...";
466 QDataStream* str =
stream();
474 kError(7011) <<
"Error, KSycocaFactory (id =" << int(
id) <<
") not found!";
480 str->device()->seek(aOffset);
492 QDataStream* str =
stream();
538 const QByteArray ksycoca_env = qgetenv(
"KDESYCOCA");
539 if (ksycoca_env.isEmpty())
542 return QFile::decodeName(ksycoca_env);
561 kWarning(7011) <<
"ERROR: KSycoca database corruption!";
576 #ifndef KDE_NO_DEPRECATED
590 s_autoRebuild =
false;
598 void KSycoca::clearCaches()
600 if (ksycocaInstance.exists() && ksycocaInstance->hasSycoca())
601 ksycocaInstance->sycoca()->d->closeDatabase();
604 #include "ksycoca.moc"