QPair<QString, KLockFile::Ptr> allocateRepository() { KLockFile::Ptr lock; QString repoPath; KComponentData component("item repositories temp", QByteArray(), KComponentData::SkipMainComponentRegistration); QString xdgCacheDir = QProcessEnvironment::systemEnvironment().value("XDG_CACHE_HOME", QDir::homePath() + "/.cache") + "/kdevduchain"; QString baseDir = QProcessEnvironment::systemEnvironment().value("KDEV_DUCHAIN_DIR", xdgCacheDir); KStandardDirs::makeDir(baseDir); Q_ASSERT( ICore::self() ); Q_ASSERT( ICore::self()->activeSession() ); baseDir += '/' + ICore::self()->activeSession()->id().toString(); //Since each instance of kdevelop needs an own directory, iterate until we find a not-yet-used one for(int a = 0; a < 100; ++a) { QString specificDir = baseDir + QString("/%1").arg(a); KStandardDirs::makeDir(specificDir); lock = new KLockFile(specificDir + "/lock", component); KLockFile::LockResult result = lock->lock(KLockFile::NoBlockFlag | KLockFile::ForceFlag); bool useDir = false; if(result != KLockFile::LockOK) { int pid; QString hostname, appname; if(lock->getLockInfo(pid, hostname, appname)) { if(!processExists(pid)) { kDebug() << "The process holding" << specificDir << "with pid" << pid << "does not exists any more. Re-using the directory."; QFile::remove(specificDir + "/lock"); useDir = true; if(lock->lock(KLockFile::NoBlockFlag | KLockFile::ForceFlag) != KLockFile::LockOK) { kWarning() << "Failed to re-establish the lock in" << specificDir; continue; } } } }else { useDir = true; } if(useDir) { repoPath = specificDir; if(result == KLockFile::LockStale) { kWarning() << "stale lock detected:" << specificDir + "/lock"; } break; } } if(repoPath.isEmpty()) { kError() << "could not create a directory for the duchain data"; }else{ kDebug() << "picked duchain directory" << repoPath; } return qMakePair(repoPath, lock); }
void KConfigINIBackEnd::sync(bool bMerge) { // write-sync is only necessary if there are dirty entries if(!pConfig->isDirty()) return; bool bEntriesLeft = true; // find out the file to write to (most specific writable file) // try local app-specific file first if(!mfileName.isEmpty()) { // Create the containing dir if needed if((resType != "config") && !QDir::isRelativePath(mLocalFileName)) { KURL path; path.setPath(mLocalFileName); QString dir = path.directory(); KStandardDirs::makeDir(dir); } // Can we allow the write? We can, if the program // doesn't run SUID. But if it runs SUID, we must // check if the user would be allowed to write if // it wasn't SUID. if(checkAccess(mLocalFileName, W_OK)) { // File is writable KLockFile::Ptr lf; bool mergeLocalFile = bMerge; // Check if the file has been updated since. if(mergeLocalFile) { lf = lockFile(false); // Lock file for local file if(lf && lf->isLocked()) lf = 0; // Already locked, we don't need to lock/unlock again if(lf) { lf->lock(KLockFile::LockForce); // But what if the locking failed? Ignore it for now... } QFileInfo info(mLocalFileName); if((d->localLastSize == info.size()) && (d->localLastModified == info.lastModified())) { // Not changed, don't merge. mergeLocalFile = false; } else { // Changed... d->localLastModified = QDateTime(); d->localLastSize = 0; } } bEntriesLeft = writeConfigFile(mLocalFileName, false, mergeLocalFile); // Only if we didn't have to merge anything can we use our in-memory state // the next time around. Otherwise the config-file may contain entries // that are different from our in-memory state which means we will have to // do a merge from then on. // We do not automatically update the in-memory state with the on-disk // state when writing the config to disk. We only do so when // KCOnfig::reparseConfiguration() is called. // For KDE 4.0 we may wish to reconsider that. if(!mergeLocalFile) { QFileInfo info(mLocalFileName); d->localLastModified = info.lastModified(); d->localLastSize = info.size(); } if(lf) lf->unlock(); } } // only write out entries to the kdeglobals file if there are any // entries marked global (indicated by bEntriesLeft) and // the useKDEGlobals flag is set. if(bEntriesLeft && useKDEGlobals) { // can we allow the write? (see above) if(checkAccess(mGlobalFileName, W_OK)) { KLockFile::Ptr lf = lockFile(true); // Lock file for global file if(lf && lf->isLocked()) lf = 0; // Already locked, we don't need to lock/unlock again if(lf) { lf->lock(KLockFile::LockForce); // But what if the locking failed? Ignore it for now... } writeConfigFile(mGlobalFileName, true, bMerge); // Always merge if(lf) lf->unlock(); } } }