From 24eb0e196f935fe0bbb39c184ce3b11365f97176 Mon Sep 17 00:00:00 2001
From: 3405691582 <dsk@google.com>
Date: Tue, 25 Mar 2025 21:42:58 -0400
Subject: [PATCH] OpenBSD support.

* Ensure the swift-crypto dependency is conditioned for the platform.

  The relevant swift-crypto changes are not landed upstream yet, but
  when they are, this picks up the dependency.

* Cast timestamps to time_t.

  This is done unconditionally here, because the standard specifies
  that `tv_sec` in `timespec` has type `time_t`, and doing so avoids a
  type mismatch error on the platform.

* Since pthread types are pointers here, make the usual changes to
  capture the fact they are optional types on the Swift side.

So far, this has been the only set of changes that have seemed necessary.

Fixes swiftlang/swift-build#114.
---
 Package.swift                 | 2 +-
 Sources/SWBUtil/FSProxy.swift | 8 ++++----
 Sources/SWBUtil/Lock.swift    | 3 +++
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Package.swift b/Package.swift
index 2f9d0fff..964543b2 100644
--- a/Package.swift
+++ b/Package.swift
@@ -195,7 +195,7 @@ let package = Package(
                 "SWBCSupport",
                 "SWBLibc",
                 .product(name: "ArgumentParser", package: "swift-argument-parser"),
-                .product(name: "Crypto", package: "swift-crypto", condition: .when(platforms: [.linux, .android])),
+                .product(name: "Crypto", package: "swift-crypto", condition: .when(platforms: [.linux, .openbsd, .android])),
                 .product(name: "SystemPackage", package: "swift-system", condition: .when(platforms: [.linux, .android, .windows])),
             ],
             exclude: ["CMakeLists.txt"],
diff --git a/Sources/SWBUtil/FSProxy.swift b/Sources/SWBUtil/FSProxy.swift
index 97f388a0..a8959df3 100644
--- a/Sources/SWBUtil/FSProxy.swift
+++ b/Sources/SWBUtil/FSProxy.swift
@@ -665,7 +665,7 @@ class LocalFS: FSProxy, @unchecked Sendable {
             let UTIME_OMIT = 1073741822
             #endif
             let atime = timespec(tv_sec: 0, tv_nsec: Int(UTIME_OMIT))
-            let mtime = timespec(tv_sec: timestamp, tv_nsec: 0)
+            let mtime = timespec(tv_sec: time_t(timestamp), tv_nsec: 0)
             guard utimensat(AT_FDCWD, path.str, [atime, mtime], 0) == 0 else {
                 throw POSIXError(errno, context: "utimensat", "AT_FDCWD", path.str, String(timestamp))
             }
@@ -1390,7 +1390,7 @@ public class PseudoFS: FSProxy, @unchecked Sendable {
                 #if os(Windows)
                 info.st_mtimespec = timespec(tv_sec: Int64(node.timestamp), tv_nsec: 0)
                 #else
-                info.st_mtimespec = timespec(tv_sec: node.timestamp, tv_nsec: 0)
+                info.st_mtimespec = timespec(tv_sec: time_t(node.timestamp), tv_nsec: 0)
                 #endif
                 info.st_size = off_t(contents.bytes.count)
                 info.st_dev = node.device
@@ -1403,7 +1403,7 @@ public class PseudoFS: FSProxy, @unchecked Sendable {
                 info.st_mtimespec = timespec(tv_sec: Int64(node.timestamp), tv_nsec: 0)
                 #else
                 info.st_mode = S_IFDIR
-                info.st_mtimespec = timespec(tv_sec: node.timestamp, tv_nsec: 0)
+                info.st_mtimespec = timespec(tv_sec: time_t(node.timestamp), tv_nsec: 0)
                 #endif
                 info.st_size = off_t(dir.contents.count)
                 info.st_dev = node.device
@@ -1416,7 +1416,7 @@ public class PseudoFS: FSProxy, @unchecked Sendable {
                 info.st_mtimespec = timespec(tv_sec: Int64(node.timestamp), tv_nsec: 0)
                 #else
                 info.st_mode = S_IFLNK
-                info.st_mtimespec = timespec(tv_sec: node.timestamp, tv_nsec: 0)
+                info.st_mtimespec = timespec(tv_sec: time_t(node.timestamp), tv_nsec: 0)
                 #endif
                 info.st_size = off_t(0)
                 info.st_dev = node.device
diff --git a/Sources/SWBUtil/Lock.swift b/Sources/SWBUtil/Lock.swift
index cbf47de9..2135ce67 100644
--- a/Sources/SWBUtil/Lock.swift
+++ b/Sources/SWBUtil/Lock.swift
@@ -26,6 +26,9 @@ public final class Lock: @unchecked Sendable {
     #if os(Windows)
     @usableFromInline
     let mutex: UnsafeMutablePointer<SRWLOCK> = UnsafeMutablePointer.allocate(capacity: 1)
+    #elseif os(OpenBSD)
+    @usableFromInline
+    let mutex: UnsafeMutablePointer<pthread_mutex_t?> = UnsafeMutablePointer.allocate(capacity: 1)
     #else
     @usableFromInline
     let mutex: UnsafeMutablePointer<pthread_mutex_t> = UnsafeMutablePointer.allocate(capacity: 1)