summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@digia.com>2013-03-19 16:45:25 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-23 14:42:45 +0100
commita3304489e870555f5d01d02c0252103db2288898 (patch)
treeebf8314f9fa8812e227b078d7e6b943860cf2448
parent0450d8119028905823a393a5598eb350b8b5d377 (diff)
Ensure QTemporaryFile can create files when an identical dir exists.
When QTemporaryFile attempts to create a new file in createFileFromTemplate, it fails if the filename exists and is a directory. Windows returns error code 5 (ERROR_ACCESS_DENIED) in this case - rather than ERROR_FILE_EXISTS - which is not handled. This patch handles ERROR_ACCESS_DENIED in addition to the already handled ERROR_FILE_EXISTS, meaning that QTemporaryFile will continue to look for unique names when a directory with the same name exists. Task-number: QTBUG-30058 Change-Id: I42339887d7f5483e3dc6a03a9da15111c350da8f Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
-rw-r--r--src/corelib/io/qtemporaryfile.cpp9
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp35
2 files changed, 43 insertions, 1 deletions
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index d3a6e3c238..c2f421843c 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -160,7 +160,14 @@ static bool createFileFromTemplate(NativeFileHandle &file,
return true;
DWORD err = GetLastError();
- if (err != ERROR_FILE_EXISTS) {
+ if (err == ERROR_ACCESS_DENIED) {
+ DWORD attributes = GetFileAttributes((const wchar_t *)path.constData());
+ if (attributes == INVALID_FILE_ATTRIBUTES) {
+ // Potential write error (read-only parent directory, etc.).
+ error = QSystemError(err, QSystemError::NativeError);
+ return false;
+ } // else file already exists as a directory.
+ } else if (err != ERROR_FILE_EXISTS) {
error = QSystemError(err, QSystemError::NativeError);
return false;
}
diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
index 28cf7a904a..6eb6f83d2a 100644
--- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -92,6 +92,7 @@ private slots:
void createNativeFile();
void QTBUG_4796_data();
void QTBUG_4796();
+ void guaranteeUnique();
};
void tst_QTemporaryFile::initTestCase()
@@ -782,5 +783,39 @@ void tst_QTemporaryFile::QTBUG_4796()
cleaner.reset();
}
+void tst_QTemporaryFile::guaranteeUnique()
+{
+ QDir dir(QDir::tempPath());
+ QString takenFileName;
+
+ // First pass. See which filename QTemporaryFile will try first.
+ {
+ // Fix the random seed.
+ qsrand(1135);
+ QTemporaryFile tmpFile("testFile1.XXXXXX");
+ tmpFile.open();
+ takenFileName = tmpFile.fileName();
+ QVERIFY(QFile::exists(takenFileName));
+ }
+
+ QVERIFY(!QFile::exists(takenFileName));
+
+ // Create a directory with same name.
+ QVERIFY(dir.mkdir(takenFileName));
+
+ // Second pass, now we have blocked its first attempt with a directory.
+ {
+ // Fix the random seed.
+ qsrand(1135);
+ QTemporaryFile tmpFile("testFile1.XXXXXX");
+ QVERIFY(tmpFile.open());
+ QString uniqueFileName = tmpFile.fileName();
+ QVERIFY(QFileInfo(uniqueFileName).isFile());
+ QVERIFY(uniqueFileName != takenFileName);
+ }
+
+ QVERIFY(dir.rmdir(takenFileName));
+}
+
QTEST_MAIN(tst_QTemporaryFile)
#include "tst_qtemporaryfile.moc"