Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 41 additions & 47 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// This source file is part of the Swift System open source project
//
// Copyright (c) 2020 - 2024 Apple Inc. and the Swift System project authors
// Copyright (c) 2020 - 2026 Apple Inc. and the Swift System project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
Expand All @@ -12,63 +12,57 @@

import PackageDescription

struct Available {
struct Availability {
var name: String
var version: String
var osAvailability: String
var sourceAvailability: String

init(
_ version: String,
_ osAvailability: String
) {
self.name = "System"
self.version = version
self.osAvailability = osAvailability
self.sourceAvailability = "macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, visionOS 1.0"
var minSwiftPMVersions: String {
"macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, visionOS 1.0"
}

var swiftSetting: SwiftSetting {
#if SYSTEM_ABI_STABLE
// Use availability matching Darwin API.
let availability = self.osAvailability
#else
// Use availability matching SwiftPM default.
let availability = self.sourceAvailability
#endif
return .enableExperimentalFeature(
"AvailabilityMacro=\(self.name) \(version):\(availability)")
var minSpanDeploymentVersions: String {
"macOS 10.14.4, iOS 12.2, watchOS 5.2, tvOS 12.2, visionOS 1.0"
}
}

let availability: [Available] = [
Available("0.0.1", "macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0"),

Available("0.0.2", "macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0"),

Available("0.0.3", "macOS 12.3, iOS 15.4, watchOS 8.5, tvOS 15.4"),
Available("1.1.0", "macOS 12.3, iOS 15.4, watchOS 8.5, tvOS 15.4"),

Available("1.1.1", "macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4"),
Available("1.2.0", "macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4"),

Available("1.2.1", "macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4"),
Available("1.3.0", "macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4"),

Available("1.3.1", "macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4, visionOS 1.0"),
Available("1.3.2", "macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4, visionOS 1.0"),
Available("1.4.0", "macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4, visionOS 1.0"),
var isStandardAvailability: Bool { name == "System" }
}

Available("1.4.1", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
Available("1.4.2", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
Available("1.5.0", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
Available("1.6.0", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
Available("1.6.1", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
let availabilityMap: [(String, String)] = [
("0.0.1", "macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0"),
("0.0.2", "macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0"),
("1.1.0", "macOS 12.3, iOS 15.4, watchOS 8.5, tvOS 15.4"),
("1.2.0", "macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4"),
("1.4.0", "macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4, visionOS 1.0"),

Available("99", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
("99", "macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999"),
]

let swiftSettingsAvailability = availability.map(\.swiftSetting)
let availabilities: [Availability] =
availabilityMap.map {
Availability(name: "System", version: $0.0, osAvailability: $0.1)
} + availabilityMap.prefix(5).map {
Availability(name: "SystemWithSpan", version: $0.0, osAvailability: $0.1)
}

let swiftSettingsAvailability = availabilities.map {
availability -> SwiftSetting in
let osVersionList: String
#if SYSTEM_ABI_STABLE
// Use availability matching Darwin API.
osVersionList = availability.osAvailability
#else
if availability.isStandardAvailability {
// Use availability matching SwiftPM minimum.
osVersionList = availability.minSwiftPMVersions
} else {
// Use availability matching Span deployment minimum.
osVersionList = availability.minSpanDeploymentVersions
}
#endif
return .enableExperimentalFeature(
"AvailabilityMacro=\(availability.name) \(availability.version):\(osVersionList)"
)
}

#if SYSTEM_CI
let swiftSettingsCI: [SwiftSetting] = [
Expand Down
1 change: 1 addition & 0 deletions Sources/Samples/Connect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct Connect: ParsableCommand {
@Option(name: .shortAndLong, help: "Message to send")
var message: String = "Hello from swift-system sockets!"

@available(System 99, *)
func run() throws {
print("Resolving \(host)...")

Expand Down
1 change: 1 addition & 0 deletions Sources/Samples/Listen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct Listen: ParsableCommand {
@Option(name: .shortAndLong, help: "Maximum number of connections to accept (0 for unlimited)")
var maxConnections: Int = 0

@available(System 99, *)
func run() throws {
// Create socket
let server = try SocketDescriptor.open(.ipv4, .stream, protocol: .tcp)
Expand Down
4 changes: 4 additions & 0 deletions Sources/Samples/Resolve.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct Resolve: ParsableCommand {
@Flag(name: .long, help: "Show only IPv6 addresses")
var ipv6Only: Bool = false

@available(System 99, *)
func run() throws {
let family: SocketDescriptor.Domain?
if ipv4Only {
Expand Down Expand Up @@ -73,6 +74,7 @@ struct Resolve: ParsableCommand {
}
}

@available(System 99, *)
private func familyName(_ domain: SocketDescriptor.Domain) -> String {
switch domain {
case .ipv4: return "IPv4"
Expand All @@ -82,6 +84,7 @@ struct Resolve: ParsableCommand {
}
}

@available(System 99, *)
private func typeName(_ type: SocketDescriptor.ConnectionType) -> String {
switch type {
case .stream: return "Stream (TCP)"
Expand All @@ -91,6 +94,7 @@ struct Resolve: ParsableCommand {
}
}

@available(System 99, *)
private func protocolName(_ proto: SocketDescriptor.ProtocolID) -> String {
switch proto {
case .tcp: return "TCP"
Expand Down
1 change: 1 addition & 0 deletions Sources/Samples/ReverseResolve.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import ArgumentParser
import SystemSockets

@available(System 99, *)
struct ReverseResolve: ParsableCommand {
static let configuration = CommandConfiguration(
abstract: "Reverse resolve an IP address to a hostname using getnameinfo"
Expand Down
3 changes: 3 additions & 0 deletions Sources/Samples/Util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ internal func complain(_ message: String) {
}
}

@available(System 99, *)
extension SocketAddress.ResolvedAddress {
var niceDescription: String {
var proto = ""
Expand All @@ -48,6 +49,7 @@ extension SocketAddress.ResolvedAddress {
}
}

@available(System 99, *)
extension SocketAddress {
var niceDescription: String {
if let ipv4 = self.ipv4 { return ipv4.description }
Expand All @@ -57,6 +59,7 @@ extension SocketAddress {
}
}

@available(System 99, *)
extension SocketDescriptor.ConnectionType {
var isConnectionless: Bool {
self == .datagram || self == .reliablyDeliveredMessage
Expand Down
2 changes: 2 additions & 0 deletions Sources/Samples/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import ArgumentParser

struct SystemSamples: ParsableCommand {

@available(System 99, *)
static var configuration = CommandConfiguration(
commandName: "system-samples",
abstract: "A collection of little programs exercising some System features.",
Expand Down
17 changes: 12 additions & 5 deletions Sources/System/FileHelpers.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This source file is part of the Swift System open source project

Copyright (c) 2020 Apple Inc. and the Swift System project authors
Copyright (c) 2020 - 2026 Apple Inc. and the Swift System project authors
Licensed under Apache License v2.0 with Runtime Library Exception

See https://swift.org/LICENSE.txt for license information
Expand All @@ -20,6 +20,7 @@ extension FileDescriptor {
/// If `body` throws an error
/// or an error occurs while closing the file descriptor,
/// this method rethrows that error.
@available(System 0.0.1, *)
public func closeAfter<R>(_ body: () throws -> R) throws -> R {
// No underscore helper, since the closure's throw isn't necessarily typed.
let result: R
Expand Down Expand Up @@ -49,6 +50,7 @@ extension FileDescriptor {
/// If `sequence` doesn't implement
/// the <doc://com.apple.documentation/documentation/swift/sequence/3128824-withcontiguousstorageifavailable> method,
/// temporary space will be allocated as needed.
@available(System 0.0.1, *)
@_alwaysEmitIntoClient
@discardableResult
public func writeAll<S: Sequence>(
Expand Down Expand Up @@ -98,6 +100,7 @@ extension FileDescriptor {
/// If `sequence` doesn't implement
/// the <doc://com.apple.documentation/documentation/swift/sequence/3128824-withcontiguousstorageifavailable> method,
/// temporary space will be allocated as needed.
@available(System 0.0.1, *)
@_alwaysEmitIntoClient
@discardableResult
public func writeAll<S: Sequence>(
Expand All @@ -106,6 +109,7 @@ extension FileDescriptor {
try _writeAll(toAbsoluteOffset: offset, sequence).get()
}

@available(System 0.0.1, *)
@usableFromInline
internal func _writeAll<S: Sequence>(
toAbsoluteOffset offset: Int64, _ sequence: S
Expand All @@ -115,6 +119,7 @@ extension FileDescriptor {
}
}

@available(System 0.0.1, *)
@_alwaysEmitIntoClient
internal func _writeAllBuffer(
toAbsoluteOffset offset: Int64, _ buffer: UnsafeRawBufferPointer
Expand All @@ -134,6 +139,7 @@ extension FileDescriptor {
return .success(buffer.count)
}

#if compiler(>=6.2)
/// Writes the entire contents of a buffer, retrying on partial writes.
///
/// - Parameters:
Expand All @@ -150,7 +156,7 @@ extension FileDescriptor {
/// call the ``seek(offset:from:)`` method.
///
/// The corresponding C function is `write`.
@available(macOS 15, iOS 18, watchOS 11, tvOS 18, visionOS 2, *)
@available(SystemWithSpan 0.0.1, *)
@_alwaysEmitIntoClient
public func writeAll(
_ data: RawSpan,
Expand All @@ -177,7 +183,7 @@ extension FileDescriptor {
/// this method leaves the file's existing offset unchanged.
///
/// The corresponding C function is `pwrite`.
@available(macOS 15, iOS 18, watchOS 11, tvOS 18, visionOS 2, *)
@available(SystemWithSpan 0.0.1, *)
@_alwaysEmitIntoClient
public func writeAll(
toAbsoluteOffset offset: Int64,
Expand Down Expand Up @@ -205,7 +211,7 @@ extension FileDescriptor {
/// call the ``seek(offset:from:)`` method.
///
/// The corresponding C function is `read`.
@available(macOS 15, iOS 18, watchOS 11, tvOS 18, visionOS 2, *)
@available(SystemWithSpan 0.0.1, *)
@_alwaysEmitIntoClient
@discardableResult
public func read(
Expand Down Expand Up @@ -238,7 +244,7 @@ extension FileDescriptor {
/// this method leaves the file's existing offset unchanged.
///
/// The corresponding C function is `pread`.
@available(macOS 15, iOS 18, watchOS 11, tvOS 18, visionOS 2, *)
@available(SystemWithSpan 0.0.1, *)
@_alwaysEmitIntoClient
@discardableResult
public func read(
Expand All @@ -257,4 +263,5 @@ extension FileDescriptor {
}
return originalCapacity - buffer.freeCapacity
}
#endif // swift(>=6.2)
}
Loading
Loading