diff options
author | Olivier Goffart <ogoffart@woboq.com> | 2014-05-28 22:53:57 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-05-30 19:36:38 +0200 |
commit | 7e5e7eeaa1418d959906cdf9d717c984c9fc7a7e (patch) | |
tree | cb7cc93009370ab9c703c1e54f9a9963a9df31fb /src/corelib/io | |
parent | e747324f68df827dcea15bd0e3ee6b023542fe01 (diff) |
QSaveFile: follow symbolic links
[ChangeLog][QtCore][QSaveFile] Now follows symbolic links while writing to
a link instead of replacing the link with the contents.
Change-Id: I5afd519cb9f96ae68fa4c23c33a18de75671a301
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Reviewed-by: David Faure <david.faure@kdab.com>
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qsavefile.cpp | 18 | ||||
-rw-r--r-- | src/corelib/io/qsavefile_p.h | 1 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index 2b901c7ccd..05d7687007 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -205,14 +205,26 @@ bool QSaveFile::open(OpenMode mode) d->writeError = QFileDevice::WriteError; return false; } - d->fileEngine = new QTemporaryFileEngine(d->fileName); + + // Resolve symlinks. Don't use QFileInfo::canonicalFilePath so it still give the expected + // target even if the file does not exist + d->finalFileName = d->fileName; + if (existingFile.isSymLink()) { + int maxDepth = 128; + while (--maxDepth && existingFile.isSymLink()) + existingFile.setFile(existingFile.symLinkTarget()); + if (maxDepth > 0) + d->finalFileName = existingFile.filePath(); + } + + d->fileEngine = new QTemporaryFileEngine(d->finalFileName); // Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine. if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) { QFileDevice::FileError err = d->fileEngine->error(); #ifdef Q_OS_UNIX if (d->directWriteFallback && err == QFileDevice::OpenError && errno == EACCES) { delete d->fileEngine; - d->fileEngine = QAbstractFileEngine::create(d->fileName); + d->fileEngine = QAbstractFileEngine::create(d->finalFileName); if (d->fileEngine->open(mode | QIODevice::Unbuffered)) { d->useTemporaryFile = false; QFileDevice::open(mode); @@ -285,7 +297,7 @@ bool QSaveFile::commit() // atomically replace old file with new file // Can't use QFile::rename for that, must use the file engine directly Q_ASSERT(d->fileEngine); - if (!d->fileEngine->renameOverwrite(d->fileName)) { + if (!d->fileEngine->renameOverwrite(d->finalFileName)) { d->setError(d->fileEngine->error(), d->fileEngine->errorString()); d->fileEngine->remove(); delete d->fileEngine; diff --git a/src/corelib/io/qsavefile_p.h b/src/corelib/io/qsavefile_p.h index b9efd1ee7c..2134c4c9bc 100644 --- a/src/corelib/io/qsavefile_p.h +++ b/src/corelib/io/qsavefile_p.h @@ -70,6 +70,7 @@ protected: ~QSaveFilePrivate(); QString fileName; + QString finalFileName; // fileName with symbolic links resolved QFileDevice::FileError writeError; |