diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index a3c96ebd78..09ec2d6a10 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -91,6 +91,7 @@ public: static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what); #if defined(Q_OS_UNIX) + static bool cloneFile(int srcfd, int dstfd, const QFileSystemMetaData &knownData); static bool fillMetaData(int fd, QFileSystemMetaData &data); // what = PosixStatFlags static QByteArray id(int fd); static bool setFileTime(int fd, const QDateTime &newDate, diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index d74c126bef..3ba8275dfd 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -78,9 +78,16 @@ extern "C" NSString *NSTemporaryDirectory(); #endif #if defined(Q_OS_LINUX) +# include # include +# include # include +// in case linux/fs.h is too old and doesn't define it: +#ifndef FICLONE +# define FICLONE _IOW(0x94, 9, int) +#endif + # if !QT_CONFIG(renameat2) && defined(SYS_renameat2) static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newpath, unsigned flags) { return syscall(SYS_renameat2, oldfd, oldpath, newfd, newpath, flags); } @@ -1065,6 +1072,19 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM return data.hasFlags(what); } +// static +bool QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaData &knownData) +{ +#if defined(Q_OS_LINUX) + // try FICLONE (only works on regular files and only on certain fs) + return ::ioctl(dstfd, FICLONE, srcfd) == 0; +#else + Q_UNUSED(srcfd); + Q_UNUSED(dstfd); + return false; +#endif +} + // Note: if \a shouldMkdirFirst is false, we assume the caller did try to mkdir // before calling this function. static bool createDirectoryWithParents(const QByteArray &nativeName, bool shouldMkdirFirst = true) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 83091ca808..c040d67862 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -737,19 +737,13 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) */ bool QFSFileEngine::cloneTo(QAbstractFileEngine *target) { + Q_D(QFSFileEngine); 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 + int srcfd = d->nativeHandle(); int dstfd = target->handle(); - return ::ioctl(dstfd, FICLONE, srcfd) == 0; -#else - return false; -#endif + return QFileSystemEngine::cloneFile(srcfd, dstfd, d->metaData); } QT_END_NAMESPACE