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);
}
Example #2
0
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();
        }
    }
}