diff options
Diffstat (limited to 'src/libs/installer/fileutils.cpp')
-rw-r--r-- | src/libs/installer/fileutils.cpp | 86 |
1 files changed, 70 insertions, 16 deletions
diff --git a/src/libs/installer/fileutils.cpp b/src/libs/installer/fileutils.cpp index 5a89073fc..044eeb34f 100644 --- a/src/libs/installer/fileutils.cpp +++ b/src/libs/installer/fileutils.cpp @@ -66,54 +66,62 @@ using namespace QInstaller; /*! \inmodule QtInstallerFramework - \class QInstaller::TempDirDeleter + \class QInstaller::TempPathDeleter \internal */ // -- TempDirDeleter -TempDirDeleter::TempDirDeleter(const QString &path) +TempPathDeleter::TempPathDeleter(const QString &path) { m_paths.insert(path); } -TempDirDeleter::TempDirDeleter(const QStringList &paths) +TempPathDeleter::TempPathDeleter(const QStringList &paths) : m_paths(QSet<QString>(paths.begin(), paths.end())) { } -TempDirDeleter::~TempDirDeleter() +TempPathDeleter::~TempPathDeleter() { releaseAndDeleteAll(); } -QStringList TempDirDeleter::paths() const +QStringList TempPathDeleter::paths() const { - return m_paths.toList(); + return m_paths.values(); } -void TempDirDeleter::add(const QString &path) +void TempPathDeleter::add(const QString &path) { m_paths.insert(path); } -void TempDirDeleter::add(const QStringList &paths) +void TempPathDeleter::add(const QStringList &paths) { m_paths += QSet<QString>(paths.begin(), paths.end()); } -void TempDirDeleter::releaseAndDeleteAll() +void TempPathDeleter::releaseAndDeleteAll() { foreach (const QString &path, m_paths) releaseAndDelete(path); } -void TempDirDeleter::releaseAndDelete(const QString &path) +void TempPathDeleter::releaseAndDelete(const QString &path) { if (m_paths.contains(path)) { try { m_paths.remove(path); - removeDirectory(path); + if (QFileInfo(path).isDir()) { + removeDirectory(path); + return; + } + QFile file(path); + if (file.exists() && !file.remove()) { + throw Error(QCoreApplication::translate("QInstaller", + "Cannot remove file \"%1\": %2").arg(file.fileName(), file.errorString())); + } } catch (const Error &e) { qCritical() << Q_FUNC_INFO << "Exception caught:" << e.message(); } catch (...) { @@ -363,7 +371,7 @@ bool QInstaller::setDefaultFilePermissions(QFile *file, DefaultFilePermissions p void QInstaller::copyDirectoryContents(const QString &sourceDir, const QString &targetDir) { Q_ASSERT(QFileInfo(sourceDir).isDir()); - Q_ASSERT(!QFileInfo(targetDir).exists() || QFileInfo(targetDir).isDir()); + Q_ASSERT(!QFileInfo::exists(targetDir) || QFileInfo(targetDir).isDir()); if (!QDir().mkpath(targetDir)) { throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\".") .arg(QDir::toNativeSeparators(targetDir))); @@ -394,7 +402,7 @@ void QInstaller::copyDirectoryContents(const QString &sourceDir, const QString & void QInstaller::moveDirectoryContents(const QString &sourceDir, const QString &targetDir) { Q_ASSERT(QFileInfo(sourceDir).isDir()); - Q_ASSERT(!QFileInfo(targetDir).exists() || QFileInfo(targetDir).isDir()); + Q_ASSERT(!QFileInfo::exists(targetDir) || QFileInfo(targetDir).isDir()); if (!QDir().mkpath(targetDir)) { throw Error(QCoreApplication::translate("QInstaller", "Cannot create directory \"%1\".") .arg(QDir::toNativeSeparators(targetDir))); @@ -449,6 +457,52 @@ void QInstaller::mkpath(const QString &path) /*! \internal + Creates directory \a path including all parent directories. Return \c true on + success, \c false otherwise. + + On Windows \c QDir::mkpath() doesn't check if the leading directories were created + elsewhere (i.e. in another thread) after the initial check that the given path + requires creating also parent directories, and returns \c false. + + On Unix platforms this case is handled different by QFileSystemEngine though, + which checks for \c EEXIST error code in case any of the recursive directories + could not be created. + + Compared to \c QInstaller::mkpath() and \c QDir::mkpath() this function checks if + each parent directory to-be-created were created elsewhere. +*/ +bool QInstaller::createDirectoryWithParents(const QString &path) +{ + if (path.isEmpty()) + return false; + + QFileInfo dirInfo(path); + if (dirInfo.exists() && dirInfo.isDir()) + return true; + + // bail out if we are at the root directory + if (dirInfo.isRoot()) + return false; + + QDir dir(path); + if (dir.exists() || dir.mkdir(path)) + return true; + + // mkdir failed, try to create the parent directory + if (!createDirectoryWithParents(dirInfo.absolutePath())) + return false; + + // now try again + if (dir.exists() || dir.mkdir(path)) + return true; + + // directory may be have also been created elsewhere + return (dirInfo.exists() && dirInfo.isDir()); +} + +/*! + \internal + Generates and returns a temporary file name. The name can start with a template \a templ. */ @@ -680,7 +734,7 @@ quint64 QInstaller::fileSize(const QFileInfo &info) bool QInstaller::isInBundle(const QString &path, QString *bundlePath) { #ifdef Q_OS_MACOS - QFileInfo fi = QFileInfo(path).absoluteFilePath(); + QFileInfo fi(QFileInfo(path).absoluteFilePath()); while (!fi.isRoot()) { if (fi.isBundle()) { if (bundlePath) @@ -810,8 +864,8 @@ void QInstaller::copyConfigChildElements(QDomDocument &dom, const QDomNodeList & // Filename may also contain a path relative to source directory but we // copy it strictly into target directory without extra paths - const QString newName = domElement.text() - .replace(QRegExp(QLatin1String("\\\\|/|\\.|:")), QLatin1String("_")); + static const QRegularExpression regex(QLatin1String("\\\\|/|\\.|:")); + const QString newName = domElement.text().replace(regex, QLatin1String("_")); const QString targetFile = targetDir + QDir::separator() + newName; const QFileInfo elementFileInfo = QFileInfo(sourceDir, domElement.text()); |