diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2010-10-22 15:00:24 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2010-10-29 13:22:09 (GMT) |
commit | 484770255f421d71954df4511e3541d2d4654d4e (patch) | |
tree | 517604946f4d891a5e519e7530525cca8da46bc4 | |
parent | ae9b1a4a392953097d05d55549cc1583f94c3bc8 (diff) | |
download | Qt-484770255f421d71954df4511e3541d2d4654d4e.zip Qt-484770255f421d71954df4511e3541d2d4654d4e.tar.gz Qt-484770255f421d71954df4511e3541d2d4654d4e.tar.bz2 |
Re-enable emulated QFile::map on symbian
Memory mapping of RFile handles is not supported in current symbian OS
versions. However the "open C" libraries provide an emulated mmap()
implementation which was used by QFile::map in Qt 4.6 release.
To avoid breaking applications which rely on this function, QFile::map
will now open the file with open C as well in order to use that handle
to call mmap().
When symbian implements a file mapping API, we can switch the implementation
to use that for RFile handles.
Reviewed-By: joao
-rw-r--r-- | src/corelib/io/qfile.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine.cpp | 12 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 47 | ||||
-rw-r--r-- | tests/auto/qfile/tst_qfile.cpp | 12 |
5 files changed, 37 insertions, 38 deletions
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index a0bc68e..f0ca11b 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -48,6 +48,7 @@ #include "qfileinfo.h" #include "private/qiodevice_p.h" #include "private/qfile_p.h" +#include "private/qsystemerror_p.h" #if defined(QT_BUILD_CORE_LIB) # include "qcoreapplication.h" #endif @@ -1223,6 +1224,7 @@ bool QFile::unmap(uchar *address) d->setError(d->fileEngine->error(), d->fileEngine->errorString()); return success; } + d->setError(PermissionsError, QSystemError(EACCES, QSystemError::StandardLibraryError).toString()); return false; } diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 5491caf..ae301f7 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -120,6 +120,9 @@ void QFSFileEnginePrivate::init() openMode = QIODevice::NotOpen; fd = -1; fh = 0; +#ifdef Q_OS_SYMBIAN + fileHandleForMaps = -1; +#endif lastIOCommand = IOFlushCommand; lastFlushFailed = false; closeFileHandle = false; @@ -355,6 +358,7 @@ bool QFSFileEnginePrivate::closeFdFh() if (fd == -1 && !fh #ifdef Q_OS_SYMBIAN && !symbianFile.SubSessionHandle() + && fileHandleForMaps == -1 #endif ) return false; @@ -364,6 +368,14 @@ bool QFSFileEnginePrivate::closeFdFh() bool closed = true; tried_stat = 0; +#ifdef Q_OS_SYMBIAN + // Map handle is always owned by us so always close it + if (fileHandleForMaps >= 0) { + QT_CLOSE(fileHandleForMaps); + fileHandleForMaps = -1; + } +#endif + // Close the file if we created the handle. if (closeFileHandle) { int ret; diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 715b46f..7c088b8 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -139,6 +139,8 @@ public: */ TInt symbianFilePos; #endif + mutable int fileHandleForMaps; + int getMapHandle(); #endif #ifdef Q_WS_WIN diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 28e0677..035e78f 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -85,6 +85,7 @@ static bool isRelativePathSymbian(const QString& fileName) #endif +#ifndef Q_OS_SYMBIAN /*! \internal @@ -124,6 +125,7 @@ static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QF return mode; } +#endif /*! \internal @@ -153,6 +155,7 @@ static inline int openModeToOpenFlags(QIODevice::OpenMode mode) return oflags; } +#ifndef Q_OS_SYMBIAN /*! \internal @@ -163,6 +166,7 @@ static inline bool setCloseOnExec(int fd) { return fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) != -1; } +#endif #ifdef Q_OS_SYMBIAN /*! @@ -539,6 +543,22 @@ int QFSFileEnginePrivate::nativeHandle() const return fh ? fileno(fh) : fd; } +#ifdef Q_OS_SYMBIAN +int QFSFileEnginePrivate::getMapHandle() +{ + if (symbianFile.SubSessionHandle()) { + // Symbian file handle can't be used for open C mmap() so open the file with open C as well. + if (fileHandleForMaps < 0) { + int flags = openModeToOpenFlags(openMode); + flags &= ~(O_CREAT | O_TRUNC); + fileHandleForMaps = ::wopen((wchar_t*)(fileEntry.nativeFilePath().utf16()), flags, 0666); + } + return fileHandleForMaps; + } + return nativeHandle(); +} +#endif + /*! \internal */ @@ -921,30 +941,6 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const return QDateTime(); } -#ifdef Q_OS_SYMBIAN -uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) -{ - //Q_Q(QFSFileEngine); - Q_UNUSED(flags) - Q_UNUSED(offset) - Q_UNUSED(size) - return 0; - //TODO: use RFileMap when available in symbian^4 -} - -bool QFSFileEnginePrivate::unmap(uchar *ptr) -{ - //TODO: RFileMap as the value in maps, unmap it here when API is available... - //Q_Q(QFSFileEngine); - //if (!maps.contains(ptr)) { - // q->setError(QFile::PermissionsError, qt_error_string(EACCES)); - // return false; - //} - Q_UNUSED(ptr) - - return false; -} -#else uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) { Q_Q(QFSFileEngine); @@ -985,7 +981,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla #ifdef Q_OS_SYMBIAN void *mapAddress; TRAPD(err, mapAddress = QT_MMAP((void*)0, realSize, - access, MAP_SHARED, nativeHandle(), realOffset)); + access, MAP_SHARED, getMapHandle(), realOffset)); if (err != KErrNone) { qWarning("OpenC bug: leave from mmap %d", err); mapAddress = MAP_FAILED; @@ -1035,7 +1031,6 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) maps.remove(ptr); return true; } -#endif QT_END_NAMESPACE diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 4e7cb9f..088c1f2 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -2800,10 +2800,6 @@ void tst_QFile::map() QFETCH(int, size); QFETCH(QFile::FileError, error); -#ifdef Q_OS_SYMBIAN - QSKIP("memory mapped files not supported on this platform", SkipAll); -#endif - QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; #ifdef Q_WS_WINCE @@ -2925,10 +2921,6 @@ void tst_QFile::mapResource() QFETCH(int, size); QFETCH(QFile::FileError, error); -#ifdef Q_OS_SYMBIAN - QSKIP("memory mapped files not supported on this platform", SkipAll); -#endif - QFile file(fileName); uchar *memory = file.map(offset, size); QCOMPARE(file.error(), error); @@ -2954,10 +2946,6 @@ void tst_QFile::mapOpenMode() QFETCH(int, openMode); static const qint64 fileSize = 4096; -#ifdef Q_OS_SYMBIAN - QSKIP("memory mapped files not supported on this platform", SkipAll); -#endif - QByteArray pattern(fileSize, 'A'); QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; |