fs/linux: fix potential copy_file issue

sendfile is meant to be run in a loop, since there is no guarantee that a single call copies all the data.
The current implementation may lead to corrupt files on linux.
This commit is contained in:
Megamouse 2023-06-09 00:09:08 +02:00 committed by Ivan
parent 5d7e75c5d8
commit 635fed0427

View File

@ -835,9 +835,20 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit
if (::fcopyfile(input, output, 0, COPYFILE_ALL))
#elif defined(__linux__) || defined(__sun)
// sendfile will work with non-socket output (i.e. regular file) on Linux 2.6.33+
off_t bytes_copied = 0;
struct ::stat fileinfo = { 0 };
if (::fstat(input, &fileinfo) == -1 || ::sendfile(output, input, &bytes_copied, fileinfo.st_size) == -1)
bool result = ::fstat(input, &fileinfo) != -1;
if (result)
{
for (off_t bytes_copied = 0; bytes_copied < fileinfo.st_size; /* Do nothing, bytes_copied is increased by sendfile. */)
{
if (::sendfile(output, input, &bytes_copied, fileinfo.st_size - bytes_copied) == -1)
{
result = false;
break;
}
}
}
if (!result)
#else
#error "Native file copy implementation is missing"
#endif