Fix QAbstractFileEngine::clone misuse
QFile::copy was assuming that the target file was native and therefore it could simply take the file descriptor to clone. While that was not currently a problem, in theory it could be as we do have one writeable file engine besides QFSFileEngine (QWinRTFileEngine). By refactoring to take the parameter as a QAbstractFileEngine, we can ensure that the target file is a native file. Change-Id: Ib7a1737987bf4c4a8c51fffd14d0c048fd509025 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
284fff1217
commit
9312ec54db
@ -864,13 +864,14 @@ bool QAbstractFileEngine::unmap(uchar *address)
|
||||
/*!
|
||||
\since 5.10
|
||||
|
||||
Copies the contents from the file specified by \a sourceHandle to this file
|
||||
by cloning it.
|
||||
Duplicates the contents of this file (starting from the current position)
|
||||
to the file specified by the engine \a target.
|
||||
|
||||
Returns \c true on success; otherwise, \c false is returned.
|
||||
*/
|
||||
bool QAbstractFileEngine::clone(int sourceHandle)
|
||||
bool QAbstractFileEngine::cloneTo(QAbstractFileEngine *target)
|
||||
{
|
||||
Q_UNUSED(sourceHandle);
|
||||
Q_UNUSED(target);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ public:
|
||||
virtual QDateTime fileTime(FileTime time) const;
|
||||
virtual void setFileName(const QString &file);
|
||||
virtual int handle() const;
|
||||
virtual bool clone(int sourceHandle);
|
||||
virtual bool cloneTo(QAbstractFileEngine *target);
|
||||
bool atEnd() const;
|
||||
uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags);
|
||||
bool unmap(uchar *ptr);
|
||||
|
@ -804,7 +804,7 @@ QFile::copy(const QString &newName)
|
||||
close();
|
||||
d->setError(QFile::CopyError, tr("Cannot open for output"));
|
||||
} else {
|
||||
if (!out.d_func()->engine()->clone(d->engine()->handle())) {
|
||||
if (!d->engine()->cloneTo(out.d_func()->engine())) {
|
||||
char block[4096];
|
||||
qint64 totalRead = 0;
|
||||
while (!atEnd()) {
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
|
||||
qint64 readLine(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
|
||||
qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
|
||||
bool clone(int sourceHandle) override;
|
||||
bool cloneTo(QAbstractFileEngine *target) override;
|
||||
|
||||
bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) Q_DECL_OVERRIDE;
|
||||
bool supportsExtension(Extension extension) const Q_DECL_OVERRIDE;
|
||||
|
@ -735,16 +735,19 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
bool QFSFileEngine::clone(int sourceHandle)
|
||||
bool QFSFileEngine::cloneTo(QAbstractFileEngine *target)
|
||||
{
|
||||
if ((target->fileFlags(LocalDiskFlag) & LocalDiskFlag) == 0)
|
||||
return false;
|
||||
#if defined(Q_OS_LINUX)
|
||||
Q_D(QFSFileEngine);
|
||||
# if !defined FICLONE
|
||||
# define FICLONE _IOW (0x94, 9, int)
|
||||
# endif
|
||||
return ::ioctl(d->fd, FICLONE, sourceHandle) == 0;
|
||||
int srcfd = d->nativeHandle();
|
||||
int dstfd = target->handle();
|
||||
return ::ioctl(dstfd, FICLONE, srcfd) == 0;
|
||||
#else
|
||||
Q_UNUSED(sourceHandle);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
@ -1032,9 +1032,11 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
bool QFSFileEngine::clone(int sourceHandle)
|
||||
bool QFSFileEngine::cloneTo(QAbstractFileEngine *target)
|
||||
{
|
||||
Q_UNUSED(sourceHandle);
|
||||
// There's some Windows Server 2016 API, but we won't
|
||||
// bother with it.
|
||||
Q_UNUSED(target);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user