From 7c0af0ded6c096e69f4d26af712ee185223413d8 Mon Sep 17 00:00:00 2001 From: Kenta Kubo <601636+kkebo@users.noreply.github.com> Date: Wed, 28 Jan 2026 00:02:14 +0900 Subject: [PATCH 1/5] Fix FreeBSD build --- Sources/System/Internals/Constants.swift | 5 ++++- Tests/SystemTests/StatTests.swift | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Sources/System/Internals/Constants.swift b/Sources/System/Internals/Constants.swift index 3e71ec90..32665612 100644 --- a/Sources/System/Internals/Constants.swift +++ b/Sources/System/Internals/Constants.swift @@ -692,9 +692,12 @@ internal var _S_IFLNK: mode_t { S_IFLNK } @_alwaysEmitIntoClient internal var _S_IFSOCK: mode_t { S_IFSOCK } -#if SYSTEM_PACKAGE_DARWIN || os(FreeBSD) +#if SYSTEM_PACKAGE_DARWIN @_alwaysEmitIntoClient internal var _S_IFWHT: mode_t { S_IFWHT } +#elseif os(FreeBSD) +@_alwaysEmitIntoClient +internal var _S_IFWHT: mode_t { .init(S_IFWHT) } #endif // MARK: - stat/chflags File Flags diff --git a/Tests/SystemTests/StatTests.swift b/Tests/SystemTests/StatTests.swift index 524226d2..d10d926b 100644 --- a/Tests/SystemTests/StatTests.swift +++ b/Tests/SystemTests/StatTests.swift @@ -118,7 +118,11 @@ private struct StatTests { #expect(targetStat.type == .regular) #expect(symlinkStat.type == .symbolicLink) #expect(symlinkStat.size < targetStat.size) + #if os(FreeBSD) + #expect(symlinkStat.sizeAllocated <= targetStat.sizeAllocated) + #else #expect(symlinkStat.sizeAllocated < targetStat.sizeAllocated) + #endif // Set each .st_atim back to its original value for comparison @@ -368,14 +372,11 @@ private struct StatTests { ] #elseif os(FreeBSD) let userSettableFlags: FileFlags = [ - .noDump, .userImmutable, .userAppend, - .opaque, .tracked, .hidden, - .userNoUnlink, - .offline, - .readOnly, - .reparse, - .sparse, - .system + .noDump, .hidden, .offline, + .readOnly, .sparse, .system + // The following flags throw EPERM on ZFS. + // .userImmutable, .userAppend, .opaque, + // .userNoUnlink, .reparse, ] #else // os(OpenBSD) let userSettableFlags: FileFlags = [ @@ -384,13 +385,13 @@ private struct StatTests { #endif flags.insert(userSettableFlags) - try #require(fchflags(fd.rawValue, flags.rawValue) == 0, "\(Errno.current)") + try #require(fchflags(fd.rawValue, UInt(flags.rawValue)) == 0, "\(Errno.current)") stat = try fd.stat() #expect(stat.flags == flags) flags.remove(userSettableFlags) - try #require(fchflags(fd.rawValue, flags.rawValue) == 0, "\(Errno.current)") + try #require(fchflags(fd.rawValue, UInt(flags.rawValue)) == 0, "\(Errno.current)") stat = try fd.stat() #expect(stat.flags == flags) From 91bd99f29a71c34f5ea35b6ce40d141819ae4fb4 Mon Sep 17 00:00:00 2001 From: Kenta Kubo <601636+kkebo@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:24:57 +0900 Subject: [PATCH 2/5] Fix Darwin tests --- Tests/SystemTests/StatTests.swift | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Tests/SystemTests/StatTests.swift b/Tests/SystemTests/StatTests.swift index d10d926b..0f392cb4 100644 --- a/Tests/SystemTests/StatTests.swift +++ b/Tests/SystemTests/StatTests.swift @@ -385,13 +385,13 @@ private struct StatTests { #endif flags.insert(userSettableFlags) - try #require(fchflags(fd.rawValue, UInt(flags.rawValue)) == 0, "\(Errno.current)") + try #require(fchflags(fd.rawValue, flags.rawValue) == 0, "\(Errno.current)") stat = try fd.stat() #expect(stat.flags == flags) flags.remove(userSettableFlags) - try #require(fchflags(fd.rawValue, UInt(flags.rawValue)) == 0, "\(Errno.current)") + try #require(fchflags(fd.rawValue, flags.rawValue) == 0, "\(Errno.current)") stat = try fd.stat() #expect(stat.flags == flags) @@ -418,4 +418,11 @@ private func == (lhs: timespec, rhs: timespec) -> Bool { lhs.tv_sec == rhs.tv_sec && lhs.tv_nsec == rhs.tv_nsec } +#if os(FreeBSD) +// Helper functions for FreeBSD +private func fchflags(_ fd: CInt, _ flags: CInterop.FileFlags) -> CInt { + fchflags(fd, UInt(flags)) +} +#endif + #endif From cf6956a19aa4d318ba09b4fe5d3ab4df8c9d1c46 Mon Sep 17 00:00:00 2001 From: Kenta Kubo <601636+kkebo@users.noreply.github.com> Date: Wed, 28 Jan 2026 21:33:06 +0900 Subject: [PATCH 3/5] Reduce the use of compile-time branching --- Sources/System/Internals/Constants.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Sources/System/Internals/Constants.swift b/Sources/System/Internals/Constants.swift index 32665612..b026c97c 100644 --- a/Sources/System/Internals/Constants.swift +++ b/Sources/System/Internals/Constants.swift @@ -692,10 +692,8 @@ internal var _S_IFLNK: mode_t { S_IFLNK } @_alwaysEmitIntoClient internal var _S_IFSOCK: mode_t { S_IFSOCK } -#if SYSTEM_PACKAGE_DARWIN -@_alwaysEmitIntoClient -internal var _S_IFWHT: mode_t { S_IFWHT } -#elseif os(FreeBSD) +#if SYSTEM_PACKAGE_DARWIN || os(FreeBSD) +// `S_IFWHT` is `Int32` on FreeBSD. @_alwaysEmitIntoClient internal var _S_IFWHT: mode_t { .init(S_IFWHT) } #endif From 4278ed8d977912da42d37734f4803071cbf87ccb Mon Sep 17 00:00:00 2001 From: Kenta Kubo <601636+kkebo@users.noreply.github.com> Date: Wed, 4 Feb 2026 01:55:12 +0900 Subject: [PATCH 4/5] Unify assertions of `sizeAllocated` on all POSIX platforms --- Tests/SystemTests/StatTests.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Tests/SystemTests/StatTests.swift b/Tests/SystemTests/StatTests.swift index 0f392cb4..a7d06376 100644 --- a/Tests/SystemTests/StatTests.swift +++ b/Tests/SystemTests/StatTests.swift @@ -118,11 +118,7 @@ private struct StatTests { #expect(targetStat.type == .regular) #expect(symlinkStat.type == .symbolicLink) #expect(symlinkStat.size < targetStat.size) - #if os(FreeBSD) #expect(symlinkStat.sizeAllocated <= targetStat.sizeAllocated) - #else - #expect(symlinkStat.sizeAllocated < targetStat.sizeAllocated) - #endif // Set each .st_atim back to its original value for comparison From 043bda4234d710434ab9ec0d54306fd6edb124e2 Mon Sep 17 00:00:00 2001 From: Kenta Kubo <601636+kkebo@users.noreply.github.com> Date: Wed, 4 Feb 2026 02:18:24 +0900 Subject: [PATCH 5/5] Remove unclear helper function --- Tests/SystemTests/StatTests.swift | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Tests/SystemTests/StatTests.swift b/Tests/SystemTests/StatTests.swift index a7d06376..fac1ae06 100644 --- a/Tests/SystemTests/StatTests.swift +++ b/Tests/SystemTests/StatTests.swift @@ -381,13 +381,15 @@ private struct StatTests { #endif flags.insert(userSettableFlags) - try #require(fchflags(fd.rawValue, flags.rawValue) == 0, "\(Errno.current)") + // On FreeBSD, the second argument of `fchflags` requires `UInt` instead of`UInt32`. + try #require(fchflags(fd.rawValue, .init(flags.rawValue)) == 0, "\(Errno.current)") stat = try fd.stat() #expect(stat.flags == flags) flags.remove(userSettableFlags) - try #require(fchflags(fd.rawValue, flags.rawValue) == 0, "\(Errno.current)") + // On FreeBSD, the second argument of `fchflags` requires `UInt` instead of`UInt32`. + try #require(fchflags(fd.rawValue, .init(flags.rawValue)) == 0, "\(Errno.current)") stat = try fd.stat() #expect(stat.flags == flags) @@ -414,11 +416,4 @@ private func == (lhs: timespec, rhs: timespec) -> Bool { lhs.tv_sec == rhs.tv_sec && lhs.tv_nsec == rhs.tv_nsec } -#if os(FreeBSD) -// Helper functions for FreeBSD -private func fchflags(_ fd: CInt, _ flags: CInterop.FileFlags) -> CInt { - fchflags(fd, UInt(flags)) -} -#endif - #endif