Skip to content

Commit 5ed6c72

Browse files
authored
[FreeBSD] Fix FreeBSD build/support (#1075)
* FreeBSD platform specific fixes - Use "/usr/share/zoneinfo" - Use platform specific types and values - Implement extattr ops for FreeBSD - Use copy_file_range(2) for file cloning * Revise patch to ProcessInfo to reduce potential impact to other platforms * Fix macOS build * typo * take suggested change
1 parent 37fcb35 commit 5ed6c72

File tree

10 files changed

+44
-5
lines changed

10 files changed

+44
-5
lines changed

Sources/FoundationEssentials/Data/Data+Reading.swift

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import WASILibc
3434
func _fgetxattr(_ fd: Int32, _ name: UnsafePointer<CChar>!, _ value: UnsafeMutableRawPointer!, _ size: Int, _ position: UInt32, _ options: Int32) -> Int {
3535
#if canImport(Darwin)
3636
return fgetxattr(fd, name, value, size, position, options)
37+
#elseif os(FreeBSD)
38+
return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, name, value, size)
3739
#elseif canImport(Glibc) || canImport(Musl) || canImport(Android)
3840
return fgetxattr(fd, name, value, size)
3941
#else

Sources/FoundationEssentials/Data/Data+Writing.swift

+2
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,8 @@ private func writeExtendedAttributes(fd: Int32, attributes: [String : Data]) {
610610
// Returns non-zero on error, but we ignore them
611611
#if canImport(Darwin)
612612
_ = fsetxattr(fd, key, valueBuf.baseAddress!, valueBuf.count, 0, 0)
613+
#elseif os(FreeBSD)
614+
_ = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, key, valueBuf.baseAddress!, valueBuf.count)
613615
#elseif canImport(Glibc) || canImport(Musl)
614616
_ = fsetxattr(fd, key, valueBuf.baseAddress!, valueBuf.count, 0)
615617
#endif

Sources/FoundationEssentials/Error/ErrorCodes+POSIX.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ extension POSIXError {
623623
return .EMULTIHOP
624624
}
625625

626-
#if !os(WASI)
626+
#if !os(WASI) && !os(FreeBSD)
627627
/// No message available on STREAM.
628628
public static var ENODATA: POSIXErrorCode {
629629
return .ENODATA
@@ -635,7 +635,7 @@ extension POSIXError {
635635
return .ENOLINK
636636
}
637637

638-
#if !os(WASI)
638+
#if !os(WASI) && !os(FreeBSD)
639639
/// No STREAM resources.
640640
public static var ENOSR: POSIXErrorCode {
641641
return .ENOSR
@@ -653,7 +653,7 @@ extension POSIXError {
653653
return .EPROTO
654654
}
655655

656-
#if !os(OpenBSD) && !os(WASI)
656+
#if !os(OpenBSD) && !os(WASI) && !os(FreeBSD)
657657
/// STREAM ioctl timeout.
658658
public static var ETIME: POSIXErrorCode {
659659
return .ETIME

Sources/FoundationEssentials/FileManager/FileManager+Files.swift

+8
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ extension _FileManagerImpl {
486486
private func _extendedAttribute(_ key: UnsafePointer<CChar>, at path: UnsafePointer<CChar>, followSymlinks: Bool) throws -> Data? {
487487
#if canImport(Darwin)
488488
var size = getxattr(path, key, nil, 0, 0, followSymlinks ? 0 : XATTR_NOFOLLOW)
489+
#elseif os(FreeBSD)
490+
var size = (followSymlinks ? extattr_get_file : extattr_get_link)(path, EXTATTR_NAMESPACE_USER, key, nil, 0)
489491
#else
490492
var size = followSymlinks ? getxattr(path, key, nil, 0) : lgetxattr(path, key, nil, 0)
491493
#endif
@@ -498,6 +500,8 @@ extension _FileManagerImpl {
498500
let buffer = malloc(size)!
499501
#if canImport(Darwin)
500502
size = getxattr(path, key, buffer, size, 0, followSymlinks ? 0 : XATTR_NOFOLLOW)
503+
#elseif os(FreeBSD)
504+
size = (followSymlinks ? extattr_get_file : extattr_get_link)(path, EXTATTR_NAMESPACE_USER, key, buffer, size)
501505
#else
502506
size = followSymlinks ? getxattr(path, key, buffer, size) : lgetxattr(path, key, buffer, size)
503507
#endif
@@ -516,6 +520,8 @@ extension _FileManagerImpl {
516520
private func _extendedAttributes(at path: UnsafePointer<CChar>, followSymlinks: Bool) throws -> [String : Data]? {
517521
#if canImport(Darwin)
518522
var size = listxattr(path, nil, 0, 0)
523+
#elseif os(FreeBSD)
524+
var size = (followSymlinks ? extattr_list_file : extattr_list_link)(path, EXTATTR_NAMESPACE_USER, nil, 0)
519525
#else
520526
var size = listxattr(path, nil, 0)
521527
#endif
@@ -524,6 +530,8 @@ extension _FileManagerImpl {
524530
defer { keyList.deallocate() }
525531
#if canImport(Darwin)
526532
size = listxattr(path, keyList.baseAddress!, size, 0)
533+
#elseif os(FreeBSD)
534+
size = (followSymlinks ? extattr_list_file : extattr_list_link)(path, EXTATTR_NAMESPACE_USER, nil, 0)
527535
#else
528536
size = listxattr(path, keyList.baseAddress!, size)
529537
#endif

Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift

+8
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,13 @@ extension _FileManagerImpl {
183183
try value.withUnsafeBytes { buffer in
184184
#if canImport(Darwin)
185185
let result = setxattr(path, key, buffer.baseAddress!, buffer.count, 0, followSymLinks ? 0 : XATTR_NOFOLLOW)
186+
#elseif os(FreeBSD)
187+
var result: Int32
188+
if followSymLinks {
189+
result = Int32(extattr_set_file(path, EXTATTR_NAMESPACE_USER, key, buffer.baseAddress!, buffer.count))
190+
} else {
191+
result = Int32(extattr_set_link(path, EXTATTR_NAMESPACE_USER, key, buffer.baseAddress!, buffer.count))
192+
}
186193
#else
187194
var result: Int32
188195
if followSymLinks {
@@ -191,6 +198,7 @@ extension _FileManagerImpl {
191198
result = setxattr(path, key, buffer.baseAddress!, buffer.count, 0)
192199
}
193200
#endif
201+
194202
#if os(macOS) && FOUNDATION_FRAMEWORK
195203
// if setxaddr failed and its a permission error for a sandbox app trying to set quaratine attribute, ignore it since its not
196204
// permitted, the attribute will be put on the file by the quaratine MAC hook

Sources/FoundationEssentials/FileManager/FileOperations+Enumeration.swift

+6
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,15 @@ struct _POSIXDirectoryContentsSequence: Sequence {
354354
continue
355355
}
356356
#endif
357+
#if os(FreeBSD)
358+
guard dent.pointee.d_fileno != 0 else {
359+
continue
360+
}
361+
#else
357362
guard dent.pointee.d_ino != 0 else {
358363
continue
359364
}
365+
#endif
360366
// Use name
361367
let fileName: String
362368
#if os(WASI)

Sources/FoundationEssentials/FileManager/FileOperations.swift

+7
Original file line numberDiff line numberDiff line change
@@ -940,10 +940,17 @@ enum _FileOperations {
940940
}
941941
#else
942942
while current < total {
943+
#if os(FreeBSD)
944+
guard copy_file_range(srcfd, &current, dstfd, nil, total - Int(current), 0) != -1 else {
945+
try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr))
946+
return
947+
}
948+
#else
943949
guard sendfile(dstfd, srcfd, &current, Swift.min(total - Int(current), chunkSize)) != -1 else {
944950
try delegate.throwIfNecessary(errno, String(cString: srcPtr), String(cString: dstPtr))
945951
return
946952
}
953+
#endif
947954
}
948955
#endif
949956
}

Sources/FoundationEssentials/LockedState.swift

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ package struct LockedState<State> {
3131
private struct _Lock {
3232
#if canImport(os)
3333
typealias Primitive = os_unfair_lock
34+
#elseif os(FreeBSD)
35+
typealias Primitive = pthread_mutex_t?
3436
#elseif canImport(Bionic) || canImport(Glibc) || canImport(Musl)
3537
typealias Primitive = pthread_mutex_t
3638
#elseif canImport(WinSDK)

Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift

+4
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ final class _ProcessInfo: Sendable {
142142
let time: UInt64 = ullTime
143143
#else
144144
var ts: timespec = timespec()
145+
#if os(FreeBSD) || os(OpenBSD)
146+
clock_gettime(CLOCK_MONOTONIC, &ts)
147+
#else
145148
clock_gettime(CLOCK_MONOTONIC_RAW, &ts)
149+
#endif
146150
let time: UInt64 = UInt64(ts.tv_sec) * 1000000000 + UInt64(ts.tv_nsec)
147151
#endif
148152
let timeString = String(time, radix: 16, uppercase: true)

Sources/_FoundationCShims/include/_CStdlib.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,15 @@
148148
#include <tzfile.h>
149149
#else
150150

151-
#if TARGET_OS_MAC || TARGET_OS_LINUX
151+
#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD
152152
#ifndef TZDIR
153153
#define TZDIR "/usr/share/zoneinfo/" /* Time zone object file directory */
154154
#endif /* !defined TZDIR */
155155

156156
#ifndef TZDEFAULT
157157
#define TZDEFAULT "/etc/localtime"
158158
#endif /* !defined TZDEFAULT */
159-
#endif /* TARGET_OS_MAC || TARGET_OS_LINUX */
159+
#endif /* TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD */
160160

161161
#endif
162162

0 commit comments

Comments
 (0)