summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-01-26 08:37:40 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-05-14 06:29:59 +0000
commitf8cbde9b0afd427d25017b46209c3119c8919e5e (patch)
treed77bd2778d0a36f38bd669994277d4b82b5b9c6b
parent5a79a9ea41ab1223edc39b6c594a682cb079dd18 (diff)
Windows/QSaveFile: Fix locking issues on Dropbox drives
Add a flag to QTemporaryFileEngine causing the file to be opened in non-shared mode, preventing renaming failures caused by the Dropbox driver accessing it. Task-number: QTBUG-57299 Change-Id: Id7afc3559fd15784d4166efbbd057d592b5e0ab2 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit fe5edcee602f0ab2912bbdd1a21f4309ed7dbfd6) Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io> Reviewed-by: Kai Pastor <dg0yt@darc.de>
-rw-r--r--src/corelib/io/qsavefile.cpp2
-rw-r--r--src/corelib/io/qtemporaryfile.cpp11
-rw-r--r--src/corelib/io/qtemporaryfile_p.h5
3 files changed, 13 insertions, 5 deletions
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 3f45ca5f91..aaf3d1f5fb 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -231,7 +231,7 @@ bool QSaveFile::open(OpenMode mode)
d->finalFileName = existingFile.filePath();
}
- d->fileEngine = new QTemporaryFileEngine;
+ d->fileEngine = new QTemporaryFileEngine(QTemporaryFileEngine::Win32NonShared);
// if the target file exists, we'll copy its permissions below,
// but until then, let's ensure the temporary file is not accessible
// to a third party
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 8a99873fee..4712e65a41 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -117,7 +117,7 @@ typedef int NativeFileHandle;
*/
static bool createFileFromTemplate(NativeFileHandle &file,
QFileSystemEntry::NativePath &path, size_t pos, size_t length, quint32 mode,
- QSystemError &error)
+ int flags, QSystemError &error)
{
Q_ASSERT(length != 0);
Q_ASSERT(pos < size_t(path.length()));
@@ -151,16 +151,18 @@ static bool createFileFromTemplate(NativeFileHandle &file,
// Atomically create file and obtain handle
#if defined(Q_OS_WIN)
Q_UNUSED(mode);
+ const DWORD shareMode = (flags & QTemporaryFileEngine::Win32NonShared)
+ ? 0u : (FILE_SHARE_READ | FILE_SHARE_WRITE);
# ifndef Q_OS_WINRT
file = CreateFile((const wchar_t *)path.constData(),
GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
+ shareMode, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
# else // !Q_OS_WINRT
file = CreateFile2((const wchar_t *)path.constData(),
GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_NEW,
+ shareMode, CREATE_NEW,
NULL);
# endif // Q_OS_WINRT
@@ -182,6 +184,7 @@ static bool createFileFromTemplate(NativeFileHandle &file,
return false;
}
#else // POSIX
+ Q_UNUSED(flags)
file = QT_OPEN(path.constData(),
QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
static_cast<mode_t>(mode));
@@ -342,7 +345,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
NativeFileHandle &file = d->fd;
#endif
- if (!createFileFromTemplate(file, filename, phPos, phLength, fileMode, error)) {
+ if (!createFileFromTemplate(file, filename, phPos, phLength, fileMode, flags, error)) {
setError(QFile::OpenError, error.toString());
return false;
}
diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h
index 7f365f0e8a..b0fab3a255 100644
--- a/src/corelib/io/qtemporaryfile_p.h
+++ b/src/corelib/io/qtemporaryfile_p.h
@@ -85,6 +85,10 @@ class QTemporaryFileEngine : public QFSFileEngine
{
Q_DECLARE_PRIVATE(QFSFileEngine)
public:
+ enum Flags { Win32NonShared = 0x1 };
+
+ explicit QTemporaryFileEngine(int _flags = 0) : flags(_flags) {}
+
void initialize(const QString &file, quint32 mode, bool nameIsTemplate = true)
{
Q_D(QFSFileEngine);
@@ -109,6 +113,7 @@ public:
bool close() override;
quint32 fileMode;
+ int flags;
bool filePathIsTemplate;
bool filePathWasTemplate;
};