From f0c42af362c1ebbd5fe8b162224ed2d84962802c Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Fri, 13 Dec 2019 12:58:56 +0000 Subject: [PATCH] implement file copying for Linux Signed-off-by: Ivailo Monev --- src/core/global/qplatformdefs.h | 2 + src/core/io/qfilesystemengine_unix.cpp | 53 ++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/core/global/qplatformdefs.h b/src/core/global/qplatformdefs.h index 6681923a1..99441ac0a 100644 --- a/src/core/global/qplatformdefs.h +++ b/src/core/global/qplatformdefs.h @@ -93,6 +93,7 @@ #define QT_LSEEK ::lseek64 #define QT_FSTAT ::fstat64 #define QT_FTRUNCATE ::ftruncate64 +#define QT_CREAT ::creat64 // Standard C89 #define QT_FOPEN ::fopen64 @@ -125,6 +126,7 @@ #define QT_LSEEK ::lseek #define QT_FSTAT ::fstat #define QT_FTRUNCATE ::ftruncate +#define QT_CREAT ::creat // Posix extensions to C89 #if !defined(QT_NO_USE_FSEEKO) diff --git a/src/core/io/qfilesystemengine_unix.cpp b/src/core/io/qfilesystemengine_unix.cpp index c8b331280..8f3b6a4e5 100644 --- a/src/core/io/qfilesystemengine_unix.cpp +++ b/src/core/io/qfilesystemengine_unix.cpp @@ -44,6 +44,10 @@ #include #include +#ifdef Q_OS_LINUX +# include +#endif + QT_BEGIN_NAMESPACE bool QFileSystemEngine::isCaseSensitive() @@ -370,9 +374,58 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy //static bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) { +#ifdef Q_OS_LINUX + +// not in qplatformdefs.h since it is Linux specific +#if defined(QT_USE_XOPEN_LFS_EXTENSIONS) && defined(QT_LARGEFILE_SUPPORT) +# define QT_SENDFILE ::sendfile64 +#else +# define QT_SENDFILE ::sendfile +#endif + + QT_STATBUF st; + if (QT_STAT(source.nativeFilePath().constData(), &st) != -1) { + if (!S_ISREG(st.st_mode)) + return false; + } + + const int sourcefd = QT_OPEN(source.nativeFilePath().constData(), O_RDONLY); + if (sourcefd == -1) { + error = QSystemError(errno, QSystemError::StandardLibraryError); + return false; + } + + const int targetfd = QT_CREAT(target.nativeFilePath().constData(), st.st_mode); + if (targetfd == -1) { + ::close(sourcefd); + error = QSystemError(errno, QSystemError::StandardLibraryError); + return false; + } + + QT_OFF_T tosend = st.st_size; + ssize_t sendresult = QT_SENDFILE(targetfd, sourcefd, Q_NULLPTR, tosend); + while (sendresult != tosend) { + if (sendresult == -1) { + error = QSystemError(errno, QSystemError::StandardLibraryError); + ::close(sourcefd); + ::close(targetfd); + return false; + } + tosend -= sendresult; + sendresult = QT_SENDFILE(targetfd, sourcefd, &tosend, tosend); + } + + ::close(sourcefd); + ::close(targetfd); + return true; + +#undef QT_SENDFILE + +#else Q_UNUSED(source); Q_UNUSED(target); error = QSystemError(ENOSYS, QSystemError::StandardLibraryError); //Function not implemented +#endif // Q_OS_LINUX return false; }