/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2017 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qplatformdefs.h"
#include "qdebug.h"
#include "qfile.h"
#include "qfsfileengine_p.h"
#include "qtemporaryfile.h"
#include "qtemporaryfile_p.h"
#include "qlist.h"
#include "qfileinfo.h"
#include "private/qiodevice_p.h"
#include "private/qfile_p.h"
#include "private/qfilesystemengine_p.h"
#include "private/qsystemerror_p.h"
#include "private/qtemporaryfile_p.h"
#if defined(QT_BUILD_CORE_LIB)
# include "qcoreapplication.h"
#endif

#include <private/qmemory_p.h>

#ifdef QT_NO_QOBJECT
#define tr(X) QString::fromLatin1(X)
#endif

QT_BEGIN_NAMESPACE

Q_DECL_COLD_FUNCTION
static bool file_already_open(QFile &file, const char *where = nullptr)
{
    qWarning("QFile::%s: File (%ls) already open", where ? where : "open", qUtf16Printable(file.fileName()));
    return false;
}

//************* QFilePrivate
QFilePrivate::QFilePrivate()
{
}

QFilePrivate::~QFilePrivate()
{
}

bool
QFilePrivate::openExternalFile(int flags, int fd, QFile::FileHandleFlags handleFlags)
{
#ifdef QT_NO_FSFILEENGINE
    Q_UNUSED(flags);
    Q_UNUSED(fd);
    return false;
#else
    auto fs = qt_make_unique<QFSFileEngine>();
    auto fe = fs.get();
    fileEngine = std::move(fs);
    return fe->open(QIODevice::OpenMode(flags), fd, handleFlags);
#endif
}

bool
QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handleFlags)
{
#ifdef QT_NO_FSFILEENGINE
    Q_UNUSED(flags);
    Q_UNUSED(fh);
    return false;
#else
    auto fs = qt_make_unique<QFSFileEngine>();
    auto fe = fs.get();
    fileEngine = std::move(fs);
    return fe->open(QIODevice::OpenMode(flags), fh, handleFlags);
#endif
}

QAbstractFileEngine *QFilePrivate::engine() const
{
    if (!fileEngine)
        fileEngine.reset(QAbstractFileEngine::create(fileName));
    return fileEngine.get();
}

//************* QFile

/*!
    \class QFile
    \inmodule QtCore
    \brief The QFile class provides an interface for reading from and writing to files.

    \ingroup io

    \reentrant

    QFile is an I/O device for reading and writing text and binary
    files and \l{The Qt Resource System}{resources}. A QFile may be
    used by itself or, more conveniently, with a QTextStream or
    QDataStream.

    The file name is usually passed in the constructor, but it can be
    set at any time using setFileName(). QFile expects the file
    separator to be '/' regardless of operating system. The use of
    other separators (e.g., '\\') is not supported.

    You can check for a file's existence using exists(), and remove a
    file using remove(). (More advanced file system related operations
    are provided by QFileInfo and QDir.)

    The file is opened with open(), closed with close(), and flushed
    with flush(). Data is usually read and written using QDataStream
    or QTextStream, but you can also call the QIODevice-inherited
    functions read(), readLine(), readAll(), write(). QFile also
    inherits getChar(), putChar(), and ungetChar(), which work one
    character at a time.

    The size of the file is returned by size(). You can get the
    current file position using pos(), or move to a new file position
    using seek(). If you've reached the end of the file, atEnd()
    returns \c true.

    \section1 Reading Files Directly

    The following example reads a text file line by line:

    \snippet file/file.cpp 0

    The QIODevice::Text flag passed to open() tells Qt to convert
    Windows-style line terminators ("\\r\\n") into C++-style
    terminators ("\\n"). By default, QFile assumes binary, i.e. it
    doesn't perform any conversion on the bytes stored in the file.

    \section1 Using Streams to Read Files

    The next example uses QTextStream to read a text file
    line by line:

    \snippet file/file.cpp 1

    QTextStream takes care of converting the 8-bit data stored on
    disk into a 16-bit Unicode QString. By default, it assumes that
    the user system's local 8-bit encoding is used (e.g., UTF-8
    on most unix based operating systems; see QTextCodec::codecForLocale() for
    details). This can be changed using \l QTextStream::setCodec().

    To write text, we can use operator<<(), which is overloaded to
    take a QTextStream on the left and various data types (including
    QString) on the right:

    \snippet file/file.cpp 2

    QDataStream is similar, in that you can use operator<<() to write
    data and operator>>() to read it back. See the class
    documentation for details.

    When you use QFile, QFileInfo, and QDir to access the file system
    with Qt, you can use Unicode file names. On Unix, these file
    names are converted to an 8-bit encoding. If you want to use
    standard C++ APIs (\c <cstdio> or \c <iostream>) or
    platform-specific APIs to access files instead of QFile, you can
    use the encodeName() and decodeName() functions to convert
    between Unicode file names and 8-bit file names.

    On Unix, there are some special system files (e.g. in \c /proc) for which
    size() will always return 0, yet you may still be able to read more data
    from such a file; the data is generated in direct response to you calling
    read(). In this case, however, you cannot use atEnd() to determine if
    there is more data to read (since atEnd() will return true for a file that
    claims to have size 0). Instead, you should either call readAll(), or call
    read() or readLine() repeatedly until no more data can be read. The next
    example uses QTextStream to read \c /proc/modules line by line:

    \snippet file/file.cpp 3

    \section1 Signals

    Unlike other QIODevice implementations, such as QTcpSocket, QFile does not
    emit the aboutToClose(), bytesWritten(), or readyRead() signals. This
    implementation detail means that QFile is not suitable for reading and
    writing certain types of files, such as device files on Unix platforms.

    \section1 Platform Specific Issues

    File permissions are handled differently on Unix-like systems and
    Windows.  In a non \l{QIODevice::isWritable()}{writable}
    directory on Unix-like systems, files cannot be created. This is not always
    the case on Windows, where, for instance, the 'My Documents'
    directory usually is not writable, but it is still possible to
    create files in it.

    Qt's understanding of file permissions is limited, which affects especially
    the \l QFile::setPermissions() function. On Windows, Qt will set only the
    legacy read-only flag, and that only when none of the Write* flags are
    passed. Qt does not manipulate access control lists (ACLs), which makes this
    function mostly useless for NTFS volumes. It may still be of use for USB
    sticks that use VFAT file systems. POSIX ACLs are not manipulated, either.

    \sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System}
*/

#ifdef QT_NO_QOBJECT
QFile::QFile()
    : QFileDevice(*new QFilePrivate)
{
}
QFile::QFile(const QString &name)
    : QFileDevice(*new QFilePrivate)
{
    d_func()->fileName = name;
}
QFile::QFile(QFilePrivate &dd)
    : QFileDevice(dd)
{
}
#else
/*!
    Constructs a QFile object.
*/
QFile::QFile()
    : QFileDevice(*new QFilePrivate, nullptr)
{
}
/*!
    Constructs a new file object with the given \a parent.
*/
QFile::QFile(QObject *parent)
    : QFileDevice(*new QFilePrivate, parent)
{
}
/*!
    Constructs a new file object to represent the file with the given \a name.
*/
QFile::QFile(const QString &name)
    : QFileDevice(*new QFilePrivate, nullptr)
{
    Q_D(QFile);
    d->fileName = name;
}
/*!
    Constructs a new file object with the given \a parent to represent the
    file with the specified \a name.
*/
QFile::QFile(const QString &name, QObject *parent)
    : QFileDevice(*new QFilePrivate, parent)
{
    Q_D(QFile);
    d->fileName = name;
}
/*!
    \internal
*/
QFile::QFile(QFilePrivate &dd, QObject *parent)
    : QFileDevice(dd, parent)
{
}
#endif

/*!
    Destroys the file object, closing it if necessary.
*/
QFile::~QFile()
{
}

/*!
    Returns the name set by setFileName() or to the QFile
    constructors.

    \sa setFileName(), QFileInfo::fileName()
*/
QString QFile::fileName() const
{
    Q_D(const QFile);
    return d->engine()->fileName(QAbstractFileEngine::DefaultName);
}

/*!
    Sets the \a name of the file. The name can have no path, a
    relative path, or an absolute path.

    Do not call this function if the file has already been opened.

    If the file name has no path or a relative path, the path used
    will be the application's current directory path
    \e{at the time of the open()} call.

    Example:
    \snippet code/src_corelib_io_qfile.cpp 0

    Note that the directory separator "/" works for all operating
    systems supported by Qt.

    \sa fileName(), QFileInfo, QDir
*/
void
QFile::setFileName(const QString &name)
{
    Q_D(QFile);
    if (isOpen()) {
        file_already_open(*this, "setFileName");
        close();
    }
    d->fileEngine.reset(); //get a new file engine later
    d->fileName = name;
}

/*!
    \fn QString QFile::decodeName(const char *localFileName)

    \overload

    Returns the Unicode version of the given \a localFileName. See
    encodeName() for details.
*/

/*!
    \fn QByteArray QFile::encodeName(const QString &fileName)

    Converts \a fileName to the local 8-bit
    encoding determined by the user's locale. This is sufficient for
    file names that the user chooses. File names hard-coded into the
    application should only use 7-bit ASCII filename characters.

    \sa decodeName()
*/

/*!
    \typedef QFile::EncoderFn
    \obsolete

    This is a typedef for a pointer to a function with the following
    signature:

    \snippet code/src_corelib_io_qfile.cpp 1

    \sa setEncodingFunction(), encodeName()
*/

/*!
    \fn QString QFile::decodeName(const QByteArray &localFileName)

    This does the reverse of QFile::encodeName() using \a localFileName.

    \sa encodeName()
*/

/*!
    \fn void QFile::setEncodingFunction(EncoderFn function)
    \obsolete

    This function does nothing. It is provided for compatibility with Qt 4 code
    that attempted to set a different encoding function for file names. That
    feature is flawed and no longer supported in Qt 5.

    \sa encodeName(), setDecodingFunction()
*/

/*!
    \typedef QFile::DecoderFn

    This is a typedef for a pointer to a function with the following
    signature:

    \snippet code/src_corelib_io_qfile.cpp 2

    \sa setDecodingFunction()
*/

/*!
    \fn void QFile::setDecodingFunction(DecoderFn function)
    \obsolete

    This function does nothing. It is provided for compatibility with Qt 4 code
    that attempted to set a different decoding function for file names. That
    feature is flawed and no longer supported in Qt 5.

    \sa setEncodingFunction(), decodeName()
*/

/*!
    \overload

    Returns \c true if the file specified by fileName() exists; otherwise
    returns \c false.

    \sa fileName(), setFileName()
*/

bool
QFile::exists() const
{
    Q_D(const QFile);
    // 0x1000000 = QAbstractFileEngine::Refresh, forcing an update
    return (d->engine()->fileFlags(QAbstractFileEngine::FlagsMask
                                    | QAbstractFileEngine::Refresh) & QAbstractFileEngine::ExistsFlag);
}

/*!
    Returns \c true if the file specified by \a fileName exists; otherwise
    returns \c false.

    \note If \a fileName is a symlink that points to a non-existing
    file, false is returned.
*/

bool
QFile::exists(const QString &fileName)
{
    return QFileInfo::exists(fileName);
}

/*!
    \fn QString QFile::symLinkTarget() const
    \since 4.2
    \overload

    Returns the absolute path of the file or directory a symlink (or shortcut
    on Windows) points to, or a an empty string if the object isn't a symbolic
    link.

    This name may not represent an existing file; it is only a string.
    QFile::exists() returns \c true if the symlink points to an existing file.

    \sa fileName(), setFileName()
*/
QString QFile::symLinkTarget() const
{
    Q_D(const QFile);
    return d->engine()->fileName(QAbstractFileEngine::LinkName);
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \obsolete

    Use symLinkTarget() instead.
*/
QString
QFile::readLink() const
{
    return symLinkTarget();
}
#endif

/*!
    \fn static QString QFile::symLinkTarget(const QString &fileName)
    \since 4.2

    Returns the absolute path of the file or directory referred to by the
    symlink (or shortcut on Windows) specified by \a fileName, or returns an
    empty string if the \a fileName does not correspond to a symbolic link.

    This name may not represent an existing file; it is only a string.
    QFile::exists() returns \c true if the symlink points to an existing file.
*/
QString QFile::symLinkTarget(const QString &fileName)
{
    return QFileInfo(fileName).symLinkTarget();
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \obsolete

    Use symLinkTarget() instead.
*/
QString
QFile::readLink(const QString &fileName)
{
    return symLinkTarget(fileName);
}
#endif

/*!
    Removes the file specified by fileName(). Returns \c true if successful;
    otherwise returns \c false.

    The file is closed before it is removed.

    \sa setFileName()
*/

bool
QFile::remove()
{
    Q_D(QFile);
    if (d->fileName.isEmpty() &&
            !static_cast<QFSFileEngine *>(d->engine())->isUnnamedFile()) {
        qWarning("QFile::remove: Empty or null file name");
        return false;
    }
    unsetError();
    close();
    if(error() == QFile::NoError) {
        if (d->engine()->remove()) {
            unsetError();
            return true;
        }
        d->setError(QFile::RemoveError, d->fileEngine->errorString());
    }
    return false;
}

/*!
    \overload

    Removes the file specified by the \a fileName given.

    Returns \c true if successful; otherwise returns \c false.

    \sa remove()
*/

bool
QFile::remove(const QString &fileName)
{
    return QFile(fileName).remove();
}

/*!
    \since 5.15

    Moves the file specified by fileName() to the trash. Returns \c true if successful,
    and sets the fileName() to the path at which the file can be found within the trash;
    otherwise returns \c false.

    \note On systems where the system API doesn't report the location of the file in the
    trash, fileName() will be set to the null string once the file has been moved. On
    systems that don't have a trash can, this function always returns false.
*/
bool
QFile::moveToTrash()
{
    Q_D(QFile);
    if (d->fileName.isEmpty() &&
        !static_cast<QFSFileEngine *>(d->engine())->isUnnamedFile()) {
        qWarning("QFile::remove: Empty or null file name");
        return false;
    }
    unsetError();
    close();
    if (error() == QFile::NoError) {
        QFileSystemEntry fileEntry(d->fileName);
        QFileSystemEntry trashEntry;
        QSystemError error;
        if (QFileSystemEngine::moveFileToTrash(fileEntry, trashEntry, error)) {
            setFileName(trashEntry.filePath());
            unsetError();
            return true;
        }
        d->setError(QFile::RenameError, error.toString());
    }
    return false;
}

/*!
    \since 5.15
    \overload

    Moves the file specified by fileName() to the trash. Returns \c true if successful,
    and sets \a pathInTrash (if provided) to the path at which the file can be found within
    the trash; otherwise returns \c false.

    \note On systems where the system API doesn't report the path of the file in the
    trash, \a pathInTrash will be set to the null string once the file has been moved.
    On systems that don't have a trash can, this function always returns false.
*/
bool
QFile::moveToTrash(const QString &fileName, QString *pathInTrash)
{
    QFile file(fileName);
    if (file.moveToTrash()) {
        if (pathInTrash)
            *pathInTrash = file.fileName();
        return true;
    }
    return false;
}

/*!
    Renames the file currently specified by fileName() to \a newName.
    Returns \c true if successful; otherwise returns \c false.

    If a file with the name \a newName already exists, rename() returns \c false
    (i.e., QFile will not overwrite it).

    The file is closed before it is renamed.

    If the rename operation fails, Qt will attempt to copy this file's
    contents to \a newName, and then remove this file, keeping only
    \a newName. If that copy operation fails or this file can't be removed,
    the destination file \a newName is removed to restore the old state.

    \sa setFileName()
*/

bool
QFile::rename(const QString &newName)
{
    Q_D(QFile);

    // if this is a QTemporaryFile, the virtual fileName() call here may do something
    if (fileName().isEmpty()) {
        qWarning("QFile::rename: Empty or null file name");
        return false;
    }
    if (d->fileName == newName) {
        d->setError(QFile::RenameError, tr("Destination file is the same file."));
        return false;
    }
    if (!exists()) {
        d->setError(QFile::RenameError, tr("Source file does not exist."));
        return false;
    }

    // If the file exists and it is a case-changing rename ("foo" -> "Foo"),
    // compare Ids to make sure it really is a different file.
    // Note: this does not take file engines into account.
    bool changingCase = false;
    QByteArray targetId = QFileSystemEngine::id(QFileSystemEntry(newName));
    if (!targetId.isNull()) {
        QByteArray fileId = d->fileEngine ?
                    d->fileEngine->id() :
                    QFileSystemEngine::id(QFileSystemEntry(d->fileName));
        changingCase = (fileId == targetId && d->fileName.compare(newName, Qt::CaseInsensitive) == 0);
        if (!changingCase) {
            d->setError(QFile::RenameError, tr("Destination file exists"));
            return false;
        }

#ifdef Q_OS_LINUX
        // rename() on Linux simply does nothing when renaming "foo" to "Foo" on a case-insensitive
        // FS, such as FAT32. Move the file away and rename in 2 steps to work around.
        QTemporaryFileName tfn(d->fileName);
        QFileSystemEntry src(d->fileName);
        QSystemError error;
        for (int attempt = 0; attempt < 16; ++attempt) {
            QFileSystemEntry tmp(tfn.generateNext(), QFileSystemEntry::FromNativePath());

            // rename to temporary name
            if (!QFileSystemEngine::renameFile(src, tmp, error))
                continue;

            // rename to final name
            if (QFileSystemEngine::renameFile(tmp, QFileSystemEntry(newName), error)) {
                d->fileEngine->setFileName(newName);
                d->fileName = newName;
                return true;
            }

            // We need to restore the original file.
            QSystemError error2;
            if (QFileSystemEngine::renameFile(tmp, src, error2))
                break;      // report the original error, below

            // report both errors
            d->setError(QFile::RenameError,
                        tr("Error while renaming: %1").arg(error.toString())
                        + QLatin1Char('\n')
                        + tr("Unable to restore from %1: %2").
                        arg(QDir::toNativeSeparators(tmp.filePath()), error2.toString()));
            return false;
        }
        d->setError(QFile::RenameError,
                    tr("Error while renaming: %1").arg(error.toString()));
        return false;
#endif // Q_OS_LINUX
    }
    unsetError();
    close();
    if(error() == QFile::NoError) {
        if (changingCase ? d->engine()->renameOverwrite(newName) : d->engine()->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;
        }

        if (isSequential()) {
            d->setError(QFile::RenameError, tr("Will not rename sequential file using block copy"));
            return false;
        }

        QFile out(newName);
        if (open(QIODevice::ReadOnly)) {
            if (out.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
                bool error = false;
                char block[4096];
                qint64 bytes;
                while ((bytes = read(block, sizeof(block))) > 0) {
                    if (bytes != out.write(block, bytes)) {
                        d->setError(QFile::RenameError, out.errorString());
                        error = true;
                        break;
                    }
                }
                if (bytes == -1) {
                    d->setError(QFile::RenameError, errorString());
                    error = true;
                }
                if(!error) {
                    if (!remove()) {
                        d->setError(QFile::RenameError, tr("Cannot remove source file"));
                        error = true;
                    }
                }
                if (error) {
                    out.remove();
                } else {
                    d->fileEngine->setFileName(newName);
                    setPermissions(permissions());
                    unsetError();
                    setFileName(newName);
                }
                close();
                return !error;
            }
            close();
            d->setError(QFile::RenameError,
                        tr("Cannot open destination file: %1").arg(out.errorString()));
        } else {
            d->setError(QFile::RenameError, errorString());
        }
    }
    return false;
}

/*!
    \overload

    Renames the file \a oldName to \a newName. Returns \c true if
    successful; otherwise returns \c false.

    If a file with the name \a newName already exists, rename() returns \c false
    (i.e., QFile will not overwrite it).

    \sa rename()
*/

bool
QFile::rename(const QString &oldName, const QString &newName)
{
    return QFile(oldName).rename(newName);
}

/*!

    Creates a link named \a linkName that points to the file currently specified by
    fileName().  What a link is depends on the underlying filesystem (be it a
    shortcut on Windows or a symbolic link on Unix). Returns \c true if successful;
    otherwise returns \c false.

    This function will not overwrite an already existing entity in the file system;
    in this case, \c link() will return false and set \l{QFile::}{error()} to
    return \l{QFile::}{RenameError}.

    \note To create a valid link on Windows, \a linkName must have a \c{.lnk} file extension.

    \sa setFileName()
*/

bool
QFile::link(const QString &linkName)
{
    Q_D(QFile);
    if (fileName().isEmpty()) {
        qWarning("QFile::link: Empty or null file name");
        return false;
    }
    QFileInfo fi(linkName);
    if (d->engine()->link(fi.absoluteFilePath())) {
        unsetError();
        return true;
    }
    d->setError(QFile::RenameError, d->fileEngine->errorString());
    return false;
}

/*!
    \overload

    Creates a link named \a linkName that points to the file \a fileName. What a link is
    depends on the underlying filesystem (be it a shortcut on Windows
    or a symbolic link on Unix). Returns \c true if successful; otherwise
    returns \c false.

    \sa link()
*/

bool
QFile::link(const QString &fileName, const QString &linkName)
{
    return QFile(fileName).link(linkName);
}

/*!
    Copies the file currently specified by fileName() to a file called
    \a newName.  Returns \c true if successful; otherwise returns \c false.

    Note that if a file with the name \a newName already exists,
    copy() returns \c false (i.e. QFile will not overwrite it).

    The source file is closed before it is copied.

    \sa setFileName()
*/

bool
QFile::copy(const QString &newName)
{
    Q_D(QFile);
    if (fileName().isEmpty()) {
        qWarning("QFile::copy: Empty or null file name");
        return false;
    }
    if (QFile::exists(newName)) {
        // ### Race condition. If a file is moved in after this, it /will/ be
        // overwritten. On Unix, the proper solution is to use hardlinks:
        // return ::link(old, new) && ::remove(old); See also rename().
        d->setError(QFile::CopyError, tr("Destination file exists"));
        return false;
    }
    unsetError();
    close();
    if(error() == QFile::NoError) {
        if (d->engine()->copy(newName)) {
            unsetError();
            return true;
        } else {
            bool error = false;
            if(!open(QFile::ReadOnly)) {
                error = true;
                d->setError(QFile::CopyError, tr("Cannot open %1 for input").arg(d->fileName));
            } else {
                const auto fileTemplate = QLatin1String("%1/qt_temp.XXXXXX");
#ifdef QT_NO_TEMPORARYFILE
                QFile out(fileTemplate.arg(QFileInfo(newName).path()));
                if (!out.open(QIODevice::ReadWrite))
                    error = true;
#else
                QTemporaryFile out(fileTemplate.arg(QFileInfo(newName).path()));
                if (!out.open()) {
                    out.setFileTemplate(fileTemplate.arg(QDir::tempPath()));
                    if (!out.open())
                        error = true;
                }
#endif
                if (error) {
                    out.close();
                    close();
                    d->setError(QFile::CopyError, tr("Cannot open for output: %1").arg(out.errorString()));
                } else {
                    if (!d->engine()->cloneTo(out.d_func()->engine())) {
                        char block[4096];
                        qint64 totalRead = 0;
                        while (!atEnd()) {
                            qint64 in = read(block, sizeof(block));
                            if (in <= 0)
                                break;
                            totalRead += in;
                            if (in != out.write(block, in)) {
                                close();
                                d->setError(QFile::CopyError, tr("Failure to write block"));
                                error = true;
                                break;
                            }
                        }

                        if (totalRead != size()) {
                            // Unable to read from the source. The error string is
                            // already set from read().
                            error = true;
                        }
                    }

                    if (!error) {
                        // Sync to disk if possible. Ignore errors (e.g. not supported).
                        d->fileEngine->syncToDisk();

                        if (!out.rename(newName)) {
                            error = true;
                            close();
                            d->setError(QFile::CopyError, tr("Cannot create %1 for output").arg(newName));
                        }
                    }
#ifdef QT_NO_TEMPORARYFILE
                    if (error)
                        out.remove();
#else
                    if (!error)
                        out.setAutoRemove(false);
#endif
                }
            }
            if(!error) {
                QFile::setPermissions(newName, permissions());
                close();
                unsetError();
                return true;
            }
        }
    }
    return false;
}

/*!
    \overload

    Copies the file \a fileName to \a newName. Returns \c true if successful;
    otherwise returns \c false.

    If a file with the name \a newName already exists, copy() returns \c false
    (i.e., QFile will not overwrite it).

    \sa rename()
*/

bool
QFile::copy(const QString &fileName, const QString &newName)
{
    return QFile(fileName).copy(newName);
}

/*!
    Opens the file using OpenMode \a mode, returning true if successful;
    otherwise false.

    The \a mode must be QIODevice::ReadOnly, QIODevice::WriteOnly, or
    QIODevice::ReadWrite. It may also have additional flags, such as
    QIODevice::Text and QIODevice::Unbuffered.

    \note In \l{QIODevice::}{WriteOnly} or \l{QIODevice::}{ReadWrite}
    mode, if the relevant file does not already exist, this function
    will try to create a new file before opening it.

    \sa QIODevice::OpenMode, setFileName()
*/
bool QFile::open(OpenMode mode)
{
    Q_D(QFile);
    if (isOpen())
        return file_already_open(*this);
    // Either Append or NewOnly implies WriteOnly
    if (mode & (Append | NewOnly))
        mode |= WriteOnly;
    unsetError();
    if ((mode & (ReadOnly | WriteOnly)) == 0) {
        qWarning("QIODevice::open: File access not specified");
        return false;
    }

    // QIODevice provides the buffering, so there's no need to request it from the file engine.
    if (d->engine()->open(mode | QIODevice::Unbuffered)) {
        QIODevice::open(mode);
        if (mode & Append)
            seek(size());
        return true;
    }
    QFile::FileError err = d->fileEngine->error();
    if(err == QFile::UnspecifiedError)
        err = QFile::OpenError;
    d->setError(err, d->fileEngine->errorString());
    return false;
}

/*!
    \overload

    Opens the existing file handle \a fh in the given \a mode.
    \a handleFlags may be used to specify additional options.
    Returns \c true if successful; otherwise returns \c false.

    Example:
    \snippet code/src_corelib_io_qfile.cpp 3

    When a QFile is opened using this function, behaviour of close() is
    controlled by the AutoCloseHandle flag.
    If AutoCloseHandle is specified, and this function succeeds,
    then calling close() closes the adopted handle.
    Otherwise, close() does not actually close the file, but only flushes it.

    \b{Warning:}
    \list 1
        \li If \a fh does not refer to a regular file, e.g., it is \c stdin,
           \c stdout, or \c stderr, you may not be able to seek(). size()
           returns \c 0 in those cases. See QIODevice::isSequential() for
           more information.
        \li Since this function opens the file without specifying the file name,
           you cannot use this QFile with a QFileInfo.
    \endlist

    \sa close()

    \b{Note for the Windows Platform}

    \a fh must be opened in binary mode (i.e., the mode string must contain
    'b', as in "rb" or "wb") when accessing files and other random-access
    devices. Qt will translate the end-of-line characters if you pass
    QIODevice::Text to \a mode. Sequential devices, such as stdin and stdout,
    are unaffected by this limitation.

    You need to enable support for console applications in order to use the
    stdin, stdout and stderr streams at the console. To do this, add the
    following declaration to your application's project file:

    \snippet code/src_corelib_io_qfile.cpp 4
*/
bool QFile::open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
{
    Q_D(QFile);
    if (isOpen())
        return file_already_open(*this);
    // Either Append or NewOnly implies WriteOnly
    if (mode & (Append | NewOnly))
        mode |= WriteOnly;
    unsetError();
    if ((mode & (ReadOnly | WriteOnly)) == 0) {
        qWarning("QFile::open: File access not specified");
        return false;
    }

    // QIODevice provides the buffering, so request unbuffered file engines
    if (d->openExternalFile(mode | Unbuffered, fh, handleFlags)) {
        QIODevice::open(mode);
        if (!(mode & Append) && !isSequential()) {
            qint64 pos = (qint64)QT_FTELL(fh);
            if (pos != -1) {
                // Skip redundant checks in QFileDevice::seek().
                QIODevice::seek(pos);
            }
        }
        return true;
    }
    return false;
}

/*!
    \overload

    Opens the existing file descriptor \a fd in the given \a mode.
    \a handleFlags may be used to specify additional options.
    Returns \c true if successful; otherwise returns \c false.

    When a QFile is opened using this function, behaviour of close() is
    controlled by the AutoCloseHandle flag.
    If AutoCloseHandle is specified, and this function succeeds,
    then calling close() closes the adopted handle.
    Otherwise, close() does not actually close the file, but only flushes it.

    The QFile that is opened using this function is automatically set
    to be in raw mode; this means that the file input/output functions
    are slow. If you run into performance issues, you should try to
    use one of the other open functions.

    \warning If \a fd is not a regular file, e.g, it is 0 (\c stdin),
    1 (\c stdout), or 2 (\c stderr), you may not be able to seek(). In
    those cases, size() returns \c 0.  See QIODevice::isSequential()
    for more information.

    \warning Since this function opens the file without specifying the file name,
             you cannot use this QFile with a QFileInfo.

    \sa close()
*/
bool QFile::open(int fd, OpenMode mode, FileHandleFlags handleFlags)
{
    Q_D(QFile);
    if (isOpen())
        return file_already_open(*this);
    // Either Append or NewOnly implies WriteOnly
    if (mode & (Append | NewOnly))
        mode |= WriteOnly;
    unsetError();
    if ((mode & (ReadOnly | WriteOnly)) == 0) {
        qWarning("QFile::open: File access not specified");
        return false;
    }

    // QIODevice provides the buffering, so request unbuffered file engines
    if (d->openExternalFile(mode | Unbuffered, fd, handleFlags)) {
        QIODevice::open(mode);
        if (!(mode & Append) && !isSequential()) {
            qint64 pos = (qint64)QT_LSEEK(fd, QT_OFF_T(0), SEEK_CUR);
            if (pos != -1) {
                // Skip redundant checks in QFileDevice::seek().
                QIODevice::seek(pos);
            }
        }
        return true;
    }
    return false;
}

/*!
    \reimp
*/
bool QFile::resize(qint64 sz)
{
    return QFileDevice::resize(sz); // for now
}

/*!
    \overload

    Sets \a fileName to size (in bytes) \a sz. Returns \c true if
    the resize succeeds; false otherwise. If \a sz is larger than \a
    fileName currently is the new bytes will be set to 0, if \a sz is
    smaller the file is simply truncated.

    \warning This function can fail if the file doesn't exist.

    \sa resize()
*/

bool
QFile::resize(const QString &fileName, qint64 sz)
{
    return QFile(fileName).resize(sz);
}

/*!
    \reimp
*/
QFile::Permissions QFile::permissions() const
{
    return QFileDevice::permissions(); // for now
}

/*!
    \overload

    Returns the complete OR-ed together combination of
    QFile::Permission for \a fileName.
*/

QFile::Permissions
QFile::permissions(const QString &fileName)
{
    return QFile(fileName).permissions();
}

/*!
    Sets the permissions for the file to the \a permissions specified.
    Returns \c true if successful, or \c false if the permissions cannot be
    modified.

    \warning This function does not manipulate ACLs, which may limit its
    effectiveness.

    \sa permissions(), setFileName()
*/

bool QFile::setPermissions(Permissions permissions)
{
    return QFileDevice::setPermissions(permissions); // for now
}

/*!
    \overload

    Sets the permissions for \a fileName file to \a permissions.
*/

bool
QFile::setPermissions(const QString &fileName, Permissions permissions)
{
    return QFile(fileName).setPermissions(permissions);
}

/*!
  \reimp
*/
qint64 QFile::size() const
{
    return QFileDevice::size(); // for now
}

QT_END_NAMESPACE

#ifndef QT_NO_QOBJECT
#include "moc_qfile.cpp"
#endif
