diff options
-rw-r--r-- | src/corelib/io/qfile.cpp | 20 | ||||
-rw-r--r-- | tests/auto/corelib/io/qfile/tst_qfile.cpp | 44 |
2 files changed, 54 insertions, 10 deletions
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 22b8ae5d2d..dc926caa1f 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -902,12 +902,12 @@ bool QFile::open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags) } if (d->openExternalFile(mode, fh, handleFlags)) { QIODevice::open(mode); - if (mode & Append) { - seek(size()); - } else { + if (!(mode & Append) && !isSequential()) { qint64 pos = (qint64)QT_FTELL(fh); - if (pos != -1) - seek(pos); + if (pos != -1) { + // Skip redundant checks in QFileDevice::seek(). + QIODevice::seek(pos); + } } return true; } @@ -960,12 +960,12 @@ bool QFile::open(int fd, OpenMode mode, FileHandleFlags handleFlags) } if (d->openExternalFile(mode, fd, handleFlags)) { QIODevice::open(mode); - if (mode & Append) { - seek(size()); - } else { + if (!(mode & Append) && !isSequential()) { qint64 pos = (qint64)QT_LSEEK(fd, QT_OFF_T(0), SEEK_CUR); - if (pos != -1) - seek(pos); + if (pos != -1) { + // Skip redundant checks in QFileDevice::seek(). + QIODevice::seek(pos); + } } return true; } diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index ae80159e88..bb280100b9 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -3065,6 +3065,40 @@ static qint64 streamCurrentPosition(FILE *f) return 0; } +class MessageHandler { +public: + MessageHandler(QtMessageHandler messageHandler = handler) + { + ok = true; + oldMessageHandler = qInstallMessageHandler(messageHandler); + } + + ~MessageHandler() + { + qInstallMessageHandler(oldMessageHandler); + } + + static bool testPassed() + { + return ok; + } +protected: + static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg) + { + if (msg == QString::fromLatin1("QIODevice::seek: Cannot call seek on a sequential device")) + ok = false; + // Defer to old message handler. + if (oldMessageHandler) + oldMessageHandler(type, context, msg); + } + + static QtMessageHandler oldMessageHandler; + static bool ok; +}; + +bool MessageHandler::ok = true; +QtMessageHandler MessageHandler::oldMessageHandler = 0; + void tst_QFile::openStandardStreamsFileDescriptors() { #ifdef Q_OS_WINCE @@ -3074,6 +3108,9 @@ void tst_QFile::openStandardStreamsFileDescriptors() QSKIP("Opening standard streams on Windows CE via descriptor not implemented"); #endif + // Check that QIODevice::seek() isn't called when opening a sequential device (QFile). + MessageHandler msgHandler; + { QFile in; in.open(STDIN_FILENO, QIODevice::ReadOnly); @@ -3094,6 +3131,8 @@ void tst_QFile::openStandardStreamsFileDescriptors() QCOMPARE( err.pos(), streamCurrentPosition(STDERR_FILENO) ); QCOMPARE( err.size(), streamExpectedSize(STDERR_FILENO) ); } + + QVERIFY(msgHandler.testPassed()); } void tst_QFile::openStandardStreamsBufferedStreams() @@ -3101,6 +3140,9 @@ void tst_QFile::openStandardStreamsBufferedStreams() #ifdef Q_OS_WINCE QSKIP("Not tested on Windows CE."); #endif + // Check that QIODevice::seek() isn't called when opening a sequential device (QFile). + MessageHandler msgHandler; + // Using streams { QFile in; @@ -3122,6 +3164,8 @@ void tst_QFile::openStandardStreamsBufferedStreams() QCOMPARE( err.pos(), streamCurrentPosition(stderr) ); QCOMPARE( err.size(), streamExpectedSize(QT_FILENO(stderr)) ); } + + QVERIFY(msgHandler.testPassed()); } void tst_QFile::writeNothing() |