diff --git a/io/copy.h b/io/copy.h index 134484b..d8441fb 100644 --- a/io/copy.h +++ b/io/copy.h @@ -114,9 +114,13 @@ template void CopyHelper::copy(NativeFileSt while (count) { const auto bytesCopied = ::sendfile64(output.fileDescriptor(), input.fileDescriptor(), nullptr, count); if (bytesCopied < 0) { + if (errno == EINVAL && static_cast(totalBytes) == count) { + // try again the unoptimized version, maybe the filesystem doesn't support sendfile + goto unoptimized_version; + } throw std::ios_base::failure(argsToString("sendfile64() failed: ", std::strerror(errno))); } - count -= static_cast(bytesCopied); + count -= static_cast(bytesCopied); } input.sync(); output.sync(); @@ -126,6 +130,7 @@ template void CopyHelper::copy(NativeFileSt input.seekp(inputTellp + totalBytes); return; } +unoptimized_version: #endif copy(static_cast(input), static_cast(output), count); } @@ -158,6 +163,10 @@ void CopyHelper::callbackCopy(NativeFileStream &input, NativeFileStr const auto bytesToCopy = static_cast(std::min(count, static_cast(bufferSize))); const auto bytesCopied = ::sendfile64(output.fileDescriptor(), input.fileDescriptor(), nullptr, bytesToCopy); if (bytesCopied < 0) { + if (errno == EINVAL && static_cast(totalBytes) == count) { + // try again the unoptimized version, maybe the filesystem doesn't support sendfile + goto unoptimized_version; + } throw std::ios_base::failure(argsToString("sendfile64() failed: ", std::strerror(errno))); } count -= static_cast(bytesCopied); @@ -175,6 +184,7 @@ void CopyHelper::callbackCopy(NativeFileStream &input, NativeFileStr callback(1.0); return; } +unoptimized_version: #endif callbackCopy(static_cast(input), static_cast(output), count, isAborted, callback); }