Skip to content

Commit 779e11a

Browse files
kateinoigakukunMaxDesiatov
authored andcommitted
Implement _copyRegularFile for WASI without sendfile (#787)
WASI doesn't have `sendfile`, so we need to implement the copy in user space with `read` and `write`. It's not as efficient as `sendfile`, but it's the best we can do. (cherry picked from commit 2a6afeb)
1 parent 05fc5eb commit 779e11a

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

Sources/FoundationEssentials/FileManager/FileOperations.swift

+19
Original file line numberDiff line numberDiff line change
@@ -873,12 +873,31 @@ enum _FileOperations {
873873
let chunkSize: Int = Int(fileInfo.st_blksize)
874874
var current: off_t = 0
875875

876+
#if os(WASI)
877+
// WASI doesn't have sendfile, so we need to do it in user space with read/write
878+
try withUnsafeTemporaryAllocation(of: UInt8.self, capacity: chunkSize) { buffer in
879+
while current < total {
880+
let readSize = Swift.min(total - Int(current), chunkSize)
881+
let bytesRead = read(srcfd, buffer.baseAddress, readSize)
882+
guard bytesRead >= 0 else {
883+
try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr))
884+
return
885+
}
886+
guard write(dstfd, buffer.baseAddress, bytesRead) == bytesRead else {
887+
try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr))
888+
return
889+
}
890+
current += off_t(bytesRead)
891+
}
892+
}
893+
#else
876894
while current < total {
877895
guard sendfile(dstfd, srcfd, &current, Swift.min(total - Int(current), chunkSize)) != -1 else {
878896
try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr))
879897
return
880898
}
881899
}
900+
#endif
882901
}
883902
#endif
884903

0 commit comments

Comments
 (0)