summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-07-16 01:19:23 -0700
committerSimon Hausmann <simon.hausmann@qt.io>2017-08-22 06:56:08 +0000
commit26094982f893b6f655d20cefb678b306be02e5ac (patch)
treebcf7cce4bdd6fbc5eb991dd227d0f5945e64af7d /src
parent750a252b89e62a7325a6d0c0c470f2c6781ad875 (diff)
Move the file-cloning code from QFSFileEngine to QFileSystemEngine
Change-Id: I02d22222fff64d4dbda4fffd14d1c1bbf48385ff Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qfilesystemengine_p.h1
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp20
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp12
3 files changed, 24 insertions, 9 deletions
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 <sys/ioctl.h>
# include <sys/syscall.h>
+# include <sys/sendfile.h>
# include <linux/fs.h>
+// 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