diff options
author | Markus Goetz <Markus.Goetz@nokia.com> | 2009-11-30 14:28:47 (GMT) |
---|---|---|
committer | Markus Goetz <Markus.Goetz@nokia.com> | 2009-11-30 15:04:11 (GMT) |
commit | b5bf6d68bdde5f5db1d72179f4e20dc1e21d20c4 (patch) | |
tree | 04da04f42f5bdb7800e637b5eea717a667420260 | |
parent | 132eccca92a90e4d67ba8b5a4052384a2b2cfdf9 (diff) | |
download | Qt-b5bf6d68bdde5f5db1d72179f4e20dc1e21d20c4.zip Qt-b5bf6d68bdde5f5db1d72179f4e20dc1e21d20c4.tar.gz Qt-b5bf6d68bdde5f5db1d72179f4e20dc1e21d20c4.tar.bz2 |
Unix: Avoid stat() when opening a file
The open() syscall can open directories for reading, which we
in QFile and file engines don't support. However, there is no need
for stat() to find out if it is a directory if we open() with a write
flag because then the syscall will fail anyway.
Reviewed-by: joao
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 32 | ||||
-rw-r--r-- | tests/auto/qfile/tst_qfile.cpp | 13 |
2 files changed, 32 insertions, 13 deletions
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 8cbf6a3..71414ce 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -191,12 +191,16 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) return false; } - QT_STATBUF statBuf; - if (QT_FSTAT(fd, &statBuf) != -1) { - if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { - q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); - QT_CLOSE(fd); - return false; + if (!(openMode & QIODevice::WriteOnly)) { + // we don't need this check if we tried to open for writing because then + // we had received EISDIR anyway. + QT_STATBUF statBuf; + if (QT_FSTAT(fd, &statBuf) != -1) { + if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { + q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); + QT_CLOSE(fd); + return false; + } } } @@ -230,12 +234,16 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) return false; } - QT_STATBUF statBuf; - if (QT_FSTAT(fileno(fh), &statBuf) != -1) { - if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { - q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); - fclose(fh); - return false; + if (!(openMode & QIODevice::WriteOnly)) { + // we don't need this check if we tried to open for writing because then + // we had received EISDIR anyway. + QT_STATBUF statBuf; + if (QT_FSTAT(fileno(fh), &statBuf) != -1) { + if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { + q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); + fclose(fh); + return false; + } } } diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index cf46ce1..7ee5665 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -2783,10 +2783,21 @@ void tst_QFile::mapOpenMode() void tst_QFile::openDirectory() { - QFile f1("resources"); + QFile f1(SRCDIR "resources"); + // it's a directory, it must exist + QVERIFY(f1.exists()); + + // ...but not be openable QVERIFY(!f1.open(QIODevice::ReadOnly)); f1.close(); QVERIFY(!f1.open(QIODevice::ReadOnly|QIODevice::Unbuffered)); + f1.close(); + QVERIFY(!f1.open(QIODevice::ReadWrite)); + f1.close(); + QVERIFY(!f1.open(QIODevice::WriteOnly)); + f1.close(); + QVERIFY(!f1.open(QIODevice::WriteOnly|QIODevice::Unbuffered)); + f1.close(); } void tst_QFile::openStandardStreams() |