summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qtemporaryfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qtemporaryfile.cpp')
-rw-r--r--src/corelib/io/qtemporaryfile.cpp151
1 files changed, 102 insertions, 49 deletions
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 79f7a108d1..a0b6c6bbfa 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -49,6 +49,11 @@
#include "private/qfile_p.h"
#include "private/qabstractfileengine_p.h"
#include "private/qfsfileengine_p.h"
+#include "private/qsystemerror_p.h"
+
+#if defined(Q_OS_SYMBIAN)
+#include "private/qcore_symbian_p.h"
+#endif
#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
#include "private/qcore_unix_p.h" // overrides QT_OPEN
@@ -83,9 +88,20 @@ struct QConcatenable<Char>
}
};
+# ifdef Q_OS_WIN
+typedef HANDLE NativeFileHandle;
+# else // Q_OS_SYMBIAN
+# ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+typedef RFile64 NativeFileHandle;
+# else
+typedef RFile NativeFileHandle;
+# endif
+# endif
+
#else // POSIX
typedef char Char;
typedef char Latin1Char;
+typedef int NativeFileHandle;
#endif
struct Placeholder
@@ -161,8 +177,9 @@ struct QConcatenable<Placeholder>
handle otherwise. In both cases, the string in \a path will be changed and
contain the generated path name.
*/
-static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
- size_t pos, size_t length)
+static bool createFileFromTemplate(NativeFileHandle &file,
+ QFileSystemEntry::NativePath &path, size_t pos, size_t length,
+ QSystemError &error)
{
Q_ASSERT(length != 0);
Q_ASSERT(pos < size_t(path.length()));
@@ -192,21 +209,50 @@ static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
}
}
+#ifdef Q_OS_SYMBIAN
+ RFs& fs = qt_s60GetRFs();
+#endif
+
for (;;) {
// Atomically create file and obtain handle
-#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- {
- int fd = QT_OPEN(path.constData(),
- QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
- 0600);
- if (fd != -1)
- return fd;
- if (errno != EEXIST)
- return -1;
+#if defined(Q_OS_WIN)
+ file = CreateFile((const wchar_t *)path.constData(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (file != INVALID_HANDLE_VALUE)
+ return true;
+
+ DWORD err = GetLastError();
+ if (err != ERROR_FILE_EXISTS) {
+ error = QSystemError(err, QSystemError::NativeError);
+ return false;
+ }
+#elif defined(Q_OS_SYMBIAN)
+ TInt err = file.Create(fs, qt_QString2TPtrC(path),
+ EFileRead | EFileWrite | EFileShareReadersOrWriters);
+
+ if (err == KErrNone)
+ return true;
+
+ if (err != KErrAlreadyExists) {
+ error = QSystemError(err, QSystemError::NativeError);
+ return false;
+ }
+#else // POSIX
+ file = QT_OPEN(path.constData(),
+ QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
+ 0600);
+
+ if (file != -1)
+ return true;
+
+ int err = errno;
+ if (err != EEXIST) {
+ error = QSystemError(err, QSystemError::NativeError);
+ return false;
}
-#else
- if (!QFileInfo(path).exists())
- return 1;
#endif
/* tricky little algorwwithm for backward compatibility */
@@ -217,8 +263,11 @@ static int createFileFromTemplate(QFileSystemEntry::NativePath &path,
case 'Z':
// Rollover, advance next character
*iter = Latin1Char('a');
- if (++iter == placeholderEnd)
- return -1;
+ if (++iter == placeholderEnd) {
+ // Out of alternatives. Return file exists error, previously set.
+ error = QSystemError(err, QSystemError::NativeError);
+ return false;
+ }
continue;
@@ -319,7 +368,14 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
if (!filePathIsTemplate)
return QFSFileEngine::open(openMode);
- const QString qfilename = d->fileEntry.filePath();
+ const QString qfilename =
+#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
+ // Since the native encoding is out of our control, we need to process
+ // the path as UTF-16 before doing any conversions
+ d->fileEntry.filePath();
+#else
+ d->fileEntry.nativeFilePath();
+#endif
// Find placeholder string.
uint phPos = qfilename.length();
@@ -333,8 +389,14 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
continue;
}
- if (qfilename[phPos] == QLatin1Char('/')
- || phLength >= 6) {
+ if (phLength >= 6
+ || qfilename[phPos] ==
+#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
+ QLatin1Char('/')
+#else
+ QLatin1Char('\\')
+#endif
+ ) {
++phPos;
break;
}
@@ -366,44 +428,35 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
filename = qfilename % Latin1Char('.') % Placeholder(phLength);
} else
filename = qfilename;
-
- // No native separators, not a "native path"
#endif
- int fd = createFileFromTemplate(filename, phPos, phLength);
+ QSystemError error;
+#if defined(Q_OS_WIN)
+ NativeFileHandle &file = d->fileHandle;
+#elif defined(Q_OS_SYMBIAN)
+ NativeFileHandle &file = d->symbianFile;
+#else // POSIX
+ NativeFileHandle &file = d->fd;
+#endif
-#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
- if (fd != -1) {
- // First open the fd as an external file descriptor to
- // initialize the engine properly.
- if (QFSFileEngine::open(openMode, fd)) {
+ if (!createFileFromTemplate(file, filename, phPos, phLength, error)) {
+ setError(QFile::OpenError, error.toString());
+ return false;
+ }
- // Allow the engine to close the handle even if it's "external".
- d->closeFileHandle = true;
+ d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
- // Restore the file names (open() resets them).
- d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename.constData(), filename.length())); //note that filename is NOT a native path
- filePathIsTemplate = false;
- return true;
- }
+#if !defined(Q_OS_WIN)
+ d->closeFileHandle = true;
+#endif
- QT_CLOSE(fd);
- }
- setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno));
- return false;
-#else
- if (fd == -1)
- return false;
+ filePathIsTemplate = false;
- d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromInternalPath());
- if (QFSFileEngine::open(openMode)) {
- filePathIsTemplate = false;
- return true;
- }
+ d->openMode = openMode;
+ d->lastFlushFailed = false;
+ d->tried_stat = 0;
- d->fileEntry = QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath());
- return false;
-#endif
+ return true;
}
bool QTemporaryFileEngine::remove()