From 34534a9653fd2308f7b04863f28bb71b741a1890 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Thu, 11 Mar 2021 13:11:46 +0400 Subject: [PATCH] Use kernel accelerated sendfile to copy files on Linux --- Telegram/SourceFiles/_other/updater_linux.cpp | 20 ++++++++++++---- .../platform/linux/specific_linux.cpp | 23 +++++++++++++++---- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/Telegram/SourceFiles/_other/updater_linux.cpp b/Telegram/SourceFiles/_other/updater_linux.cpp index 5d4d742e2f..911dab048d 100644 --- a/Telegram/SourceFiles/_other/updater_linux.cpp +++ b/Telegram/SourceFiles/_other/updater_linux.cpp @@ -97,11 +97,6 @@ bool copyFile(const char *from, const char *to) { fclose(ffrom); return false; } - static const int BufSize = 65536; - char buf[BufSize]; - while (size_t size = fread(buf, 1, BufSize, ffrom)) { - fwrite(buf, 1, size, fto); - } struct stat fst; // from http://stackoverflow.com/questions/5486774/keeping-fileowner-and-permissions-after-copying-file-in-c //let's say this wont fail since you already worked OK on that fp @@ -110,6 +105,21 @@ bool copyFile(const char *from, const char *to) { fclose(fto); return false; } + + ssize_t copied = sendfile( + fileno(ffrom), + fileno(fto), + nullptr, + fst.st_size); + + if (copied == -1) { + static const int BufSize = 65536; + char buf[BufSize]; + while (size_t size = fread(buf, 1, BufSize, ffrom)) { + fwrite(buf, 1, size, fto); + } + } + //update to the same uid/gid if (fchown(fileno(fto), fst.st_uid, fst.st_gid) != 0) { fclose(ffrom); diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp index 32b0a150d9..43e523f599 100644 --- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp @@ -1022,11 +1022,6 @@ bool linuxMoveFile(const char *from, const char *to) { fclose(ffrom); return false; } - static const int BufSize = 65536; - char buf[BufSize]; - while (size_t size = fread(buf, 1, BufSize, ffrom)) { - fwrite(buf, 1, size, fto); - } struct stat fst; // from http://stackoverflow.com/questions/5486774/keeping-fileowner-and-permissions-after-copying-file-in-c //let's say this wont fail since you already worked OK on that fp @@ -1035,6 +1030,24 @@ bool linuxMoveFile(const char *from, const char *to) { fclose(fto); return false; } + + ssize_t copied = -1; +#ifdef Q_OS_LINUX + copied = sendfile( + fileno(ffrom), + fileno(fto), + nullptr, + fst.st_size); +#endif // Q_OS_LINUX + + if (copied == -1) { + static const int BufSize = 65536; + char buf[BufSize]; + while (size_t size = fread(buf, 1, BufSize, ffrom)) { + fwrite(buf, 1, size, fto); + } + } + //update to the same uid/gid if (fchown(fileno(fto), fst.st_uid, fst.st_gid) != 0) { fclose(ffrom);