From ced744549a1795c0b7cc4e8a1f7f705b528da936 Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 20 Jan 2025 10:52:43 -0500 Subject: [PATCH 1/7] Advise porter on where to make necessary change. In #1075 the change was already made for BSD (thank you!); my working edit had this guidance to ensure future porters get an error directing them where to make a necessary change. Otherwise, the FoundationEssentials build will fail and complain these variables are not defined but not have guidance as to where they are sourced from. --- Sources/_FoundationCShims/include/_CStdlib.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/_FoundationCShims/include/_CStdlib.h b/Sources/_FoundationCShims/include/_CStdlib.h index 6aba41be3..405febca9 100644 --- a/Sources/_FoundationCShims/include/_CStdlib.h +++ b/Sources/_FoundationCShims/include/_CStdlib.h @@ -156,6 +156,10 @@ #ifndef TZDEFAULT #define TZDEFAULT "/etc/localtime" #endif /* !defined TZDEFAULT */ +#elif TARGET_OS_WINDOWS +/* not required */ +#else +#error "possibly define TZDIR and TZDEFAULT for this platform" #endif /* TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD */ #endif From 73c398931971053abc003122944a3b19cc152166 Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 20 Jan 2025 11:01:50 -0500 Subject: [PATCH 2/7] OpenBSD does not support extended attributes. --- Sources/FoundationEssentials/Data/Data+Reading.swift | 2 ++ Sources/FoundationEssentials/Data/Data+Writing.swift | 2 ++ .../FileManager/FileManager+Directories.swift | 2 +- .../FileManager/FileManager+Files.swift | 6 +++--- .../FileManager/FileManager+Utilities.swift | 2 +- .../FoundationEssentials/FileManager/FileOperations.swift | 4 ++-- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Sources/FoundationEssentials/Data/Data+Reading.swift b/Sources/FoundationEssentials/Data/Data+Reading.swift index 39c50e5d6..b6803f738 100644 --- a/Sources/FoundationEssentials/Data/Data+Reading.swift +++ b/Sources/FoundationEssentials/Data/Data+Reading.swift @@ -40,6 +40,8 @@ func _fgetxattr(_ fd: Int32, _ name: UnsafePointer!, _ value: UnsafeMutab return fgetxattr(fd, name, value, size, position, options) #elseif os(FreeBSD) return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, name, value, size) +#elseif os(OpenBSD) + return -1 #elseif canImport(Glibc) || canImport(Musl) || canImport(Android) return fgetxattr(fd, name, value, size) #else diff --git a/Sources/FoundationEssentials/Data/Data+Writing.swift b/Sources/FoundationEssentials/Data/Data+Writing.swift index 657f2ae2e..af49745d6 100644 --- a/Sources/FoundationEssentials/Data/Data+Writing.swift +++ b/Sources/FoundationEssentials/Data/Data+Writing.swift @@ -639,6 +639,8 @@ private func writeExtendedAttributes(fd: Int32, attributes: [String : Data]) { _ = fsetxattr(fd, key, valueBuf.baseAddress!, valueBuf.count, 0, 0) #elseif os(FreeBSD) _ = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, key, valueBuf.baseAddress!, valueBuf.count) +#elseif os(OpenBSD) + return #elseif canImport(Glibc) || canImport(Musl) _ = fsetxattr(fd, key, valueBuf.baseAddress!, valueBuf.count, 0) #endif diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Directories.swift b/Sources/FoundationEssentials/FileManager/FileManager+Directories.swift index 41bb83eb0..4371f24ad 100644 --- a/Sources/FoundationEssentials/FileManager/FileManager+Directories.swift +++ b/Sources/FoundationEssentials/FileManager/FileManager+Directories.swift @@ -201,7 +201,7 @@ extension _FileManagerImpl { } } return results -#elseif os(WASI) +#elseif os(WASI) || os(OpenBSD) // wasi-libc does not support FTS for now throw CocoaError.errorWithFilePath(.featureUnsupported, path) #else diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift index 8f0083f04..5edb5377e 100644 --- a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift +++ b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift @@ -485,7 +485,7 @@ extension _FileManagerImpl { #endif } -#if !os(Windows) && !os(WASI) +#if !os(Windows) && !os(WASI) && !os(OpenBSD) private func _extendedAttribute(_ key: UnsafePointer, at path: UnsafePointer, followSymlinks: Bool) throws -> Data? { #if canImport(Darwin) var size = getxattr(path, key, nil, 0, 0, followSymlinks ? 0 : XATTR_NOFOLLOW) @@ -647,7 +647,7 @@ extension _FileManagerImpl { var attributes = statAtPath.fileAttributes try? Self._catInfo(for: URL(filePath: path, directoryHint: .isDirectory), statInfo: statAtPath, into: &attributes) - #if !os(WASI) // WASI does not support extended attributes + #if !os(WASI) && !os(OpenBSD) if let extendedAttrs = try? _extendedAttributes(at: fsRep, followSymlinks: false) { attributes[._extendedAttributes] = extendedAttrs } @@ -950,7 +950,7 @@ extension _FileManagerImpl { try Self._setCatInfoAttributes(attributes, path: path) if let extendedAttrs = attributes[.init("NSFileExtendedAttributes")] as? [String : Data] { - #if os(WASI) + #if os(WASI) || os(OpenBSD) // WASI does not support extended attributes throw CocoaError.errorWithFilePath(.featureUnsupported, path) #elseif canImport(Android) diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift b/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift index d2e54be75..d882a67bb 100644 --- a/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift +++ b/Sources/FoundationEssentials/FileManager/FileManager+Utilities.swift @@ -178,7 +178,7 @@ extension _FileManagerImpl { #endif } -#if !os(Windows) && !os(WASI) +#if !os(Windows) && !os(WASI) && !os(OpenBSD) static func _setAttribute(_ key: UnsafePointer, value: Data, at path: UnsafePointer, followSymLinks: Bool) throws { try value.withUnsafeBytes { buffer in #if canImport(Darwin) diff --git a/Sources/FoundationEssentials/FileManager/FileOperations.swift b/Sources/FoundationEssentials/FileManager/FileOperations.swift index 660d19b9a..b0c243055 100644 --- a/Sources/FoundationEssentials/FileManager/FileOperations.swift +++ b/Sources/FoundationEssentials/FileManager/FileOperations.swift @@ -921,7 +921,7 @@ enum _FileOperations { } var current: off_t = 0 - #if os(WASI) + #if os(WASI) || os(OpenBSD) // 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 { @@ -958,7 +958,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) + #if !os(WASI) && !os(Android) && !os(OpenBSD) // Copy extended attributes #if os(FreeBSD) // FreeBSD uses the `extattr_*` calls for setting extended attributes. Unlike like, the namespace for the extattrs are not determined by prefix of the attribute From 2baef81bc6d6cacb88b86381090e8aeea0ab78aa Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 20 Jan 2025 11:14:56 -0500 Subject: [PATCH 3/7] OpenBSD does not have secure_getenv. --- Sources/FoundationEssentials/Platform.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/FoundationEssentials/Platform.swift b/Sources/FoundationEssentials/Platform.swift index 5177da6ca..1e39051b8 100644 --- a/Sources/FoundationEssentials/Platform.swift +++ b/Sources/FoundationEssentials/Platform.swift @@ -224,7 +224,7 @@ extension Platform { // MARK: - Environment Variables extension Platform { static func getEnvSecure(_ name: String) -> String? { - #if canImport(Glibc) + #if canImport(Glibc) && !os(OpenBSD) if let value = secure_getenv(name) { return String(cString: value) } else { From c9d099bf6df7c0a4d9e14138e24858cf0464d065 Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 20 Jan 2025 11:25:30 -0500 Subject: [PATCH 4/7] Remaining OpenBSD changes. * OpenBSD also needs `pthread_mutex_t?`. * Originally I followed Darwin's check with `d_namlen`, but this should work too. --- .../FileManager/FileOperations+Enumeration.swift | 4 +++- Sources/FoundationEssentials/LockedState.swift | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Sources/FoundationEssentials/FileManager/FileOperations+Enumeration.swift b/Sources/FoundationEssentials/FileManager/FileOperations+Enumeration.swift index dc9eff2eb..1d497f8c4 100644 --- a/Sources/FoundationEssentials/FileManager/FileOperations+Enumeration.swift +++ b/Sources/FoundationEssentials/FileManager/FileOperations+Enumeration.swift @@ -354,7 +354,8 @@ struct _POSIXDirectoryContentsSequence: Sequence { continue } #endif - #if os(FreeBSD) + + #if os(FreeBSD) || os(OpenBSD) guard dent.pointee.d_fileno != 0 else { continue } @@ -363,6 +364,7 @@ struct _POSIXDirectoryContentsSequence: Sequence { continue } #endif + // Use name let fileName: String #if os(WASI) diff --git a/Sources/FoundationEssentials/LockedState.swift b/Sources/FoundationEssentials/LockedState.swift index cf9d89b8f..2316fb955 100644 --- a/Sources/FoundationEssentials/LockedState.swift +++ b/Sources/FoundationEssentials/LockedState.swift @@ -31,7 +31,7 @@ package struct LockedState { private struct _Lock { #if canImport(os) typealias Primitive = os_unfair_lock -#elseif os(FreeBSD) +#elseif os(FreeBSD) || os(OpenBSD) typealias Primitive = pthread_mutex_t? #elseif canImport(Bionic) || canImport(Glibc) || canImport(Musl) typealias Primitive = pthread_mutex_t From 2e8a03da479356fa281423510860a017a384045a Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 20 Jan 2025 13:14:55 -0500 Subject: [PATCH 5/7] Correct statvfs type casts for OpenBSD. On OpenBSD, fsblkcnt_t -- the type of f_blocks -- is a UInt64; therefore, so must `blockSize` be. Ultimately, both sides of the `totalSizeBytes` multiplication should probably be type cast for all platforms, but that's a more significant functional change for another time. --- .../FoundationEssentials/FileManager/FileManager+Files.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift index 5edb5377e..118712a64 100644 --- a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift +++ b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift @@ -736,6 +736,9 @@ extension _FileManagerImpl { #if canImport(Darwin) let fsNumber = result.f_fsid.val.0 let blockSize = UInt64(result.f_bsize) + #elseif os(OpenBSD) + let fsNumber = result.f_fsid + let blockSize = UInt64(result.f_bsize) #else let fsNumber = result.f_fsid let blockSize = UInt(result.f_frsize) From 35b9684918ba2da982f933eb4618e382ba74a26d Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Mon, 24 Mar 2025 20:56:54 -0400 Subject: [PATCH 6/7] Default activeProcessorCount to 1, not 0. After a rather tedious debugging session trying to figure out why swiftpm-bootstrap appeared to be deadlocked, this turned out to be the culprit. Perhaps this should be #error instead, but for now, set a sensible default. --- Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift b/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift index 6db2b3c9d..7e3179e93 100644 --- a/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift +++ b/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift @@ -481,7 +481,7 @@ extension _ProcessInfo { GetSystemInfo(&sysInfo) return sysInfo.dwActiveProcessorMask.nonzeroBitCount #else - return 0 + return 1 #endif } From 6ad8d460034e9626485eebe800474e64cbd2cdcf Mon Sep 17 00:00:00 2001 From: 3405691582 Date: Sat, 29 Mar 2025 17:43:19 -0400 Subject: [PATCH 7/7] Use sysconf for activeProcessorCount. This is what Dispatch does in some places for OpenBSD anyway, so do likewise here. --- Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift b/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift index 7e3179e93..1caa04bfb 100644 --- a/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift +++ b/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift @@ -469,7 +469,7 @@ extension _ProcessInfo { return 0 } return Int(count) -#elseif os(Linux) || os(FreeBSD) || canImport(Android) +#elseif os(Linux) || os(FreeBSD) || os(OpenBSD) || canImport(Android) #if os(Linux) if let fsCount = Self.fsCoreCount() { return fsCount