diff --git a/Sources/FoundationEssentials/FileManager/FileOperations.swift b/Sources/FoundationEssentials/FileManager/FileOperations.swift index 8e67a771f..9596cc604 100644 --- a/Sources/FoundationEssentials/FileManager/FileOperations.swift +++ b/Sources/FoundationEssentials/FileManager/FileOperations.swift @@ -871,12 +871,31 @@ enum _FileOperations { let chunkSize: Int = Int(fileInfo.st_blksize) var current: off_t = 0 + #if os(WASI) + // WASI doesn't have sendfile, so we need to do it in user space with read/write + try withUnsafeTemporaryAllocation(of: UInt8.self, capacity: chunkSize) { buffer in + while current < total { + let readSize = Swift.min(total - Int(current), chunkSize) + let bytesRead = read(srcfd, buffer.baseAddress, readSize) + guard bytesRead >= 0 else { + try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr)) + return + } + guard write(dstfd, buffer.baseAddress, bytesRead) == bytesRead else { + try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr)) + return + } + current += off_t(bytesRead) + } + } + #else while current < total { guard sendfile(dstfd, srcfd, ¤t, Swift.min(total - Int(current), chunkSize)) != -1 else { try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr)) return } } + #endif } #endif