OSDN Git Service

merge QAbstractFileEngine into QFile
authorIvailo Monev <xakepa10@gmail.com>
Mon, 31 Oct 2022 08:28:06 +0000 (10:28 +0200)
committerIvailo Monev <xakepa10@gmail.com>
Mon, 31 Oct 2022 09:23:39 +0000 (11:23 +0200)
the behaviour of QTemporaryFile changes slightly, e.g. downcast to QFile
and open() with flags does not work like before - if you down-cast
better be sure you want to call the down-casted method (it is like a
C-style cast)

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
16 files changed:
src/core/CMakeLists.txt
src/core/io/qabstractfileengine.cpp [deleted file]
src/core/io/qabstractfileengine.h [deleted file]
src/core/io/qabstractfileengine_p.h [deleted file]
src/core/io/qfile.cpp
src/core/io/qfile.h
src/core/io/qfile_p.h
src/core/io/qfileinfo.cpp
src/core/io/qfileinfo_p.h
src/core/io/qfilesystemengine_unix.cpp
src/core/io/qfilesystemmetadata_p.h
src/core/io/qtemporaryfile.cpp
src/core/io/qtemporaryfile.h
src/tools/moc/CMakeLists.txt
tests/auto/qfile/tst_qfile.cpp
tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp

index ce70ddc..06e45ac 100644 (file)
@@ -18,7 +18,6 @@ set(CORE_PUBLIC_HEADERS
     QHash
     QLibrary
     QObjectCleanupHandler
-    QAbstractFileEngine
     QTranslator
     QWaitCondition
     QMimeData
@@ -104,8 +103,6 @@ set(CORE_HEADERS
     ${CMAKE_CURRENT_SOURCE_DIR}/global/qnamespace.h
     ${CMAKE_CURRENT_SOURCE_DIR}/global/qnumeric.h
     ${CMAKE_CURRENT_SOURCE_DIR}/global/qplatformdefs.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/io/qabstractfileengine.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/io/qabstractfileengine_p.h
     ${CMAKE_CURRENT_SOURCE_DIR}/io/qbuffer.h
     ${CMAKE_CURRENT_SOURCE_DIR}/io/qdatastream.h
     ${CMAKE_CURRENT_SOURCE_DIR}/io/qdataurl_p.h
@@ -229,7 +226,6 @@ set(CORE_SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/global/qglobal.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/global/qlibraryinfo.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/global/qt_error_string.cpp
-    ${CMAKE_CURRENT_SOURCE_DIR}/io/qabstractfileengine.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/io/qbuffer.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/io/qdatastream.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/io/qdataurl.cpp
diff --git a/src/core/io/qabstractfileengine.cpp b/src/core/io/qabstractfileengine.cpp
deleted file mode 100644 (file)
index db09e0a..0000000
+++ /dev/null
@@ -1,1025 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Copyright (C) 2016 Ivailo Monev
-**
-** This file is part of the QtCore module of the Katie Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-**
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qabstractfileengine.h"
-#include "qabstractfileengine_p.h"
-#include "qdatetime.h"
-#include "qdebug.h"
-#include "qfilesystementry_p.h"
-#include "qfilesystemengine_p.h"
-#include "qfileinfo_p.h"
-#include "qcore_unix_p.h"
-
-#include <sys/mman.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-QAbstractFileEnginePrivate::QAbstractFileEnginePrivate()
-    : fileError(QFile::UnspecifiedError),
-    openMode(QIODevice::NotOpen),
-    fd(-1),
-    closeFileHandle(false)
-{
-}
-
-bool QAbstractFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const
-{
-    if (!metaData.hasFlags(flags)) {
-        if (!fileEntry.isEmpty())
-            QFileSystemEngine::fillMetaData(fileEntry, metaData, metaData.missingFlags(flags));
-
-        if (metaData.missingFlags(flags) && fd != -1)
-            QFileSystemEngine::fillMetaData(fd, metaData);
-    }
-
-    return metaData.exists();
-}
-
-uchar *QAbstractFileEnginePrivate::map(qint64 offset, qint64 size)
-{
-    Q_Q(QAbstractFileEngine);
-    if (openMode == QIODevice::NotOpen) {
-        q->setError(QFile::PermissionsError, qt_error_string(EACCES));
-        return 0;
-    }
-
-    if (offset < 0 || offset != qint64(QT_OFF_T(offset))
-            || size < 0 || quint64(size) > quint64(size_t(-1))) {
-        q->setError(QFile::UnspecifiedError, qt_error_string(EINVAL));
-        return 0;
-    }
-
-    // If we know the mapping will extend beyond EOF, fail early to avoid
-    // undefined behavior. Otherwise, let mmap have its say.
-    if (doStat(QFileSystemMetaData::SizeAttribute)
-            && (QT_OFF_T(size) > metaData.size() - QT_OFF_T(offset)))
-        qWarning("QAbstractFileEngine::map: Mapping a file beyond its size is not portable");
-
-    int access = 0;
-    if (openMode & QIODevice::ReadOnly) access |= PROT_READ;
-    if (openMode & QIODevice::WriteOnly) access |= PROT_WRITE;
-
-    static const int pageSize = ::getpagesize();
-    const int extra = offset % pageSize;
-
-    if (quint64(size + extra) > quint64((size_t)-1)) {
-        q->setError(QFile::UnspecifiedError, qt_error_string(EINVAL));
-        return 0;
-    }
-
-    size_t realSize = (size_t)size + extra;
-    QT_OFF_T realOffset = QT_OFF_T(offset);
-    realOffset &= ~(QT_OFF_T(pageSize - 1));
-
-    void *mapAddress = QT_MMAP(nullptr, realSize,
-                   access, MAP_SHARED, fd, realOffset);
-    if (mapAddress != MAP_FAILED) {
-        uchar *address = extra + static_cast<uchar*>(mapAddress);
-        maps[address] = QPair<int,size_t>(extra, realSize);
-        return address;
-    }
-
-    switch(errno) {
-    case EBADF:
-        q->setError(QFile::PermissionsError, qt_error_string(EACCES));
-        break;
-    case ENFILE:
-    case ENOMEM:
-        q->setError(QFile::ResourceError, qt_error_string(errno));
-        break;
-    case EINVAL:
-        // size are out of bounds
-    default:
-        q->setError(QFile::UnspecifiedError, qt_error_string(errno));
-        break;
-    }
-    return 0;
-}
-
-bool QAbstractFileEnginePrivate::unmap(uchar *ptr)
-{
-    Q_Q(QAbstractFileEngine);
-    if (!maps.contains(ptr)) {
-        q->setError(QFile::PermissionsError, qt_error_string(EACCES));
-        return false;
-    }
-
-    uchar *start = ptr - maps[ptr].first;
-    size_t len = maps[ptr].second;
-    if (::munmap(start, len) == -1) {
-        q->setError(QFile::UnspecifiedError, qt_error_string(errno));
-        return false;
-    }
-    maps.remove(ptr);
-    return true;
-}
-
-/*!
-    Creates and returns a QAbstractFileEngine suitable for processing \a
-    fileName.
-*/
-QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName)
-{
-    // fall back to regular file engine
-    QAbstractFileEngine *engine = new QAbstractFileEngine();
-    engine->d_ptr->fileEntry = QFileSystemEntry(fileName);
-    return engine;
-}
-
-/*!
-    \enum QAbstractFileEngine::FileName
-
-    These values are used to request a file name in a particular
-    format.
-
-    \value DefaultName The same filename that was passed to the
-    QAbstractFileEngine.
-    \value BaseName The name of the file excluding the path.
-    \value PathName The path to the file excluding the base name.
-    \value AbsoluteName The absolute path to the file (including
-    the base name).
-    \value AbsolutePathName The absolute path to the file (excluding
-    the base name).
-    \value LinkName The full file name of the file that this file is a
-    link to. (This will be empty if this file is not a link.)
-    \value CanonicalName Often very similar to LinkName. Will return the true path to the file.
-    \value CanonicalPathName Same as CanonicalName, excluding the base name.
-
-    \omitvalue NFileNames
-
-    \sa fileName(), setFileName()
-*/
-
-/*!
-    \enum QAbstractFileEngine::FileTime
-
-    These are used by the fileTime() function.
-
-    \value CreationTime When the file was created.
-    \value ModificationTime When the file was most recently modified.
-    \value AccessTime When the file was most recently accessed (e.g.
-    read or written to).
-
-    \sa setFileName()
-*/
-
-/*!
-    \enum QAbstractFileEngine::FileOwner
-
-    \value OwnerUser The user who owns the file.
-    \value OwnerGroup The group who owns the file.
-
-    \sa owner(), ownerId(), setFileName()
-*/
-
-/*!
-   Constructs a new QAbstractFileEngine that does not refer to any file or directory.
-
-   \sa setFileName()
- */
-QAbstractFileEngine::QAbstractFileEngine()
-    : d_ptr(new QAbstractFileEnginePrivate())
-{
-    d_ptr->q_ptr = this;
-}
-
-/*!
-   \internal
-
-   Constructs a QAbstractFileEngine.
- */
-QAbstractFileEngine::QAbstractFileEngine(QAbstractFileEnginePrivate &dd)
-    : d_ptr(&dd)
-{
-    d_ptr->q_ptr = this;
-}
-
-/*!
-    Destroys the QAbstractFileEngine.
- */
-QAbstractFileEngine::~QAbstractFileEngine()
-{
-    Q_D(QAbstractFileEngine);
-    if (d->closeFileHandle) {
-        if (d->fd != -1) {
-            qt_safe_close(d->fd);
-        }
-    }
-    QList<uchar*> keys = d->maps.keys();
-    for (int i = 0; i < keys.count(); ++i)
-        unmap(keys.at(i));
-
-    delete d_ptr;
-}
-
-/*!
-    \fn bool QAbstractFileEngine::open(QIODevice::OpenMode mode)
-
-    Opens the file in the specified \a mode. Returns true if the file
-    was successfully opened; otherwise returns false.
-
-    The \a mode is an OR combination of QIODevice::OpenMode and
-    QIODevice::HandlingMode values.
-*/
-bool QAbstractFileEngine::open(QIODevice::OpenMode openMode)
-{
-    Q_D(QAbstractFileEngine);
-    if (Q_UNLIKELY(d->fileEntry.isEmpty())) {
-        qWarning("QAbstractFileEngine::open: No file name specified");
-        setError(QFile::OpenError, QLatin1String("No file name specified"));
-        return false;
-    }
-
-    // Append implies WriteOnly.
-    if (openMode & QFile::Append)
-        openMode |= QFile::WriteOnly;
-
-    // WriteOnly implies Truncate if neither ReadOnly nor Append are sent.
-    if ((openMode & QFile::WriteOnly) && !(openMode & (QFile::ReadOnly | QFile::Append)))
-        openMode |= QFile::Truncate;
-
-    d->openMode = openMode;
-    d->metaData.clear();
-    d->fd = -1;
-
-    int flags = QT_OPEN_RDONLY;
-
-    if ((d->openMode & QFile::ReadWrite) == QFile::ReadWrite) {
-        flags = QT_OPEN_RDWR | QT_OPEN_CREAT;
-    } else if (d->openMode & QFile::WriteOnly) {
-        flags = QT_OPEN_WRONLY | QT_OPEN_CREAT;
-    }
-
-    if (d->openMode & QFile::Append) {
-        flags |= QT_OPEN_APPEND;
-    } else if (d->openMode & QFile::WriteOnly) {
-        if ((d->openMode & QFile::Truncate) || !(d->openMode & QFile::ReadOnly))
-            flags |= QT_OPEN_TRUNC;
-    }
-
-    if (d->openMode & QFile::Unbuffered) {
-#ifdef O_DSYNC
-        flags |= O_DSYNC;
-#else
-        flags |= O_SYNC;
-#endif
-    }
-
-    // Try to open the file.
-    const QByteArray native = d->fileEntry.nativeFilePath();
-    d->fd = qt_safe_open(native.constData(), flags, 0666);
-
-    // On failure, return and report the error.
-    if (d->fd == -1) {
-        setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
-                 qt_error_string(errno));
-        d->openMode = QIODevice::NotOpen;
-        return false;
-    }
-
-    // Refuse to open directories, EISDIR is not a thing (by standards) for
-    // non-write modes.
-    QT_STATBUF statbuf;
-    if (QT_FSTAT(d->fd, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
-        setError(QFile::OpenError, QLatin1String("file to open is a directory"));
-        qt_safe_close(d->fd);
-        d->openMode = QIODevice::NotOpen;
-        d->fd = -1;
-        return false;
-    }
-
-    // Seek to the end when in Append mode.
-    if (d->openMode & QFile::Append) {
-        if (QT_LSEEK(d->fd, 0, SEEK_END) == -1) {
-            setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
-                     qt_error_string(errno));
-            qt_safe_close(d->fd);
-            d->openMode = QIODevice::NotOpen;
-            d->fd = -1;
-            return false;
-        }
-    }
-
-    d->closeFileHandle = true;
-
-    return true;
-}
-
-/*!
-    Closes the file, returning true if successful; otherwise returns false.
-
-    The default implementation always returns false.
-*/
-bool QAbstractFileEngine::close()
-{
-    Q_D(QAbstractFileEngine);
-    d->openMode = QIODevice::NotOpen;
-
-    if (d->fd == -1)
-        return false;
-
-    d->metaData.clear();
-
-    // Close the file if we created the handle.
-    if (d->closeFileHandle) {
-        int ret = qt_safe_close(d->fd);
-
-        // We must reset these guys regardless; calling close again after a
-        // failed close causes crashes on some systems.
-        d->fd = -1;
-
-        // Report errors.
-        if (ret != 0) {
-            setError(QFile::UnspecifiedError, qt_error_string(errno));
-            return false;
-        }
-    }
-
-    return true;
-}
-
-/*!
-    Flushes the open file, returning true if successful; otherwise returns
-    false.
-
-    The default implementation always returns false.
-*/
-bool QAbstractFileEngine::flush()
-{
-    Q_D(const QAbstractFileEngine);
-    return (d->fd != -1);
-}
-
-/*!
-    Returns the size of the file.
-*/
-qint64 QAbstractFileEngine::size() const
-{
-    Q_D(const QAbstractFileEngine);
-
-    d->metaData.clear();
-    if (!d->doStat(QFileSystemMetaData::SizeAttribute))
-        return 0;
-    return d->metaData.size();
-}
-
-/*!
-    Returns the current file position.
-
-    This is the position of the data read/write head of the file.
-*/
-qint64 QAbstractFileEngine::pos() const
-{
-    Q_D(const QAbstractFileEngine);
-    return (qint64)QT_LSEEK(d->fd, 0, SEEK_CUR);
-}
-
-/*!
-    \fn bool QAbstractFileEngine::seek(qint64 offset)
-
-    Sets the file position to the given \a offset. Returns true if
-    the position was successfully set; otherwise returns false.
-
-    The offset is from the beginning of the file, unless the
-    file is sequential.
-
-    \sa isSequential()
-*/
-bool QAbstractFileEngine::seek(qint64 pos)
-{
-    Q_D(QAbstractFileEngine);
-
-    if (pos < 0 || pos != qint64(QT_OFF_T(pos)))
-        return false;
-
-    if (Q_UNLIKELY(QT_LSEEK(d->fd, QT_OFF_T(pos), SEEK_SET) == -1)) {
-        qWarning("QAbstractFileEngine::seek: Cannot set file position %lld", pos);
-        setError(QFile::PositionError, qt_error_string(errno));
-        return false;
-    }
-    return true;
-}
-
-/*!
-    Returns true if the file is a sequential access device; returns
-    false if the file is a direct access device.
-
-    Operations involving size() and seek(int) are not valid on
-    sequential devices.
-*/
-bool QAbstractFileEngine::isSequential() const
-{
-    Q_D(const QAbstractFileEngine);
-    if (d->doStat(QFileSystemMetaData::SequentialType))
-        return d->metaData.isSequential();
-    return true;
-}
-
-/*!
-    Requests that the file is deleted from the file system. If the
-    operation succeeds return true; otherwise return false.
-
-    \sa setFileName() rmdir()
- */
-bool QAbstractFileEngine::remove()
-{
-    Q_D(QAbstractFileEngine);
-    int error;
-    bool ret = QFileSystemEngine::removeFile(d->fileEntry, &error);
-    d->metaData.clear();
-    if (!ret) {
-        setError(QFile::RemoveError, qt_error_string(error));
-    }
-    return ret;
-}
-
-/*!
-    Copies the contents of this file to a file with the name \a newName.
-    Returns true on success; otherwise, false is returned.
-*/
-bool QAbstractFileEngine::copy(const QString &newName)
-{
-    Q_D(QAbstractFileEngine);
-    int error;
-    bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(newName), &error);
-    if (!ret) {
-        setError(QFile::CopyError, qt_error_string(error));
-    }
-    return ret;
-}
-
-/*!
-    Requests that the file be renamed to \a newName in the file
-    system. If the operation succeeds return true; otherwise return
-    false.
-
-    \sa setFileName()
- */
-bool QAbstractFileEngine::rename(const QString &newName)
-{
-    Q_D(QAbstractFileEngine);
-    int error;
-    bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), &error);
-    d->metaData.clear();
-    if (!ret) {
-        setError(QFile::RenameError, qt_error_string(error));
-    }
-
-    return ret;
-}
-
-/*!
-    Creates a link from the file currently specified by fileName() to
-    \a newName. What a link is depends on the underlying filesystem
-    (be it a shortcut on Windows or a symbolic link on Unix). Returns
-    true if successful; otherwise returns false.
-*/
-bool QAbstractFileEngine::link(const QString &newName)
-{
-    Q_D(QAbstractFileEngine);
-    int error;
-    bool ret = QFileSystemEngine::createLink(d->fileEntry, QFileSystemEntry(newName), &error);
-    if (!ret) {
-        setError(QFile::RenameError, qt_error_string(error));
-    }
-    return ret;
-}
-
-/*!
-    Requests that the file be set to size \a size. If \a size is larger
-    than the current file then it is filled with 0's, if smaller it is
-    simply truncated. If the operations succceeds return true; otherwise
-    return false;
-
-    \sa size()
-*/
-bool QAbstractFileEngine::setSize(qint64 size)
-{
-    Q_D(QAbstractFileEngine);
-    int ret = 0;
-    if (d->fd != -1) {
-        Q_EINTR_LOOP(ret, QT_FTRUNCATE(d->fd, size));
-    } else {
-        Q_EINTR_LOOP(ret, QT_TRUNCATE(d->fileEntry.nativeFilePath().constData(), size));
-    }
-    d->metaData.clearFlags(QFileSystemMetaData::SizeAttribute);
-    if (ret == -1) {
-        setError(QFile::ResizeError, qt_error_string(errno));
-        return false;
-    }
-    return true;
-}
-
-/*!
-    Return true if the file referred to by this file engine has a
-    relative path; otherwise return false.
-
-    \sa setFileName()
-*/
-bool QAbstractFileEngine::isRelativePath() const
-{
-    Q_D(const QAbstractFileEngine);
-    return d->fileEntry.filePath().length() ? d->fileEntry.filePath()[0] != QLatin1Char('/') : true;
-}
-
-/*!
-    Return true if the file referred to by this file engine exists;
-    otherwise return false.
-*/
-bool QAbstractFileEngine::exists() const
-{
-    Q_D(const QAbstractFileEngine);
-    d->metaData.clear(); // always stat
-    if (!d->doStat(QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::FileType))
-        return false;
-    return d->metaData.exists() && d->metaData.isFile();
-}
-
-/*!
-    Return the set of permissions for the file engine's file.
-
-    \sa setFileName()
-*/
-QFile::Permissions QAbstractFileEngine::permissions() const
-{
-    Q_D(const QAbstractFileEngine);
-    bool exists = d->doStat(QFileSystemMetaData::Permissions | QFileSystemMetaData::LinkType);
-    if (!exists && !d->metaData.isLink())
-        return 0;
-    return d->metaData.permissions();
-}
-
-/*!
-    Requests that the file's permissions be set to \a perms. The argument
-    perms will be set to the OR-ed together combination of
-    QAbstractFileEngine::FileInfo, with only the QAbstractFileEngine::PermsMask being
-    honored. If the operations succceeds return true; otherwise return
-    false;
-
-    \sa size()
-*/
-bool QAbstractFileEngine::setPermissions(uint perms)
-{
-    Q_D(QAbstractFileEngine);
-    int error;
-    if (!QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(perms), &error)) {
-        setError(QFile::PermissionsError, qt_error_string(error));
-        return false;
-    }
-    return true;
-}
-
-/*!
-    Return  the file engine's current file name in the format
-    specified by \a file.
-
-    If you don't handle some \c FileName possibilities, return the
-    file name set in setFileName() when an unhandled format is
-    requested.
-
-    \sa setFileName(), FileName
- */
-QString QAbstractFileEngine::fileName(FileName file) const
-{
-    Q_D(const QAbstractFileEngine);
-    if (file == BaseName) {
-        return d->fileEntry.fileName();
-    } else if (file == PathName) {
-        return d->fileEntry.path();
-    } else if (file == AbsoluteName || file == AbsolutePathName) {
-        QFileSystemEntry entry(QFileSystemEngine::absoluteName(d->fileEntry));
-        if (file == AbsolutePathName) {
-            return entry.path();
-        }
-        return entry.filePath();
-    } else if (file == CanonicalName || file == CanonicalPathName) {
-        QFileSystemEntry entry(QFileSystemEngine::canonicalName(d->fileEntry, d->metaData));
-        if (file == CanonicalPathName)
-            return entry.path();
-        return entry.filePath();
-    } else if (file == LinkName) {
-        if (!d->metaData.hasFlags(QFileSystemMetaData::LinkType))
-            QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::LinkType);
-        if (d->metaData.isLink()) {
-            QFileSystemEntry entry = QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData);
-            return entry.filePath();
-        }
-        return QString();
-    }
-    return d->fileEntry.filePath();
-}
-
-/*!
-    If \a owner is \c OwnerUser return the ID of the user who owns
-    the file. If \a owner is \c OwnerGroup return the ID of the group
-    that own the file. If you can't determine the owner return -2.
-
-    \sa owner() setFileName(), FileOwner
- */
-uint QAbstractFileEngine::ownerId(FileOwner owner) const
-{
-    Q_D(const QAbstractFileEngine);
-
-    if (d->doStat(QFileSystemMetaData::OwnerIds)) {
-        if (owner == QAbstractFileEngine::OwnerUser)
-            return d->metaData.userId();
-        return d->metaData.groupId();
-    }
-
-    return QFileSystemMetaData::nobodyID;
-}
-
-/*!
-    If \a owner is \c OwnerUser return the name of the user who owns
-    the file. If \a owner is \c OwnerGroup return the name of the group
-    that own the file. If you can't determine the owner return
-    QString().
-
-    \sa ownerId() setFileName(), FileOwner
- */
-QString QAbstractFileEngine::owner(FileOwner owner) const
-{
-    if (owner == QAbstractFileEngine::OwnerUser)
-        return QFileSystemEngine::resolveUserName(ownerId(owner));
-    return QFileSystemEngine::resolveGroupName(ownerId(owner));
-}
-
-/*!
-    If \a time is \c CreationTime, return when the file was created.
-    If \a time is \c ModificationTime, return when the file was most
-    recently modified. If \a time is \c AccessTime, return when the
-    file was most recently accessed (e.g. read or written).
-    If the time cannot be determined return QDateTime() (an invalid
-    date time).
-
-    \sa setFileName(), QDateTime, QDateTime::isValid(), FileTime
- */
-QDateTime QAbstractFileEngine::fileTime(FileTime time) const
-{
-    Q_D(const QAbstractFileEngine);
-
-    if (d->doStat(QFileSystemMetaData::Times)) {
-        switch (time) {
-        case QAbstractFileEngine::ModificationTime:
-            return d->metaData.modificationTime();
-        case QAbstractFileEngine::AccessTime:
-            return d->metaData.accessTime();
-        case QAbstractFileEngine::CreationTime:
-            return d->metaData.creationTime();
-        }
-    }
-
-    return QDateTime();
-}
-
-/*!
-    Sets the file engine's file name to \a file. This file name is the
-    file that the rest of the functions will operate on.
-
-    \sa rename()
- */
-void QAbstractFileEngine::setFileName(const QString &file)
-{
-    Q_D(QAbstractFileEngine);
-    d->metaData.clear();
-    d->openMode = QIODevice::NotOpen;
-    d->fd = -1;
-    d->closeFileHandle = false;
-    d->fileEntry = QFileSystemEntry(file);
-}
-
-/*!
-    Returns the native file handle for this file engine. This handle must be
-    used with care; its value and type are platform specific, and using it
-    will most likely lead to non-portable code.
-*/
-int QAbstractFileEngine::handle() const
-{
-    Q_D(const QAbstractFileEngine);
-    return d->fd;
-}
-
-/*!
-    \since 4.4
-
-    Maps \a size bytes of the file into memory starting at \a offset.
-    Returns a pointer to the memory if successful; otherwise returns false
-    if, for example, an error occurs.
-
-    \sa unmap(), supportsExtension()
- */
-
-uchar *QAbstractFileEngine::map(qint64 offset, qint64 size)
-{
-    MapExtensionOption option;
-    option.offset = offset;
-    option.size = size;
-    MapExtensionReturn r;
-    if (!extension(MapExtension, &option, &r))
-        return 0;
-    return r.address;
-}
-
-/*!
-    \since 4.4
-
-    Unmaps the memory \a address.  Returns true if the unmap succeeds; otherwise
-    returns false.
-
-    \sa map(), supportsExtension()
- */
-bool QAbstractFileEngine::unmap(uchar *address)
-{
-    UnMapExtensionOption options;
-    options.address = address;
-    return extension(UnMapExtension, &options);
-}
-
-/*!
-    Reads a number of characters from the file into \a data. At most
-    \a maxlen characters will be read.
-
-    Returns -1 if a fatal error occurs, or 0 if there are no bytes to
-    read.
-*/
-qint64 QAbstractFileEngine::read(char *data, qint64 maxlen)
-{
-    Q_D(QAbstractFileEngine);
-
-    if (maxlen < 0) {
-        setError(QFile::ReadError, qt_error_string(EINVAL));
-        return -1;
-    }
-
-    qint64 readBytes = 0;
-    bool eof = false;
-
-    if (d->fd != -1) {
-        ssize_t result;
-        do {
-            result = QT_READ(d->fd, data + readBytes, size_t(maxlen - readBytes));
-        } while ((result == -1 && errno == EINTR)
-                || (result > 0 && (readBytes += result) < maxlen));
-
-        eof = !(result == -1);
-    }
-
-    if (!eof && readBytes == 0) {
-        readBytes = -1;
-        setError(QFile::ReadError, qt_error_string(errno));
-    }
-
-    return readBytes;
-}
-
-/*!
-    Writes \a len bytes from \a data to the file. Returns the number
-    of characters written on success; otherwise returns -1.
-*/
-qint64 QAbstractFileEngine::write(const char *data, qint64 len)
-{
-    Q_D(QAbstractFileEngine);
-
-    if (len < 0 || len != qint64(size_t(len))) {
-        setError(QFile::WriteError, qt_error_string(EINVAL));
-        return -1;
-    }
-
-    qint64 writtenBytes = 0;
-
-    if (d->fd != -1) {
-        ssize_t result;
-        do {
-            result = QT_WRITE(d->fd, data + writtenBytes, size_t(len - writtenBytes));
-        } while ((result == -1 && errno == EINTR)
-                || (result > 0 && (writtenBytes += result) < len));
-    }
-
-    if (len && writtenBytes == 0) {
-        writtenBytes = -1;
-        setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError, qt_error_string(errno));
-    }
-
-    d->metaData.clearFlags(QFileSystemMetaData::SizeAttribute);
-
-    return writtenBytes;
-}
-
-/*!
-    Reads one line, terminated by a '\n' character, from the file info
-    \a data. At most \a maxlen characters will be read. The end-of-line
-    character is included.
-*/
-qint64 QAbstractFileEngine::readLine(char *data, qint64 maxlen)
-{
-    qint64 readSoFar = 0;
-    while (readSoFar < maxlen) {
-        char c;
-        qint64 readResult = read(&c, 1);
-        if (readResult <= 0)
-            return (readSoFar > 0) ? readSoFar : -1;
-        ++readSoFar;
-        *data++ = c;
-        if (c == '\n')
-            return readSoFar;
-    }
-    return readSoFar;
-}
-
-/*!
-   \enum QAbstractFileEngine::Extension
-   \since 4.3
-
-   This enum describes the types of extensions that the file engine can
-   support. Before using these extensions, you must verify that the extension
-   is supported (i.e., call supportsExtension()).
-
-   \value FastReadLineExtension Whether the file engine provides a
-   fast implementation for readLine() or not. If readLine() remains
-   unimplemented in the file engine, QAbstractFileEngine will provide
-   an implementation based on calling read() repeatedly. If
-   supportsExtension() returns false for this extension, however,
-   QIODevice can provide a faster implementation by making use of its
-   internal buffer. For engines that already provide a fast readLine()
-   implementation, returning false for this extension can avoid
-   unnnecessary double-buffering in QIODevice.
-
-   \value MapExtension Whether the file engine provides the ability to map
-   a file to memory.
-
-   \value UnMapExtension Whether the file engine provides the ability to
-   unmap memory that was previously mapped.
-*/
-
-/*!
-   \class QAbstractFileEngine::ExtensionOption
-   \since 4.3
-   \brief provides an extended input argument to QAbstractFileEngine's
-   extension support.
-
-   \sa QAbstractFileEngine::extension()
-*/
-
-/*!
-   \class QAbstractFileEngine::ExtensionReturn
-   \since 4.3
-   \brief provides an extended output argument to QAbstractFileEngine's
-   extension support.
-
-   \sa QAbstractFileEngine::extension()
-*/
-
-/*!
-    \since 4.3
-
-    The \a option argument is provided as input to the extension, and
-    this function can store output results in \a output.
-
-    The behavior of this function is determined by \a extension; see the
-    Extension documentation for details.
-
-    You can call supportsExtension() to check if an extension is supported by
-    the file engine.
-
-    By default, map and unmap extensions are supported.
-
-    \sa supportsExtension(), Extension
-*/
-bool QAbstractFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
-{
-    Q_D(QAbstractFileEngine);
-
-    if (extension == MapExtension) {
-        const MapExtensionOption *options = (MapExtensionOption*)(option);
-        MapExtensionReturn *returnValue = static_cast<MapExtensionReturn*>(output);
-        returnValue->address = d->map(options->offset, options->size);
-        return (returnValue->address != 0);
-    } else if (extension == UnMapExtension) {
-        UnMapExtensionOption *options = (UnMapExtensionOption*)option;
-        return d->unmap(options->address);
-    }
-
-    return false;
-}
-
-/*!
-    \since 4.3
-
-    Returns true if the file engine supports \a extension; otherwise, false
-    is returned. By default map, unmap and fast readline extensions are supported.
-
-    \sa extension()
-*/
-bool QAbstractFileEngine::supportsExtension(Extension extension) const
-{
-    Q_D(const QAbstractFileEngine);
-    if (extension == FastReadLineExtension && d->fd != -1 && isSequential())
-        return true;
-    if (extension == UnMapExtension || extension == MapExtension)
-        return true;
-    return false;
-}
-
-/*!
-    Returns the QFile::FileError that resulted from the last failed
-    operation. If QFile::UnspecifiedError is returned, QFile will
-    use its own idea of the error status.
-
-    \sa QFile::FileError, errorString()
- */
-QFile::FileError QAbstractFileEngine::error() const
-{
-    Q_D(const QAbstractFileEngine);
-    return d->fileError;
-}
-
-/*!
-    Returns the human-readable message appropriate to the current error
-    reported by error(). If no suitable string is available, an
-    empty string is returned.
-
-    \sa error()
- */
-QString QAbstractFileEngine::errorString() const
-{
-    Q_D(const QAbstractFileEngine);
-    return d->errorString;
-}
-
-/*!
-    Sets the error type to \a error, and the error string to \a errorString.
-
-    \sa QFile::error(), QIODevice::errorString(), QIODevice::setErrorString()
-*/
-void QAbstractFileEngine::setError(QFile::FileError error, const QString &errorString)
-{
-    Q_D(QAbstractFileEngine);
-    d->fileError = error;
-    d->errorString = errorString;
-}
-
-/*!
-    Opens the file descriptor \a fd in \a openMode mode. Returns true
-    on success; otherwise returns false.
-
-    The \a handleFlags argument specifies whether the file handle will be
-    closed by Katie. See the QFile::FileHandleFlags documentation for more
-    information.
-*/
-bool QAbstractFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandleFlags handleFlags)
-{
-    Q_D(QAbstractFileEngine);
-
-    // Append implies WriteOnly.
-    if (openMode & QFile::Append)
-        openMode |= QFile::WriteOnly;
-
-    // WriteOnly implies Truncate if neither ReadOnly nor Append are sent.
-    if ((openMode & QFile::WriteOnly) && !(openMode & (QFile::ReadOnly | QFile::Append)))
-        openMode |= QFile::Truncate;
-
-    d->openMode = openMode;
-    d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle);
-    d->fileEntry.clear();
-    d->fd = fd;
-    d->metaData.clear();
-
-    // Seek to the end when in Append mode.
-    if (d->openMode & QFile::Append) {
-        if (QT_LSEEK(d->fd, 0, SEEK_END) == -1) {
-            setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
-                     qt_error_string(errno));
-            if (d->closeFileHandle) {
-                qt_safe_close(d->fd);
-            }
-            d->openMode = QIODevice::NotOpen;
-            d->fd = -1;
-            return false;
-        }
-    }
-
-    return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/core/io/qabstractfileengine.h b/src/core/io/qabstractfileengine.h
deleted file mode 100644 (file)
index 4e9ae24..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Copyright (C) 2016 Ivailo Monev
-**
-** This file is part of the QtCore module of the Katie Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-**
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTFILEENGINE_H
-#define QABSTRACTFILEENGINE_H
-
-#include <QtCore/qfile.h>
-#include <QtCore/qdatetime.h>
-
-#ifdef open
-#error qabstractfileengine.h must be included before any header file that defines open
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QAbstractFileEnginePrivate;
-
-class Q_CORE_EXPORT QAbstractFileEngine
-{
-public:
-    enum FileName {
-        DefaultName,
-        BaseName,
-        PathName,
-        AbsoluteName,
-        AbsolutePathName,
-        LinkName,
-        CanonicalName,
-        CanonicalPathName,
-        NFileNames
-    };
-    enum FileOwner {
-        OwnerUser,
-        OwnerGroup
-    };
-    enum FileTime {
-        CreationTime,
-        ModificationTime,
-        AccessTime
-    };
-
-    ~QAbstractFileEngine();
-
-    virtual bool open(QIODevice::OpenMode openMode); // virtual for QTemporaryFile
-    virtual bool close(); // virtual for QTemporaryFile
-    bool flush();
-    qint64 size() const;
-    qint64 pos() const;
-    bool seek(qint64 pos);
-    bool isSequential() const;
-    virtual bool remove(); // virtual for QTemporaryFile
-    bool copy(const QString &newName);
-    virtual bool rename(const QString &newName); // virtual for QTemporaryFile
-    bool link(const QString &newName);
-    bool setSize(qint64 size);
-    bool isRelativePath() const;
-    bool exists() const;
-    QFile::Permissions permissions() const;
-    bool setPermissions(uint perms);
-    QString fileName(FileName file) const;
-    uint ownerId(FileOwner) const;
-    QString owner(FileOwner) const;
-    QDateTime fileTime(FileTime time) const;
-    virtual void setFileName(const QString &file); // virtual for QTemporaryFile
-    int handle() const;
-    uchar *map(qint64 offset, qint64 size);
-    bool unmap(uchar *ptr);
-
-    qint64 read(char *data, qint64 maxlen);
-    qint64 readLine(char *data, qint64 maxlen);
-    qint64 write(const char *data, qint64 len);
-
-    QFile::FileError error() const;
-    QString errorString() const;
-
-    enum Extension {
-        FastReadLineExtension,
-        MapExtension,
-        UnMapExtension
-    };
-    class ExtensionOption
-    {};
-    class ExtensionReturn
-    {};
-
-    class MapExtensionOption : public ExtensionOption {
-    public:
-        qint64 offset;
-        qint64 size;
-    };
-    class MapExtensionReturn : public ExtensionReturn {
-    public:
-        uchar *address;
-    };
-
-    class UnMapExtensionOption : public ExtensionOption {
-    public:
-        uchar *address;
-    };
-
-    bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr);
-    bool supportsExtension(Extension extension) const;
-
-    // Factory
-    static QAbstractFileEngine *create(const QString &fileName);
-
-    //FS only!!
-    bool open(QIODevice::OpenMode flags, int fd, QFile::FileHandleFlags handleFlags);
-
-protected:
-    void setError(QFile::FileError error, const QString &str);
-
-    QAbstractFileEngine();
-    QAbstractFileEngine(QAbstractFileEnginePrivate &);
-
-    QAbstractFileEnginePrivate* d_ptr;
-private:
-    Q_DECLARE_PRIVATE(QAbstractFileEngine)
-    Q_DISABLE_COPY(QAbstractFileEngine)
-
-    friend class QFilePrivate;
-};
-
-QT_END_NAMESPACE
-
-#endif // QABSTRACTFILEENGINE_H
diff --git a/src/core/io/qabstractfileengine_p.h b/src/core/io/qabstractfileengine_p.h
deleted file mode 100644 (file)
index c8d5c5f..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Copyright (C) 2016 Ivailo Monev
-**
-** This file is part of the QtCore module of the Katie Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-**
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTFILEENGINE_P_H
-#define QABSTRACTFILEENGINE_P_H
-
-//
-//  W A R N I N G
-//  -------------
-//
-// This file is not part of the Katie API.  It exists purely as an
-// implementation detail.  This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtCore/qabstractfileengine.h"
-#include "qfilesystementry_p.h"
-#include "qfilesystemmetadata_p.h"
-#include "qhash.h"
-
-QT_BEGIN_NAMESPACE
-
-class QAbstractFileEnginePrivate
-{
-public:
-    QAbstractFileEnginePrivate();
-
-    QFile::FileError fileError;
-    QString errorString;
-
-    QFileSystemEntry fileEntry;
-    QIODevice::OpenMode openMode;
-
-    uchar *map(qint64 offset, qint64 size);
-    bool unmap(uchar *ptr);
-
-    mutable QFileSystemMetaData metaData;
-
-    QHash<uchar *, QPair<int /*offset % PageSize*/, size_t /*length + offset % PageSize*/> > maps;
-    int fd;
-
-    bool closeFileHandle;
-
-    bool doStat(QFileSystemMetaData::MetaDataFlags flags) const;
-
-    QAbstractFileEngine *q_ptr;
-    Q_DECLARE_PUBLIC(QAbstractFileEngine)
-};
-
-QT_END_NAMESPACE
-
-#endif // QABSTRACTFILEENGINE_P_H
index 0387da1..9d92c18 100644 (file)
 #include "qfileinfo.h"
 #include "qiodevice_p.h"
 #include "qfile_p.h"
+#include "qfilesystemengine_p.h"
 #include "qcorecommon_p.h"
+#include "qcore_unix_p.h"
 
 #ifdef QT_NO_QOBJECT
 #define tr(X) QString::fromLatin1(X)
 #endif
 
+#include <sys/mman.h>
+
 QT_BEGIN_NAMESPACE
 
 //************* QFilePrivate
 QFilePrivate::QFilePrivate()
-    : fileEngine(0),
-      error(QFile::NoError)
+    : error(QFile::NoError),
+    fd(-1),
+    closeFileHandle(false)
 {
 }
 
 QFilePrivate::~QFilePrivate()
 {
-    delete fileEngine;
-    fileEngine = 0;
 }
 
-bool
-QFilePrivate::openExternalFile(int flags, int fd, QFile::FileHandleFlags handleFlags)
+bool QFilePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const
 {
-    delete fileEngine;
-    fileEngine = 0;
-    fileEngine = new QAbstractFileEngine();
-    return fileEngine->open(QIODevice::OpenMode(flags), fd, handleFlags);
+    if (!metaData.hasFlags(flags)) {
+        if (!fileEntry.isEmpty())
+            QFileSystemEngine::fillMetaData(fileEntry, metaData, metaData.missingFlags(flags));
+
+        if (metaData.missingFlags(flags) && fd != -1)
+            QFileSystemEngine::fillMetaData(fd, metaData);
+    }
+
+    return metaData.exists();
 }
 
-void
-QFilePrivate::setError(QFile::FileError err)
+bool QFilePrivate::unmap(uchar *ptr)
 {
-    error = err;
-    errorString.clear();
+    if (!maps.contains(ptr)) {
+        setError(QFile::PermissionsError, qt_error_string(EACCES));
+        return false;
+    }
+
+    uchar *start = ptr - maps[ptr].first;
+    size_t len = maps[ptr].second;
+    if (::munmap(start, len) == -1) {
+        setError(QFile::UnspecifiedError, qt_error_string(errno));
+        return false;
+    }
+    maps.remove(ptr);
+    return true;
+}
+
+bool QFilePrivate::openExternalFile(QIODevice::OpenMode mode, int _fd, QFile::FileHandleFlags handleFlags)
+{
+    // Append implies WriteOnly.
+    if (mode & QFile::Append)
+        mode |= QFile::WriteOnly;
+
+    // WriteOnly implies Truncate if neither ReadOnly nor Append are sent.
+    if ((mode & QFile::WriteOnly) && !(mode & (QFile::ReadOnly | QFile::Append)))
+        mode |= QFile::Truncate;
+
+    closeFileHandle = (handleFlags & QFile::AutoCloseHandle);
+    fileEntry.clear();
+    fd = _fd;
+    metaData.clear();
+
+    // Seek to the end when in Append mode.
+    if (mode & QFile::Append) {
+        if (QT_LSEEK(fd, 0, SEEK_END) == -1) {
+            setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
+                     qt_error_string(errno));
+            if (closeFileHandle) {
+                qt_safe_close(fd);
+            }
+            fd = -1;
+            return false;
+        }
+    }
+
+    return true;
 }
 
-void
-QFilePrivate::setError(QFile::FileError err, const QString &errStr)
+void QFilePrivate::setError(QFile::FileError err, const QString &errStr)
 {
     error = err;
     errorString = errStr;
@@ -269,7 +316,7 @@ QFile::QFile()
 QFile::QFile(const QString &name)
     : QIODevice(*new QFilePrivate)
 {
-    d_func()->fileName = name;
+    d_func()->fileEntry = QFileSystemEntry(name);
 }
 QFile::QFile(QFilePrivate &dd)
     : QIODevice(dd)
@@ -297,7 +344,7 @@ QFile::QFile(const QString &name)
     : QIODevice(*new QFilePrivate, 0)
 {
     Q_D(QFile);
-    d->fileName = name;
+    d->fileEntry = QFileSystemEntry(name);
 }
 /*!
     Constructs a new file object with the given \a parent to represent the
@@ -307,7 +354,7 @@ QFile::QFile(const QString &name, QObject *parent)
     : QIODevice(*new QFilePrivate, parent)
 {
     Q_D(QFile);
-    d->fileName = name;
+    d->fileEntry = QFileSystemEntry(name);
 }
 /*!
     \internal
@@ -334,7 +381,8 @@ QFile::~QFile()
 */
 QString QFile::fileName() const
 {
-    return fileEngine()->fileName(QAbstractFileEngine::DefaultName);
+    Q_D(const QFile);
+    return d->fileEntry.filePath();
 }
 
 /*!
@@ -355,20 +403,15 @@ QString QFile::fileName() const
 
     \sa fileName(), QFileInfo, QDir
 */
-void
-QFile::setFileName(const QString &name)
+void QFile::setFileName(const QString &name)
 {
     Q_D(QFile);
     if (Q_UNLIKELY(isOpen())) {
         qWarning("QFile::setFileName: File (%s) is already opened",
                  qPrintable(fileName()));
-        close();
-    }
-    if(d->fileEngine) { //get a new file engine later
-        delete d->fileEngine;
-        d->fileEngine = 0;
     }
-    d->fileName = name;
+    close();
+    d->fileEntry = QFileSystemEntry(name);
 }
 
 /*!
@@ -400,8 +443,7 @@ QByteArray QFile::encodeName(const QString &fileName)
     \sa setDecodingFunction(), encodeName()
 */
 
-QString
-QFile::decodeName(const QByteArray &localFileName)
+QString QFile::decodeName(const QByteArray &localFileName)
 {
     return QString::fromLocal8Bit(localFileName.constData());
 }
@@ -415,10 +457,13 @@ QFile::decodeName(const QByteArray &localFileName)
     \sa fileName(), setFileName()
 */
 
-bool
-QFile::exists() const
+bool QFile::exists() const
 {
-    return fileEngine()->exists();
+    Q_D(const QFile);
+    d->metaData.clear(); // always stat
+    if (!d->doStat(QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::FileType))
+        return false;
+    return d->metaData.exists() && d->metaData.isFile();
 }
 
 /*!
@@ -426,8 +471,7 @@ QFile::exists() const
     returns false.
 */
 
-bool
-QFile::exists(const QString &fileName)
+bool QFile::exists(const QString &fileName)
 {
     QFileInfo info(fileName);
     return (info.exists() && info.isFile());
@@ -448,10 +492,16 @@ QFile::exists(const QString &fileName)
     \sa fileName() setFileName()
 */
 
-QString
-QFile::readLink() const
+QString QFile::readLink() const
 {
-    return fileEngine()->fileName(QAbstractFileEngine::LinkName);
+    Q_D(const QFile);
+    if (!d->metaData.hasFlags(QFileSystemMetaData::LinkType))
+        QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::LinkType);
+    if (d->metaData.isLink()) {
+        QFileSystemEntry entry = QFileSystemEngine::getLinkTarget(d->fileEntry, d->metaData);
+        return entry.filePath();
+    }
+    return QString();
 }
 
 /*!
@@ -466,8 +516,7 @@ QFile::readLink() const
     QFile::exists() returns true if the symlink points to an existing file.
 */
 
-QString
-QFile::readLink(const QString &fileName)
+QString QFile::readLink(const QString &fileName)
 {
     return QFileInfo(fileName).readLink();
 }
@@ -481,22 +530,25 @@ QFile::readLink(const QString &fileName)
     \sa setFileName()
 */
 
-bool
-QFile::remove()
+bool QFile::remove()
 {
     Q_D(QFile);
-    if (Q_UNLIKELY(d->fileName.isEmpty())) {
+    if (Q_UNLIKELY(d->fileEntry.isEmpty())) {
         qWarning("QFile::remove: Empty or null file name");
         return false;
     }
     unsetError();
     close();
     if(error() == QFile::NoError) {
-        if(fileEngine()->remove()) {
-            unsetError();
-            return true;
+        int error = 0;
+        bool ret = QFileSystemEngine::removeFile(d->fileEntry, &error);
+        d->metaData.clear();
+        if (!ret) {
+            d->setError(QFile::RemoveError, qt_error_string(error));
+            return false;
         }
-        d->setError(QFile::RemoveError, d->fileEngine->errorString());
+        unsetError();
+        return true;
     }
     return false;
 }
@@ -533,7 +585,7 @@ bool
 QFile::rename(const QString &newName)
 {
     Q_D(QFile);
-    if (Q_UNLIKELY(d->fileName.isEmpty())) {
+    if (Q_UNLIKELY(d->fileEntry.isEmpty())) {
         qWarning("QFile::rename: Empty or null file name");
         return false;
     }
@@ -549,14 +601,21 @@ QFile::rename(const QString &newName)
     unsetError();
     close();
     if(error() == QFile::NoError) {
-        if (fileEngine()->rename(newName)) {
-            unsetError();
-            // engine was able to handle the new name so we just reset it
-            d->fileEngine->setFileName(newName);
-            d->fileName = newName;
-            return true;
+        int error = 0;
+        bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), &error);
+        d->metaData.clear();
+        if (!ret) {
+            d->setError(QFile::RenameError, qt_error_string(error));
+            return false;
         }
-        d->setError(QFile::RenameError, d->fileEngine->errorString());
+
+        unsetError();
+        // just reset it
+        d->metaData.clear();
+        d->fd = -1;
+        d->closeFileHandle = false;
+        d->fileEntry = QFileSystemEntry(newName);
+        return true;
     }
     return false;
 }
@@ -597,21 +656,22 @@ QFile::rename(const QString &oldName, const QString &newName)
     \sa setFileName()
 */
 
-bool
-QFile::link(const QString &linkName)
+bool QFile::link(const QString &linkName)
 {
     Q_D(QFile);
-    if (Q_UNLIKELY(d->fileName.isEmpty())) {
+    if (Q_UNLIKELY(d->fileEntry.isEmpty())) {
         qWarning("QFile::link: Empty or null file name");
         return false;
     }
     QFileInfo fi(linkName);
-    if(fileEngine()->link(fi.absoluteFilePath())) {
-        unsetError();
-        return true;
+    int error = 0;
+    bool ret = QFileSystemEngine::createLink(d->fileEntry, QFileSystemEntry(fi.absoluteFilePath()), &error);
+    if (!ret) {
+        d->setError(QFile::RenameError, qt_error_string(error));
+        return false;
     }
-    d->setError(QFile::RenameError, d->fileEngine->errorString());
-    return false;
+    unsetError();
+    return true;
 }
 
 /*!
@@ -647,7 +707,7 @@ bool
 QFile::copy(const QString &newName)
 {
     Q_D(QFile);
-    if (Q_UNLIKELY(d->fileName.isEmpty())) {
+    if (Q_UNLIKELY(d->fileEntry.isEmpty())) {
         qWarning("QFile::copy: Empty or null file name");
         return false;
     }
@@ -655,11 +715,12 @@ QFile::copy(const QString &newName)
     unsetError();
     close();
     if(error() == QFile::NoError) {
-        if(fileEngine()->copy(newName)) {
+        int error = 0;
+        if(QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(newName), &error)) {
             unsetError();
             return true;
         }
-        d->setError(QFile::CopyError, d->fileEngine->errorString());
+        d->setError(QFile::CopyError, qt_error_string(error));
     }
     return false;
 }
@@ -693,7 +754,9 @@ QFile::copy(const QString &fileName, const QString &newName)
 bool QFile::isSequential() const
 {
     Q_D(const QFile);
-    return d->fileEngine && d->fileEngine->isSequential();
+    if (d->doStat(QFileSystemMetaData::SequentialType))
+        return d->metaData.isSequential();
+    return true;
 }
 
 /*!
@@ -722,19 +785,86 @@ bool QFile::open(OpenMode mode)
 
     unsetError();
     if (Q_UNLIKELY((mode & (ReadOnly | WriteOnly)) == 0)) {
-        qWarning("QIODevice::open: File access not specified");
+        qWarning("QFile::open: File access not specified");
         return false;
     }
 
-    if (fileEngine()->open(mode)) {
-        QIODevice::open(mode);
-        return true;
+    if (Q_UNLIKELY(d->fileEntry.isEmpty())) {
+        qWarning("QFile::open: No file name specified");
+        d->setError(QFile::OpenError, QLatin1String("No file name specified"));
+        return false;
     }
-    QFile::FileError err = d->fileEngine->error();
-    if(err == QFile::UnspecifiedError)
-        err = QFile::OpenError;
-    d->setError(err, d->fileEngine->errorString());
-    return false;
+
+    // Append implies WriteOnly.
+    if (mode & QFile::Append)
+        mode |= QFile::WriteOnly;
+
+    // WriteOnly implies Truncate if neither ReadOnly nor Append are sent.
+    if ((mode & QFile::WriteOnly) && !(mode & (QFile::ReadOnly | QFile::Append)))
+        mode |= QFile::Truncate;
+
+    d->metaData.clear();
+    d->fd = -1;
+
+    int flags = QT_OPEN_RDONLY;
+
+    if ((mode & QFile::ReadWrite) == QFile::ReadWrite) {
+        flags = QT_OPEN_RDWR | QT_OPEN_CREAT;
+    } else if (mode & QFile::WriteOnly) {
+        flags = QT_OPEN_WRONLY | QT_OPEN_CREAT;
+    }
+
+    if (mode & QFile::Append) {
+        flags |= QT_OPEN_APPEND;
+    } else if (mode & QFile::WriteOnly) {
+        if ((mode & QFile::Truncate) || !(mode & QFile::ReadOnly))
+            flags |= QT_OPEN_TRUNC;
+    }
+
+    if (mode & QFile::Unbuffered) {
+#ifdef O_DSYNC
+        flags |= O_DSYNC;
+#else
+        flags |= O_SYNC;
+#endif
+    }
+
+    // Try to open the file.
+    const QByteArray native = d->fileEntry.nativeFilePath();
+    d->fd = qt_safe_open(native.constData(), flags, 0666);
+
+    // On failure, return and report the error.
+    if (d->fd == -1) {
+        d->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
+                    qt_error_string(errno));
+        return false;
+    }
+
+    // Refuse to open directories, EISDIR is not a thing (by standards) for
+    // non-write modes.
+    QT_STATBUF statbuf;
+    if (QT_FSTAT(d->fd, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
+        qt_safe_close(d->fd);
+        d->fd = -1;
+        d->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
+        return false;
+    }
+
+    // Seek to the end when in Append mode.
+    if (mode & QFile::Append) {
+        if (QT_LSEEK(d->fd, 0, SEEK_END) == -1) {
+            qt_safe_close(d->fd);
+            d->fd = -1;
+            d->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
+                        qt_error_string(errno));
+            return false;
+        }
+    }
+
+    d->closeFileHandle = true;
+
+    QIODevice::open(mode);
+    return true;
 }
 
 /*! \fn QFile::open(OpenMode, FILE*)
@@ -888,10 +1018,10 @@ bool QFile::open(int fd, OpenMode mode, FileHandleFlags handleFlags)
 int QFile::handle() const
 {
     Q_D(const QFile);
-    if (!isOpen() || !d->fileEngine)
+    if (!isOpen())
         return -1;
 
-    return d->fileEngine->handle();
+    return d->fd;
 }
 
 /*!
@@ -904,19 +1034,67 @@ int QFile::handle() const
 
     Returns a pointer to the memory or 0 if there is an error.
 
-    \sa unmap(), QAbstractFileEngine::supportsExtension()
+    \sa unmap()
  */
 uchar *QFile::map(qint64 offset, qint64 size)
 {
     Q_D(QFile);
-    if (fileEngine()
-            && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
-        unsetError();
-        uchar *address = d->fileEngine->map(offset, size);
-        if (address == 0)
-            d->setError(d->fileEngine->error(), d->fileEngine->errorString());
+    unsetError();
+    if (openMode() == QIODevice::NotOpen) {
+        d->setError(QFile::PermissionsError, qt_error_string(EACCES));
+        return 0;
+    }
+
+    if (offset < 0 || offset != qint64(QT_OFF_T(offset))
+            || size < 0 || quint64(size) > quint64(size_t(-1))) {
+        d->setError(QFile::UnspecifiedError, qt_error_string(EINVAL));
+        return 0;
+    }
+
+    // If we know the mapping will extend beyond EOF, fail early to avoid
+    // undefined behavior. Otherwise, let mmap have its say.
+    if (d->doStat(QFileSystemMetaData::SizeAttribute)
+            && (QT_OFF_T(size) > d->metaData.size() - QT_OFF_T(offset)))
+        qWarning("QFile::map: Mapping a file beyond its size is not portable");
+
+    int access = 0;
+    if (openMode() & QIODevice::ReadOnly) access |= PROT_READ;
+    if (openMode() & QIODevice::WriteOnly) access |= PROT_WRITE;
+
+    static const int pageSize = ::getpagesize();
+    const int extra = offset % pageSize;
+
+    if (quint64(size + extra) > quint64((size_t)-1)) {
+        d->setError(QFile::UnspecifiedError, qt_error_string(EINVAL));
+        return 0;
+    }
+
+    size_t realSize = (size_t)size + extra;
+    QT_OFF_T realOffset = QT_OFF_T(offset);
+    realOffset &= ~(QT_OFF_T(pageSize - 1));
+
+    void *mapAddress = QT_MMAP(nullptr, realSize,
+                   access, MAP_SHARED, d->fd, realOffset);
+    if (mapAddress != MAP_FAILED) {
+        uchar *address = extra + static_cast<uchar*>(mapAddress);
+        d->maps[address] = QPair<int,size_t>(extra, realSize);
         return address;
     }
+
+    switch(errno) {
+    case EBADF:
+        d->setError(QFile::PermissionsError, qt_error_string(EACCES));
+        break;
+    case ENFILE:
+    case ENOMEM:
+        d->setError(QFile::ResourceError, qt_error_string(errno));
+        break;
+    case EINVAL:
+        // size are out of bounds
+    default:
+        d->setError(QFile::UnspecifiedError, qt_error_string(errno));
+        break;
+    }
     return 0;
 }
 
@@ -926,21 +1104,13 @@ uchar *QFile::map(qint64 offset, qint64 size)
 
     Returns true if the unmap succeeds; false otherwise.
 
-    \sa map(), QAbstractFileEngine::supportsExtension()
+    \sa map()
  */
 bool QFile::unmap(uchar *address)
 {
     Q_D(QFile);
-    if (fileEngine()
-        && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
-        unsetError();
-        const bool success = d->fileEngine->unmap(address);
-        if (!success)
-            d->setError(d->fileEngine->error(), d->fileEngine->errorString());
-        return success;
-    }
-    d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension"));
-    return false;
+    unsetError();
+    return d->unmap(address);
 }
 
 /*!
@@ -967,15 +1137,22 @@ bool QFile::unmap(uchar *address)
 bool QFile::resize(qint64 sz)
 {
     Q_D(QFile);
-    fileEngine();
-    if (isOpen() && d->fileEngine->pos() > sz)
+    if (isOpen() && QT_LSEEK(d->fd, 0, SEEK_CUR) > sz) {
         seek(sz);
-    if(d->fileEngine->setSize(sz)) {
-        unsetError();
-        return true;
     }
-    d->setError(QFile::ResizeError, d->fileEngine->errorString());
-    return false;
+    int ret = 0;
+    if (d->fd != -1) {
+        Q_EINTR_LOOP(ret, QT_FTRUNCATE(d->fd, sz));
+    } else {
+        Q_EINTR_LOOP(ret, QT_TRUNCATE(d->fileEntry.nativeFilePath().constData(), sz));
+    }
+    d->metaData.clearFlags(QFileSystemMetaData::SizeAttribute);
+    if (ret == -1) {
+        d->setError(QFile::ResizeError, qt_error_string(errno));
+        return false;
+    }
+    unsetError();
+    return true;
 }
 
 /*!
@@ -1003,7 +1180,11 @@ bool QFile::resize(const QString &fileName, qint64 sz)
 
 QFile::Permissions QFile::permissions() const
 {
-    return fileEngine()->permissions();
+    Q_D(const QFile);
+    bool exists = d->doStat(QFileSystemMetaData::Permissions | QFileSystemMetaData::LinkType);
+    if (!exists && !d->metaData.isLink())
+        return 0;
+    return d->metaData.permissions();
 }
 
 /*!
@@ -1029,12 +1210,13 @@ QFile::Permissions QFile::permissions(const QString &fileName)
 bool QFile::setPermissions(Permissions permissions)
 {
     Q_D(QFile);
-    if(fileEngine()->setPermissions(permissions)) {
-        unsetError();
-        return true;
+    int error = 0;
+    if (!QFileSystemEngine::setPermissions(d->fileEntry, QFile::Permissions(permissions), &error)) {
+        d->setError(QFile::PermissionsError, qt_error_string(error));
+        return false;
     }
-    d->setError(QFile::PermissionsError, d->fileEngine->errorString());
-    return false;
+    unsetError();
+    return true;
 }
 
 /*!
@@ -1056,25 +1238,17 @@ bool QFile::setPermissions(const QString &fileName, Permissions permissions)
 bool QFile::flush()
 {
     Q_D(QFile);
-    if (Q_UNLIKELY(!d->fileEngine)) {
-        qWarning("QFile::flush: No file engine. Is IODevice open?");
-        return false;
-    }
-
-    if (!d->fileEngine->flush()) {
-        QFile::FileError err = d->fileEngine->error();
-        if(err == QFile::UnspecifiedError)
-            err = QFile::WriteError;
-        d->setError(err, d->fileEngine->errorString());
+    if (d->fd == -1) {
+        d->setError(QFile::WriteError, QString());
         return false;
     }
     return true;
 }
 
 /*!
-  Calls QFile::flush() and closes the file. Errors from flush are ignored.
+    Calls QFile::flush() and closes the file. Errors from flush are ignored.
 
-  \sa QIODevice::close()
+    \sa QIODevice::close()
 */
 void QFile::close()
 {
@@ -1084,34 +1258,62 @@ void QFile::close()
     const bool flushed = flush();
     QIODevice::close();
 
-    // keep earlier error from flush
-    if (d->fileEngine->close() && flushed)
+    if (d->fd == -1) {
+        d->setError(QFile::UnspecifiedError, QString());
+        return;
+    }
+
+    d->metaData.clear();
+
+    // Close the file if we created the handle.
+    int ret = 0;
+    if (d->closeFileHandle) {
+        ret = qt_safe_close(d->fd);
+    }
+
+    // We must reset these guys regardless; calling close again after a
+    // failed close causes crashes on some systems.
+    d->fd = -1;
+    QList<uchar*> keys = d->maps.keys();
+    for (int i = 0; i < keys.count(); ++i) {
+        d->unmap(keys.at(i));
+    }
+
+    // Report errors.
+    if (ret != 0) {
+        d->setError(QFile::UnspecifiedError, qt_error_string(errno));
+        return;
+    }
+
+    if (flushed) {
         unsetError();
-    else if (flushed)
-        d->setError(d->fileEngine->error(), d->fileEngine->errorString());
+    }
 }
 
 /*!
-  Returns the size of the file.
+    Returns the size of the file.
 
-  For regular empty files on Unix (e.g. those in \c /proc), this function
-  returns 0; the contents of such a file are generated on demand in response
-  to you calling read().
+    For regular empty files on Unix (e.g. those in \c /proc), this function
+    returns 0; the contents of such a file are generated on demand in response
+    to you calling read().
 */
-
 qint64 QFile::size() const
 {
-    return fileEngine()->size();
+    Q_D(const QFile);
+    d->metaData.clear();
+    if (!d->doStat(QFileSystemMetaData::SizeAttribute))
+        return 0;
+    return d->metaData.size();
 }
 
 /*!
-  Returns true if the end of the file has been reached; otherwise returns
-  false.
+    Returns true if the end of the file has been reached; otherwise returns
+    false.
 
-  For regular empty files on Unix (e.g. those in \c /proc), this function
-  returns true, since the file system reports that the size of such a file is
-  0. Therefore, you should not depend on atEnd() when reading data from such a
-  file, but rather call read() until no more data can be read.
+    For regular empty files on Unix (e.g. those in \c /proc), this function
+    returns true, since the file system reports that the size of such a file is
+    0. Therefore, you should not depend on atEnd() when reading data from such a
+    file, but rather call read() until no more data can be read.
 */
 
 bool QFile::atEnd() const
@@ -1147,14 +1349,22 @@ bool QFile::seek(qint64 off)
         return false;
     }
 
-    if (off == d->pos && off == d->devicePos)
+    if (off == d->pos && off == d->devicePos) {
         return true; // avoid expensive flush for NOP seek to current position
+    }
+
+    if (off < 0 || off != qint64(QT_OFF_T(off))) {
+        d->setError(QFile::PositionError, QString());
+        return false;
+    }
 
-    if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
-        QFile::FileError err = d->fileEngine->error();
-        if(err == QFile::UnspecifiedError)
-            err = QFile::PositionError;
-        d->setError(err, d->fileEngine->errorString());
+    if (Q_UNLIKELY(QT_LSEEK(d->fd, QT_OFF_T(off), SEEK_SET) == -1)) {
+        qWarning("QFile::seek: Cannot set file position %lld", off);
+        d->setError(QFile::PositionError, qt_error_string(errno));
+        return false;
+    }
+    if (!QIODevice::seek(off)) {
+        d->setError(QFile::PositionError, QString());
         return false;
     }
     unsetError();
@@ -1167,8 +1377,19 @@ bool QFile::seek(qint64 off)
 qint64 QFile::readLineData(char *data, qint64 maxlen)
 {
     Q_D(QFile);
-    if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
-        return d->fileEngine->readLine(data, maxlen);
+    if (d->fd != -1 && isSequential()) {
+        qint64 readSoFar = 0;
+        while (readSoFar < maxlen) {
+            char c;
+            qint64 readResult = readData(&c, 1);
+            if (readResult <= 0)
+                return (readSoFar > 0) ? readSoFar : -1;
+            ++readSoFar;
+            *data++ = c;
+            if (c == '\n')
+                return readSoFar;
+        }
+        return readSoFar;
     }
     // Fall back to QIODevice's readLine implementation if the engine
     // cannot do it faster.
@@ -1183,15 +1404,30 @@ qint64 QFile::readData(char *data, qint64 len)
     Q_D(QFile);
     unsetError();
 
-    qint64 read = d->fileEngine->read(data, len);
-    if(read < 0) {
-        QFile::FileError err = d->fileEngine->error();
-        if(err == QFile::UnspecifiedError)
-            err = QFile::ReadError;
-        d->setError(err, d->fileEngine->errorString());
+    if (len < 0) {
+        d->setError(QFile::ReadError, qt_error_string(EINVAL));
+        return -1;
+    }
+
+    qint64 readBytes = 0;
+    bool eof = false;
+
+    if (d->fd != -1) {
+        ssize_t result;
+        do {
+            result = QT_READ(d->fd, data + readBytes, size_t(len - readBytes));
+        } while ((result == -1 && errno == EINTR)
+                || (result > 0 && (readBytes += result) < len));
+
+        eof = !(result == -1);
+    }
+
+    if (!eof && readBytes == 0) {
+        readBytes = -1;
+        d->setError(QFile::ReadError, qt_error_string(errno));
     }
 
-    return read;
+    return readBytes;
 }
 
 /*!
@@ -1202,26 +1438,29 @@ qint64 QFile::writeData(const char *data, qint64 len)
     Q_D(QFile);
     unsetError();
 
-    qint64 ret = d->fileEngine->write(data, len);
-    if(ret < 0) {
-        QFile::FileError err = d->fileEngine->error();
-        if(err == QFile::UnspecifiedError)
-            err = QFile::WriteError;
-        d->setError(err, d->fileEngine->errorString());
+    if (len < 0 || len != qint64(size_t(len))) {
+        d->setError(QFile::WriteError, qt_error_string(EINVAL));
+        return -1;
     }
-    return ret;
-}
 
-/*!
-    \internal
-    Returns the QIOEngine for this QFile object.
-*/
-QAbstractFileEngine *QFile::fileEngine() const
-{
-    Q_D(const QFile);
-    if(!d->fileEngine)
-        d->fileEngine = QAbstractFileEngine::create(d->fileName);
-    return d->fileEngine;
+    qint64 writtenBytes = 0;
+
+    if (d->fd != -1) {
+        ssize_t result;
+        do {
+            result = QT_WRITE(d->fd, data + writtenBytes, size_t(len - writtenBytes));
+        } while ((result == -1 && errno == EINTR)
+                || (result > 0 && (writtenBytes += result) < len));
+    }
+
+    if (len && writtenBytes == 0) {
+        writtenBytes = -1;
+        d->setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError, qt_error_string(errno));
+    }
+
+    d->metaData.clearFlags(QFileSystemMetaData::SizeAttribute);
+
+    return writtenBytes;
 }
 
 /*!
@@ -1262,7 +1501,7 @@ QString QFile::errorString() const
 void QFile::unsetError()
 {
     Q_D(QFile);
-    d->setError(QFile::NoError);
+    d->setError(QFile::NoError, QString());
 }
 
 #ifndef QT_NO_QOBJECT
index 7764abc..c4ecf21 100644 (file)
@@ -33,8 +33,6 @@
 
 QT_BEGIN_NAMESPACE
 
-
-class QAbstractFileEngine;
 class QFilePrivate;
 
 class Q_CORE_EXPORT QFile : public QIODevice
@@ -141,9 +139,6 @@ public:
     uchar *map(qint64 offset, qint64 size);
     bool unmap(uchar *address);
 
-    virtual QAbstractFileEngine *fileEngine() const;
-
-
 protected:
 #ifdef QT_NO_QOBJECT
     QFile(QFilePrivate &dd);
index 3e332f4..604d4b3 100644 (file)
@@ -33,8 +33,9 @@
 // We mean it.
 //
 
-#include "qabstractfileengine.h"
 #include "qiodevice_p.h"
+#include "qfilesystementry_p.h"
+#include "qfilesystemmetadata_p.h"
 
 QT_BEGIN_NAMESPACE
 
@@ -46,13 +47,18 @@ protected:
     QFilePrivate();
     ~QFilePrivate();
 
-    bool openExternalFile(int flags, int fd, QFile::FileHandleFlags handleFlags);
-
-    QString fileName;
-    mutable QAbstractFileEngine *fileEngine;
+    bool openExternalFile(QIODevice::OpenMode mode, int fd, QFile::FileHandleFlags handleFlags);
+    bool doStat(QFileSystemMetaData::MetaDataFlags flags) const;
+    bool unmap(uchar *ptr);
 
     QFile::FileError error;
-    void setError(QFile::FileError err);
+    QString errorString;
+    QFileSystemEntry fileEntry;
+    mutable QFileSystemMetaData metaData;
+    QHash<uchar *, QPair<int /*offset % PageSize*/, size_t /*length + offset % PageSize*/> > maps;
+    int fd;
+    bool closeFileHandle;
+
     void setError(QFile::FileError err, const QString &errorString);
 };
 
index 31fe1ff..1972b03 100644 (file)
 
 QT_BEGIN_NAMESPACE
 
-QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const
+QString QFileInfoPrivate::getFileName(const QFileInfoPrivate::FileName name) const
 {
     if (cache_enabled && !fileNames[(int)name].isNull())
         return fileNames[(int)name];
 
     QString ret;
     switch (name) {
-        case QAbstractFileEngine::CanonicalName:
-        case QAbstractFileEngine::CanonicalPathName: {
+        case FileName::CanonicalName:
+        case FileName::CanonicalPathName: {
             QFileSystemEntry entry = QFileSystemEngine::canonicalName(fileEntry, metaData);
             if (cache_enabled) { // be smart and store both
-                fileNames[QAbstractFileEngine::CanonicalName] = entry.filePath();
-                fileNames[QAbstractFileEngine::CanonicalPathName] = entry.path();
+                fileNames[FileName::CanonicalName] = entry.filePath();
+                fileNames[FileName::CanonicalPathName] = entry.path();
             }
-            if (name == QAbstractFileEngine::CanonicalName)
+            if (name == FileName::CanonicalName)
                 ret = entry.filePath();
             else
                 ret = entry.path();
             break;
         }
-        case QAbstractFileEngine::LinkName:
+        case FileName::LinkName:
             ret = QFileSystemEngine::getLinkTarget(fileEntry, metaData).filePath();
             break;
-        case QAbstractFileEngine::AbsoluteName:
-        case QAbstractFileEngine::AbsolutePathName: {
+        case FileName::AbsoluteName:
+        case FileName::AbsolutePathName: {
             QFileSystemEntry entry = QFileSystemEngine::absoluteName(fileEntry);
             if (cache_enabled) { // be smart and store both
-                fileNames[QAbstractFileEngine::AbsoluteName] = entry.filePath();
-                fileNames[QAbstractFileEngine::AbsolutePathName] = entry.path();
+                fileNames[FileName::AbsoluteName] = entry.filePath();
+                fileNames[FileName::AbsolutePathName] = entry.path();
             }
-            if (name == QAbstractFileEngine::AbsoluteName)
+            if (name == FileName::AbsoluteName)
                 ret = entry.filePath();
             else
                 ret = entry.path();
@@ -359,7 +359,7 @@ QString QFileInfo::absoluteFilePath() const
     Q_D(const QFileInfo);
     if (d->isDefaultConstructed)
         return QLatin1String("");
-    return d->getFileName(QAbstractFileEngine::AbsoluteName);
+    return d->getFileName(QFileInfoPrivate::AbsoluteName);
 }
 
 /*!
@@ -376,7 +376,7 @@ QString QFileInfo::canonicalFilePath() const
     Q_D(const QFileInfo);
     if (d->isDefaultConstructed)
         return QLatin1String("");
-    return d->getFileName(QAbstractFileEngine::CanonicalName);
+    return d->getFileName(QFileInfoPrivate::CanonicalName);
 }
 
 
@@ -405,7 +405,7 @@ QString QFileInfo::absolutePath() const
         qWarning("QFileInfo::absolutePath: Constructed with empty filename");
         return QLatin1String("");
     }
-    return d->getFileName(QAbstractFileEngine::AbsolutePathName);
+    return d->getFileName(QFileInfoPrivate::AbsolutePathName);
 }
 
 /*!
@@ -421,7 +421,7 @@ QString QFileInfo::canonicalPath() const
     Q_D(const QFileInfo);
     if (d->isDefaultConstructed)
         return QLatin1String("");
-    return d->getFileName(QAbstractFileEngine::CanonicalPathName);
+    return d->getFileName(QFileInfoPrivate::CanonicalPathName);
 }
 
 /*!
@@ -827,7 +827,7 @@ QString QFileInfo::readLink() const
     Q_D(const QFileInfo);
     if (d->isDefaultConstructed)
         return QLatin1String("");
-    return d->getFileName(QAbstractFileEngine::LinkName);
+    return d->getFileName(QFileInfoPrivate::LinkName);
 }
 
 /*!
index bceec11..6b0492c 100644 (file)
@@ -43,6 +43,18 @@ QT_BEGIN_NAMESPACE
 class QFileInfoPrivate : public QSharedData
 {
 public:
+    enum FileName {
+        DefaultName,
+        BaseName,
+        PathName,
+        AbsoluteName,
+        AbsolutePathName,
+        LinkName,
+        CanonicalName,
+        CanonicalPathName,
+        NFileNames
+    };
+
     inline QFileInfoPrivate()
         : QSharedData(),
         isDefaultConstructed(true),
@@ -74,16 +86,16 @@ public:
 
     inline void clear() const {
         metaData.clear();
-        for (int i = 0; i < QAbstractFileEngine::NFileNames; i++)
+        for (int i = 0; i < FileName::NFileNames; i++)
             fileNames[i].clear();
     }
 
-    QString getFileName(QAbstractFileEngine::FileName) const;
+    QString getFileName(const FileName name) const;
 
     QFileSystemEntry fileEntry;
     mutable QFileSystemMetaData metaData;
 
-    mutable QString fileNames[QAbstractFileEngine::NFileNames];
+    mutable QString fileNames[FileName::NFileNames];
 
     bool const isDefaultConstructed; // QFileInfo is a default constructed instance
     bool cache_enabled;
index f2c9e4a..dbb5c00 100644 (file)
@@ -501,7 +501,7 @@ QFileSystemEntry QFileSystemEngine::currentPath()
 
 #ifndef QT_NO_DEBUG
     if (result.isEmpty())
-        qWarning("QAbstractFileEngine::currentPath: " GETCWDFUNCNAME "() failed");
+        qWarning("QFileSystemEngine::currentPath: " GETCWDFUNCNAME "() failed");
 #endif
 #undef GETCWDFUNCNAME
 
index e8416b1..b13d859 100644 (file)
@@ -34,9 +34,9 @@
 //
 
 #include "qplatformdefs.h"
-#include <QtCore/qdatetime.h>
-#include <QtCore/qabstractfileengine.h>
+#include "qdatetime.h"
 #include "qfilesystementry_p.h"
+#include "qfile.h"
 
 QT_BEGIN_NAMESPACE
 
index a9a1046..36d8200 100644 (file)
@@ -26,8 +26,8 @@
 #include "qplatformdefs.h"
 #include "qdir.h"
 #include "qfile_p.h"
-#include "qabstractfileengine_p.h"
 #include "qfilesystemengine_p.h"
+#include "qdebug.h"
 #include "qcore_unix_p.h"
 #include "qcorecommon_p.h"
 
 
 QT_BEGIN_NAMESPACE
 
-//************* QTemporaryFileEngine
-class QTemporaryFileEngine : public QAbstractFileEngine
-{
-    Q_DECLARE_PRIVATE(QAbstractFileEngine)
-public:
-    QTemporaryFileEngine(const QString &file, bool fileIsTemplate = true)
-        : QAbstractFileEngine(), filePathIsTemplate(fileIsTemplate)
-    {
-        Q_D(QAbstractFileEngine);
-        d->fileEntry = QFileSystemEntry(file);
-
-        if (!filePathIsTemplate)
-            QAbstractFileEngine::setFileName(file);
-    }
-
-    ~QTemporaryFileEngine();
-
-    bool isReallyOpen();
-    void setFileName(const QString &file);
-    void setFileTemplate(const QString &fileTemplate);
-
-    bool open(QIODevice::OpenMode flags);
-    bool remove();
-    bool rename(const QString &newName);
-    bool close();
-
-    bool filePathIsTemplate;
-};
-
-QTemporaryFileEngine::~QTemporaryFileEngine()
-{
-    QAbstractFileEngine::close();
-}
-
-bool QTemporaryFileEngine::isReallyOpen()
-{
-    Q_D(QAbstractFileEngine);
-    return (d->fd != -1);
-
-}
-
-void QTemporaryFileEngine::setFileName(const QString &file)
-{
-    // Really close the file, so we don't leak
-    QAbstractFileEngine::close();
-    QAbstractFileEngine::setFileName(file);
-}
-
-void QTemporaryFileEngine::setFileTemplate(const QString &fileTemplate)
-{
-    Q_D(QAbstractFileEngine);
-    if (filePathIsTemplate)
-        d->fileEntry = QFileSystemEntry(fileTemplate);
-}
-
-bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
-{
-    Q_D(QAbstractFileEngine);
-    Q_ASSERT(!isReallyOpen());
-
-    openMode |= QIODevice::ReadWrite;
-
-    if (!filePathIsTemplate)
-        return QAbstractFileEngine::open(openMode);
-
-    QString qfilename = d->fileEntry.filePath();
-
-    // "Nativify" :-)
-    QFileSystemEntry::NativePath filename =
-        QFileSystemEngine::absoluteName(QFileSystemEntry(qfilename)).nativeFilePath();
-
-    // Find placeholder in native path
-    uint phPos = filename.length();
-    uint phLength = 0;
-    while (phPos != 0) {
-        --phPos;
-
-        if (filename.at(phPos) == 'X') {
-            ++phLength;
-            continue;
-        }
-
-        // require atleast 6 for compatibility
-        if (phLength >= 6 || filename.at(phPos) == '/') {
-            ++phPos;
-            break;
-        }
-
-        // start over
-        phLength = 0;
-    }
-
-    // Ensure there is a placeholder mask
-    if (phLength < 6) {
-        filename.append(".XXXXXXXXXX");
-        phPos = filename.length() - 10;
-        phLength = 10;
-    }
-
-    Q_ASSERT(phLength >= 6);
-    Q_ASSERT(phPos < filename.length());
-    Q_ASSERT(phLength <= filename.length() - phPos);
-
-    static const char tmpnamechars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-    char *data = filename.data();
-    for (uint i = 0; i < phLength; i++) {
-        data[i + phPos] = tmpnamechars[qrand() % 52];
-    }
-
-    // Create file and obtain handle
-    d->fd = qt_safe_open(data, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR, 0600);
-
-    if (d->fd == -1) {
-        setError(QFile::OpenError, qt_error_string(errno));
-        return false;
-    }
-
-    d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
-
-    d->closeFileHandle = true;
-
-    filePathIsTemplate = false;
-
-    d->openMode = openMode;
-    d->metaData.clear();
-
-    return true;
-}
-
-bool QTemporaryFileEngine::remove()
-{
-    Q_D(QAbstractFileEngine);
-    // Since the QTemporaryFileEngine::close() does not really close the file,
-    // we must explicitly call QAbstractFileEngine::close() before we remove it.
-    QAbstractFileEngine::close();
-    if (QAbstractFileEngine::remove()) {
-        d->fileEntry.clear();
-        return true;
-    }
-    return false;
-}
-
-bool QTemporaryFileEngine::rename(const QString &newName)
-{
-    QAbstractFileEngine::close();
-    return QAbstractFileEngine::rename(newName);
-}
-
-bool QTemporaryFileEngine::close()
-{
-    // Don't close the file, just seek to the front.
-    seek(0);
-    setError(QFile::UnspecifiedError, QString());
-    return true;
-}
-
 //************* QTemporaryFilePrivate
 class QTemporaryFilePrivate : public QFilePrivate
 {
@@ -349,32 +192,97 @@ QTemporaryFile::~QTemporaryFile()
 {
     Q_D(QTemporaryFile);
     close();
-    if (!d->fileName.isEmpty() && d->autoRemove)
+    if (!d->fileEntry.isEmpty() && d->autoRemove)
         remove();
 }
 
 /*!
-  \fn bool QTemporaryFile::open()
-
-  A QTemporaryFile will always be opened in QIODevice::ReadWrite mode,
-  this allows easy access to the data in the file. This function will
-  return true upon success and will set the fileName() to the unique
-  filename used.
+    A QTemporaryFile will always be opened in QIODevice::ReadWrite mode,
+    this allows easy access to the data in the file. This function will
+    return true upon success and will set the fileName() to the unique
+    filename used.
 
-  \sa fileName()
+    \sa fileName()
 */
+bool QTemporaryFile::open()
+{
+    Q_D(QTemporaryFile);
+    if (Q_UNLIKELY(isOpen())) {
+        qWarning("QTemporaryFile::open: File (%s) already open", qPrintable(fileName()));
+        return false;
+    }
+
+    // "Nativify" :-)
+    QFileSystemEntry::NativePath filename =
+        QFileSystemEngine::absoluteName(QFileSystemEntry(d->templateName)).nativeFilePath();
+
+    // Find placeholder in native path
+    uint phPos = filename.length();
+    uint phLength = 0;
+    while (phPos != 0) {
+        --phPos;
+
+        if (filename.at(phPos) == 'X') {
+            ++phLength;
+            continue;
+        }
+
+        // require atleast 6 for compatibility
+        if (phLength >= 6 || filename.at(phPos) == '/') {
+            ++phPos;
+            break;
+        }
+
+        // start over
+        phLength = 0;
+    }
+
+    // Ensure there is a placeholder mask
+    if (phLength < 6) {
+        filename.append(".XXXXXXXXXX");
+        phPos = filename.length() - 10;
+        phLength = 10;
+    }
+
+    Q_ASSERT(phLength >= 6);
+    Q_ASSERT(phPos < filename.length());
+    Q_ASSERT(phLength <= filename.length() - phPos);
+
+    static const char tmpnamechars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+    char *data = filename.data();
+    for (uint i = 0; i < phLength; i++) {
+        data[i + phPos] = tmpnamechars[qrand() % 52];
+    }
+
+    // Create file and obtain handle
+    d->fd = qt_safe_open(data, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR, 0600);
+
+    if (d->fd == -1) {
+        d->setError(QFile::OpenError, qt_error_string(errno));
+        return false;
+    }
+
+    d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
+    d->closeFileHandle = true;
+    d->metaData.clear();
+
+    QIODevice::open(QIODevice::ReadWrite);
+
+    return true;
+}
 
 /*!
-   Returns true if the QTemporaryFile is in auto remove
-   mode. Auto-remove mode will automatically delete the filename from
-   disk upon destruction. This makes it very easy to create your
-   QTemporaryFile object on the stack, fill it with data, read from
-   it, and finally on function return it will automatically clean up
-   after itself.
+    Returns true if the QTemporaryFile is in auto remove
+    mode. Auto-remove mode will automatically delete the filename from
+    disk upon destruction. This makes it very easy to create your
+    QTemporaryFile object on the stack, fill it with data, read from
+    it, and finally on function return it will automatically clean up
+    after itself.
 
-   Auto-remove is on by default.
+    Auto-remove is on by default.
 
-   \sa setAutoRemove(), remove()
+    \sa setAutoRemove(), remove()
 */
 bool QTemporaryFile::autoRemove() const
 {
@@ -396,23 +304,6 @@ void QTemporaryFile::setAutoRemove(bool b)
 }
 
 /*!
-   Returns the complete unique filename backing the QTemporaryFile
-   object. This string is null before the QTemporaryFile is opened,
-   afterwards it will contain the fileTemplate() plus
-   additional characters to make it unique.
-
-   \sa fileTemplate()
-*/
-
-QString QTemporaryFile::fileName() const
-{
-    Q_D(const QTemporaryFile);
-    if(d->fileName.isEmpty())
-        return QString();
-    return fileEngine()->fileName(QAbstractFileEngine::DefaultName);
-}
-
-/*!
   Returns the set file template. The default file template will be
   called qt_temp and be placed in QDir::tempPath().
 
@@ -425,10 +316,10 @@ QString QTemporaryFile::fileTemplate() const
 }
 
 /*!
-   Sets the static portion of the file name to \a name. If the file
-   template ends in XXXXXXXXXX that will automatically be replaced with
-   the unique part of the filename, otherwise a filename will be
-   determined automatically based on the static portion specified.
+    Sets the static portion of the file name to \a name. If the file
+    template ends in XXXXXXXXXX that will automatically be replaced with
+    the unique part of the filename, otherwise a filename will be
+    determined automatically based on the static portion specified.
 
     If \a name contains a relative file path, the path will be relative to the
     current working directory. You can use QDir::tempPath() to construct \a
@@ -440,48 +331,6 @@ void QTemporaryFile::setFileTemplate(const QString &name)
 {
     Q_D(QTemporaryFile);
     d->templateName = name;
-    if (d->fileEngine)
-        static_cast<QTemporaryFileEngine*>(d->fileEngine)->setFileTemplate(name);
-}
-
-/*!
-   \internal
-*/
-
-QAbstractFileEngine *QTemporaryFile::fileEngine() const
-{
-    Q_D(const QTemporaryFile);
-    if(!d->fileEngine) {
-        if (d->fileName.isEmpty())
-            d->fileEngine = new QTemporaryFileEngine(d->templateName);
-        else
-            d->fileEngine = new QTemporaryFileEngine(d->fileName, false);
-    }
-    return d->fileEngine;
-}
-
-/*!
-   \reimp
-
-    Creates a unique file name for the temporary file, and opens it.  You can
-    get the unique name later by calling fileName(). The file is guaranteed to
-    have been created by this function (i.e., it has never existed before).
-*/
-bool QTemporaryFile::open(OpenMode flags)
-{
-    Q_D(QTemporaryFile);
-    if (!d->fileName.isEmpty()) {
-        if (static_cast<QTemporaryFileEngine*>(fileEngine())->isReallyOpen()) {
-            setOpenMode(flags);
-            return true;
-        }
-    }
-
-    if (QFile::open(flags)) {
-        d->fileName = d->fileEngine->fileName(QAbstractFileEngine::DefaultName);
-        return true;
-    }
-    return false;
 }
 
 #ifndef QT_NO_QOBJECT
index 0a8079e..a563f7b 100644 (file)
@@ -55,18 +55,11 @@ public:
     bool autoRemove() const;
     void setAutoRemove(bool b);
 
-    // ### Hides open(flags)
-    bool open() { return open(QIODevice::ReadWrite); }
+    bool open();
 
-    QString fileName() const;
     QString fileTemplate() const;
     void setFileTemplate(const QString &name);
 
-    virtual QAbstractFileEngine *fileEngine() const;
-
-protected:
-    bool open(OpenMode flags);
-
 private:
     friend class QFile;
     Q_DISABLE_COPY(QTemporaryFile)
index 1fd4771..f427ed4 100644 (file)
@@ -51,7 +51,6 @@ set(BOOTSTRAP_SOURCES
     ${CMAKE_SOURCE_DIR}/src/core/codecs/qtextcodec.cpp
     ${CMAKE_SOURCE_DIR}/src/core/global/qglobal.cpp
     ${CMAKE_SOURCE_DIR}/src/core/global/qt_error_string.cpp
-    ${CMAKE_SOURCE_DIR}/src/core/io/qabstractfileengine.cpp
     ${CMAKE_SOURCE_DIR}/src/core/io/qbuffer.cpp
     ${CMAKE_SOURCE_DIR}/src/core/io/qdir.cpp
     ${CMAKE_SOURCE_DIR}/src/core/io/qdiriterator.cpp
index 1c0b8ef..20cd299 100644 (file)
@@ -452,7 +452,7 @@ void tst_QFile::open()
     }
 
     if (filename.isEmpty())
-        QTest::ignoreMessage(QtWarningMsg, "QAbstractFileEngine::open: No file name specified");
+        QTest::ignoreMessage(QtWarningMsg, "QFile::open: No file name specified");
 
     if (ok) {
         QVERIFY2(f.open(QIODevice::OpenMode(mode)),
index b5f0862..cfcb326 100644 (file)
@@ -54,14 +54,12 @@ private slots:
     void fileNameIsEmpty();
     void autoRemove();
     void write();
-    void openCloseOpenClose();
     void size();
     void resize();
     void openOnRootDrives();
     void stressTest();
     void rename();
     void renameFdLeak();
-    void reOpenThroughQFile();
     void keepOpenMode();
     void resetTemplateAfterError();
     void setTemplateAfterOpen();
@@ -188,30 +186,6 @@ void tst_QTemporaryFile::write()
     file.close();
 }
 
-void tst_QTemporaryFile::openCloseOpenClose()
-{
-    QString fileName;
-    {
-        // Create a temp file
-        QTemporaryFile file("tempXXXXXX");
-        file.setAutoRemove(true);
-        QVERIFY(file.open());
-        file.write("OLE");
-        fileName = file.fileName();
-        QVERIFY(QFile::exists(fileName));
-        file.close();
-
-        // Check that it still exists after being closed
-        QVERIFY(QFile::exists(fileName));
-        QVERIFY(!file.isOpen());
-        QVERIFY(file.open());
-        QCOMPARE(file.readAll(), QByteArray("OLE"));
-        // Check that it's still the same file after being opened again.
-        QCOMPARE(file.fileName(), fileName);
-    }
-    QVERIFY(!QFile::exists(fileName));
-}
-
 void tst_QTemporaryFile::size()
 {
     QTemporaryFile file;
@@ -324,48 +298,20 @@ void tst_QTemporaryFile::renameFdLeak()
     QVERIFY(qt_safe_close(fd) == -1 && errno == EBADF);
 }
 
-void tst_QTemporaryFile::reOpenThroughQFile()
-{
-    QByteArray data("abcdefghij");
-
-    QTemporaryFile file;
-    QVERIFY(((QFile &)file).open(QIODevice::WriteOnly));
-    QCOMPARE(file.write(data), (qint64)data.size());
-
-    file.close();
-    QVERIFY(file.open());
-    QCOMPARE(file.readAll(), data);
-}
-
 void tst_QTemporaryFile::keepOpenMode()
 {
     QByteArray data("abcdefghij");
 
     {
-        QTemporaryFile file;
-        QVERIFY(((QFile &)file).open(QIODevice::WriteOnly));
-        QVERIFY(QIODevice::WriteOnly == file.openMode());
-
-        QCOMPARE(file.write(data), (qint64)data.size());
-        file.close();
-
-        QVERIFY(((QFile &)file).open(QIODevice::ReadOnly));
-        QVERIFY(QIODevice::ReadOnly == file.openMode());
-        QCOMPARE(file.readAll(), data);
-    }
-
-    {
-        QTemporaryFile file;
-        QVERIFY(file.open());
-        QCOMPARE(file.write(data), (qint64)data.size());
-        QVERIFY(file.rename("temporary-file.txt"));
+        QTemporaryFile tmpfile;
+        QVERIFY(tmpfile.open());
+        QCOMPARE(tmpfile.write(data), (qint64)data.size());
+        QVERIFY(tmpfile.rename("temporary-file.txt"));
 
-        QVERIFY(((QFile &)file).open(QIODevice::ReadOnly));
+        QFile file("temporary-file.txt");
+        QVERIFY(file.open(QIODevice::ReadOnly));
         QVERIFY(QIODevice::ReadOnly == file.openMode());
         QCOMPARE(file.readAll(), data);
-
-        QVERIFY(((QFile &)file).open(QIODevice::WriteOnly));
-        QVERIFY(QIODevice::WriteOnly == file.openMode());
     }
 }
 
@@ -433,7 +379,7 @@ void tst_QTemporaryFile::setTemplateAfterOpen()
     QVERIFY( temp.open() );
 
     QString const fileName = temp.fileName();
-    QString const newTemplate("funny-path/funny-name-XXXXXX.tmp");
+    QString const newTemplate("funny-name-XXXXXX.tmp");
 
     QVERIFY( !fileName.isEmpty() );
     QVERIFY( QFile::exists(fileName) );
@@ -445,7 +391,6 @@ void tst_QTemporaryFile::setTemplateAfterOpen()
     QCOMPARE( temp.fileTemplate(), newTemplate );
 
     QVERIFY( temp.open() );
-    QCOMPARE( temp.fileName(), fileName );
     QCOMPARE( temp.fileTemplate(), newTemplate );
 }