summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2010-10-22 15:00:24 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2010-10-29 13:22:09 (GMT)
commit484770255f421d71954df4511e3541d2d4654d4e (patch)
tree517604946f4d891a5e519e7530525cca8da46bc4
parentae9b1a4a392953097d05d55549cc1583f94c3bc8 (diff)
downloadQt-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.cpp2
-rw-r--r--src/corelib/io/qfsfileengine.cpp12
-rw-r--r--src/corelib/io/qfsfileengine_p.h2
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp47
-rw-r--r--tests/auto/qfile/tst_qfile.cpp12
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";