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
11 changes: 7 additions & 4 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(macOS 15, iOS 18, watchOS 11, tvOS 18, visionOS 2, *)
func run() throws {
print("Resolving \(host)...")

Expand All @@ -48,15 +49,17 @@ struct Connect: ParsableCommand {

// Send message
let messageBytes = Array(message.utf8)
let sent = try messageBytes.withUnsafeBytes { buffer in
try socket.send(UnsafeRawBufferPointer(buffer))
let sent = try messageBytes.withUnsafeBytes { bytes in
let span = RawSpan(_unsafeBytes: bytes)
return try socket.send(span)
}
print("Sent \(sent) bytes: \(message)")

// Receive response
var buffer = [UInt8](repeating: 0, count: 4096)
let received = try buffer.withUnsafeMutableBytes { buffer in
try socket.receive(into: buffer)
let received = try buffer.withUnsafeMutableBytes { buf in
var output = OutputRawSpan(buffer: buf, initializedCount: 0)
return try socket.receive(into: &output)
}

if received > 0 {
Expand Down
11 changes: 7 additions & 4 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(macOS 15, iOS 18, watchOS 11, tvOS 18, visionOS 2, *)
func run() throws {
// Create socket
let server = try SocketDescriptor.open(.ipv4, .stream, protocol: .tcp)
Expand Down Expand Up @@ -56,8 +57,9 @@ struct Listen: ParsableCommand {
var buffer = [UInt8](repeating: 0, count: 4096)

while true {
let received = try buffer.withUnsafeMutableBytes { buffer in
try client.receive(into: buffer)
let received = try buffer.withUnsafeMutableBytes { buf in
var output = OutputRawSpan(buffer: buf, initializedCount: 0)
return try client.receive(into: &output)
}
if received == 0 {
print("[\(connectionCount)] Client disconnected")
Expand All @@ -68,8 +70,9 @@ struct Listen: ParsableCommand {
print("[\(connectionCount)] Received \(received) bytes: \(message)")

// Echo back
let sent = try buffer.prefix(received).withUnsafeBytes { buffer in
try client.send(UnsafeRawBufferPointer(buffer))
let sent = try buffer.prefix(received).withUnsafeBytes { bytes in
let span = RawSpan(_unsafeBytes: bytes)
return try client.send(span)
}
print("[\(connectionCount)] Echoed \(sent) bytes")
}
Expand Down
24 changes: 9 additions & 15 deletions Sources/System/FileOperations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -492,21 +492,15 @@ extension FileDescriptor {
into buffer: inout OutputRawSpan,
retryOnInterrupt: Bool = true
) throws(Errno) -> Int {
do {
return try buffer.withUnsafeMutableBytes { buf, count in
// Read into the uninitialized portion (starting at offset 'count')
let uninitializedPortion = UnsafeMutableRawBufferPointer(
start: buf.baseAddress?.advanced(by: count),
count: buf.count - count
)
let bytesRead = try read(fromAbsoluteOffset: offset, into: uninitializedPortion, retryOnInterrupt: retryOnInterrupt)
count += bytesRead // Add to existing count, don't replace it!
return bytesRead
}
} catch let error as Errno {
throw error
} catch {
fatalError("Unexpected error type")
try buffer.withUnsafeMutableBytes { buf, count throws(Errno) -> Int in
// Read into the uninitialized portion (starting at offset 'count')
let uninitializedPortion = UnsafeMutableRawBufferPointer(
start: buf.baseAddress?.advanced(by: count),
count: buf.count - count
)
let bytesRead = try _read(fromAbsoluteOffset: offset, into: uninitializedPortion, retryOnInterrupt: retryOnInterrupt).get()
count += bytesRead // Add to existing count, don't replace it!
return bytesRead
}
}
}
Expand Down
27 changes: 15 additions & 12 deletions Sources/SystemSockets/Sockets/SocketMessages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,23 +70,26 @@ extension SocketDescriptor {
/// - Complexity: Amortized O(`data.count`), when averaged over multiple
/// calls. This method reallocates the buffer if there isn't enough
/// capacity or if the storage is shared with another value.
@available(macOS 15, iOS 18, watchOS 11, tvOS 18, visionOS 2, *)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: we'll want to switch to a Span availability macro before landing on main, similar to the file I/O work.

public mutating func appendMessage(
level: SocketDescriptor.ProtocolID,
type: SocketDescriptor.Option,
bytes: UnsafeRawBufferPointer
bytes: RawSpan
) {
appendMessage(
level: level,
type: type,
unsafeUninitializedCapacity: bytes.count
) { buffer in
assert(buffer.count >= bytes.count)
if bytes.count > 0 {
buffer.baseAddress!.copyMemory(
from: bytes.baseAddress!,
byteCount: bytes.count)
bytes.withUnsafeBytes { buffer in
appendMessage(
level: level,
type: type,
unsafeUninitializedCapacity: buffer.count
) { dest in
assert(dest.count >= buffer.count)
if buffer.count > 0 {
dest.baseAddress!.copyMemory(
from: buffer.baseAddress!,
byteCount: buffer.count)
}
return buffer.count
}
return bytes.count
}
}

Expand Down
Loading
Loading