@@ -512,7 +512,14 @@ enum _FileOperations {
512
512
// We failed for a reason other than the directory not being empty, so throw
513
513
throw CocoaError . removeFileError ( errno, resolve ( path: pathStr) )
514
514
}
515
-
515
+
516
+ #if os(WASI)
517
+
518
+ // wasi-libc does not support FTS, so we don't support removing non-empty directories on WASI for now.
519
+ throw CocoaError ( . featureUnsupported)
520
+
521
+ #else
522
+
516
523
let seq = _FTSSequence ( path, FTS_PHYSICAL | FTS_XDEV | FTS_NOCHDIR | FTS_NOSTAT)
517
524
let iterator = seq. makeIterator ( )
518
525
var isFirst = true
@@ -561,6 +568,7 @@ enum _FileOperations {
561
568
}
562
569
}
563
570
}
571
+ #endif
564
572
565
573
}
566
574
#endif
@@ -903,6 +911,43 @@ enum _FileOperations {
903
911
}
904
912
#endif
905
913
914
+ #if os(WASI)
915
+ private static func _linkOrCopyFile( _ srcPtr: UnsafePointer < CChar > , _ dstPtr: UnsafePointer < CChar > , with fileManager: FileManager , delegate: some LinkOrCopyDelegate ) throws {
916
+ var stat = stat ( )
917
+ guard lstat ( srcPtr, & stat) == 0 , !stat. isDirectory else {
918
+ // wasi-libc does not support FTS for now, so we don't support copying/linking
919
+ // directories on WASI for now.
920
+ throw CocoaError ( . featureUnsupported)
921
+ }
922
+
923
+ // For now, we support only copying regular files and symlinks.
924
+ // After we get FTS support (https://github.com/WebAssembly/wasi-libc/pull/522),
925
+ // we can remove this method and use the below FTS-based implementation.
926
+ let src = String ( cString: srcPtr)
927
+ let dst = String ( cString: dstPtr)
928
+ guard delegate. shouldPerformOnItemAtPath ( src, to: dst) else { return }
929
+
930
+ if stat. isSymbolicLink {
931
+ try withUnsafeTemporaryAllocation ( of: CChar . self, capacity: FileManager . MAX_PATH_SIZE) { tempBuff in
932
+ tempBuff. initialize ( repeating: 0 )
933
+ defer { tempBuff. deinitialize ( ) }
934
+ let len = readlink ( srcPtr, tempBuff. baseAddress!, FileManager . MAX_PATH_SIZE - 1 )
935
+ if len >= 0 , symlink ( tempBuff. baseAddress!, dstPtr) != - 1 {
936
+ return
937
+ }
938
+ try delegate. throwIfNecessary ( errno, src, dst)
939
+ }
940
+ } else {
941
+ if delegate. copyData {
942
+ try _copyRegularFile ( srcPtr, dstPtr, delegate: delegate)
943
+ } else {
944
+ if link ( srcPtr, dstPtr) != 0 {
945
+ try delegate. throwIfNecessary ( errno, src, dst)
946
+ }
947
+ }
948
+ }
949
+ }
950
+ #else
906
951
private static func _linkOrCopyFile( _ srcPtr: UnsafePointer < CChar > , _ dstPtr: UnsafePointer < CChar > , with fileManager: FileManager , delegate: some LinkOrCopyDelegate ) throws {
907
952
try withUnsafeTemporaryAllocation ( of: CChar . self, capacity: FileManager . MAX_PATH_SIZE) { buffer in
908
953
let dstLen = Platform . copyCString ( dst: buffer. baseAddress!, src: dstPtr, size: FileManager . MAX_PATH_SIZE)
@@ -1015,6 +1060,7 @@ enum _FileOperations {
1015
1060
}
1016
1061
}
1017
1062
}
1063
+ #endif
1018
1064
1019
1065
private static func linkOrCopyFile( _ src: String , dst: String , with fileManager: FileManager , delegate: some LinkOrCopyDelegate ) throws {
1020
1066
try src. withFileSystemRepresentation { srcPtr in
0 commit comments