Skip to content

Commit

Permalink
[6.1] Fix WASI build of _copyDirectoryMetadata (#1099)
Browse files Browse the repository at this point in the history
* Fix WASI build of `_copyDirectoryMetadata` (#1094)

Extended attributes don't exist in WASI, so we need to exclude the use
of xattr-related APIs including `flistxattr`.

* Follow-up fixes to make it work with wasi-libc (#1095)

* Gate `fchown` and `fchmod` calls behind `os(WASI)`

They are not available on WASI, so we gate them behind `os(WASI)`.

* Add missing constant shims for wasi-libc

* Use `futimens` instead of legacy `futimes`

wasi-libc does not provide `futimes` as it is a legacy function.
https://github.com/WebAssembly/wasi-libc/blob/574b88da481569b65a237cb80daf9a2d5aeaf82d/libc-top-half/musl/include/sys/time.h#L34

* Don't try to set extended attributes on Android (#1106)

Normal users don't have permission to change these, even for their own files.

---------

Co-authored-by: finagolfin <[email protected]>
  • Loading branch information
kateinoigakukun and finagolfin authored Jan 3, 2025
1 parent ca7070f commit bca2f46
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
12 changes: 9 additions & 3 deletions Sources/FoundationEssentials/FileManager/FileOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,7 @@ enum _FileOperations {

#if !canImport(Darwin)
private static func _copyDirectoryMetadata(srcFD: CInt, srcPath: @autoclosure () -> String, dstFD: CInt, dstPath: @autoclosure () -> String, delegate: some LinkOrCopyDelegate) throws {
#if !os(WASI) && !os(Android)
// Copy extended attributes
var size = flistxattr(srcFD, nil, 0)
if size > 0 {
Expand All @@ -936,28 +937,33 @@ enum _FileOperations {
}
}
}
#endif
var statInfo = stat()
if fstat(srcFD, &statInfo) == 0 {
#if !os(WASI) // WASI doesn't have fchown for now
// Copy owner/group
if fchown(dstFD, statInfo.st_uid, statInfo.st_gid) != 0 {
try delegate.throwIfNecessary(errno, srcPath(), dstPath())
}
#endif

// Copy modification date
let value = timeval(tv_sec: statInfo.st_mtim.tv_sec, tv_usec: statInfo.st_mtim.tv_nsec / 1000)
let value = statInfo.st_mtim
var tv = (value, value)
try withUnsafePointer(to: &tv) {
try $0.withMemoryRebound(to: timeval.self, capacity: 2) {
if futimes(dstFD, $0) != 0 {
try $0.withMemoryRebound(to: timespec.self, capacity: 2) {
if futimens(dstFD, $0) != 0 {
try delegate.throwIfNecessary(errno, srcPath(), dstPath())
}
}
}

#if !os(WASI) // WASI doesn't have fchmod for now
// Copy permissions
if fchmod(dstFD, statInfo.st_mode) != 0 {
try delegate.throwIfNecessary(errno, srcPath(), dstPath())
}
#endif
} else {
try delegate.throwIfNecessary(errno, srcPath(), dstPath())
}
Expand Down
9 changes: 9 additions & 0 deletions Sources/FoundationEssentials/WASILibc+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,14 @@ internal var O_TRUNC: Int32 {
internal var O_WRONLY: Int32 {
return _platform_shims_O_WRONLY()
}
internal var O_RDONLY: Int32 {
return _platform_shims_O_RDONLY()
}
internal var O_DIRECTORY: Int32 {
return _platform_shims_O_DIRECTORY()
}
internal var O_NOFOLLOW: Int32 {
return _platform_shims_O_NOFOLLOW()
}

#endif // os(WASI)
4 changes: 4 additions & 0 deletions Sources/_FoundationCShims/include/platform_shims.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ static inline int32_t _platform_shims_O_CREAT(void) { return O_CREAT; }
static inline int32_t _platform_shims_O_EXCL(void) { return O_EXCL; }
static inline int32_t _platform_shims_O_TRUNC(void) { return O_TRUNC; }
static inline int32_t _platform_shims_O_WRONLY(void) { return O_WRONLY; }
static inline int32_t _platform_shims_O_RDONLY(void) { return O_RDONLY; }
static inline int32_t _platform_shims_O_DIRECTORY(void) { return O_DIRECTORY; }
static inline int32_t _platform_shims_O_NOFOLLOW(void) { return O_NOFOLLOW; }

#endif

#endif /* CSHIMS_PLATFORM_SHIMS */

0 comments on commit bca2f46

Please sign in to comment.