Skip to content

Commit 18a6ae3

Browse files
authored
Merge pull request #121 from swhitty/Musl
Add Musl / static linux SDK support
2 parents 2999f02 + b839b5f commit 18a6ae3

File tree

5 files changed

+211
-2
lines changed

5 files changed

+211
-2
lines changed

.github/workflows/build.yml

+17
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,20 @@ jobs:
9595
run: swift build --build-tests
9696
- name: Test
9797
run: swift test --skip-build
98+
99+
linux_swift_6_0_musl:
100+
runs-on: ubuntu-latest
101+
container: swift:6.0
102+
steps:
103+
- name: Checkout
104+
uses: actions/checkout@v4
105+
- name: Version
106+
run: swift --version
107+
- name: SDK List Pre
108+
run: swift sdk list
109+
- name: Install SDK
110+
run: swift sdk install https://download.swift.org/swift-6.0.1-release/static-sdk/swift-6.0.1-RELEASE/swift-6.0.1-RELEASE_static-linux-0.0.1.artifactbundle.tar.gz --checksum d4f46ba40e11e697387468e18987ee622908bc350310d8af54eb5e17c2ff5481
111+
- name: SDK List Post
112+
run: swift sdk list
113+
- name: Build
114+
run: swift build --swift-sdk x86_64-swift-linux-musl

FlyingSocks/Sources/Mutex.swift

+5-1
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,13 @@ extension Mutex {
129129
}
130130
}
131131

132-
#elseif canImport(Glibc)
132+
#elseif canImport(Glibc) || canImport(Musl)
133133

134+
#if canImport(Musl)
135+
import Musl
136+
#else
134137
import Glibc
138+
#endif
135139

136140
extension Mutex {
137141

FlyingSocks/Sources/Socket+Musl.swift

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
//
2+
// Socket+Musl.swift
3+
// FlyingFox
4+
//
5+
// Created by Simon Whitty on 26/09/2024.
6+
// Copyright © 2024 Simon Whitty. All rights reserved.
7+
//
8+
// Distributed under the permissive MIT license
9+
// Get the latest version from here:
10+
//
11+
// https://github.com/swhitty/FlyingFox
12+
//
13+
// Permission is hereby granted, free of charge, to any person obtaining a copy
14+
// of this software and associated documentation files (the "Software"), to deal
15+
// in the Software without restriction, including without limitation the rights
16+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17+
// copies of the Software, and to permit persons to whom the Software is
18+
// furnished to do so, subject to the following conditions:
19+
//
20+
// The above copyright notice and this permission notice shall be included in all
21+
// copies or substantial portions of the Software.
22+
//
23+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29+
// SOFTWARE.
30+
//
31+
32+
#if canImport(Musl)
33+
import Musl
34+
35+
public extension Socket {
36+
typealias FileDescriptorType = Int32
37+
}
38+
39+
extension Socket.FileDescriptor {
40+
static let invalid = Socket.FileDescriptor(rawValue: -1)
41+
}
42+
43+
extension Socket {
44+
static let stream = Int32(SOCK_STREAM)
45+
static let in_addr_any = Musl.in_addr(s_addr: Musl.in_addr_t(0))
46+
47+
static func makeAddressINET(port: UInt16) -> Musl.sockaddr_in {
48+
Musl.sockaddr_in(
49+
sin_family: sa_family_t(AF_INET),
50+
sin_port: port.bigEndian,
51+
sin_addr: in_addr_any,
52+
sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)
53+
)
54+
}
55+
56+
static func makeAddressINET6(port: UInt16) -> Musl.sockaddr_in6 {
57+
Musl.sockaddr_in6(
58+
sin6_family: sa_family_t(AF_INET6),
59+
sin6_port: port.bigEndian,
60+
sin6_flowinfo: 0,
61+
sin6_addr: in6addr_any,
62+
sin6_scope_id: 0
63+
)
64+
}
65+
66+
static func makeAddressLoopback(port: UInt16) -> Musl.sockaddr_in6 {
67+
Musl.sockaddr_in6(
68+
sin6_family: sa_family_t(AF_INET6),
69+
sin6_port: port.bigEndian,
70+
sin6_flowinfo: 0,
71+
sin6_addr: in6addr_loopback,
72+
sin6_scope_id: 0
73+
)
74+
}
75+
76+
static func makeAddressUnix(path: String) -> Musl.sockaddr_un {
77+
var addr = Musl.sockaddr_un()
78+
addr.sun_family = sa_family_t(AF_UNIX)
79+
let pathCount = min(path.utf8.count, 104)
80+
let len = UInt8(MemoryLayout<UInt8>.size + MemoryLayout<sa_family_t>.size + pathCount + 1)
81+
_ = withUnsafeMutablePointer(to: &addr.sun_path.0) { ptr in
82+
path.withCString {
83+
strncpy(ptr, $0, Int(len))
84+
}
85+
}
86+
return addr
87+
}
88+
89+
static func socket(_ domain: Int32, _ type: Int32, _ protocol: Int32) -> FileDescriptorType {
90+
Musl.socket(domain, type, `protocol`)
91+
}
92+
93+
static func socketpair(_ domain: Int32, _ type: Int32, _ protocol: Int32) -> (FileDescriptorType, FileDescriptorType) {
94+
var sockets: [Int32] = [-1, -1]
95+
_ = Musl.socketpair(domain, type, `protocol`, &sockets)
96+
return (sockets[0], sockets[1])
97+
}
98+
99+
static func fcntl(_ fd: Int32, _ cmd: Int32) -> Int32 {
100+
Musl.fcntl(fd, cmd)
101+
}
102+
103+
static func fcntl(_ fd: Int32, _ cmd: Int32, _ value: Int32) -> Int32 {
104+
Musl.fcntl(fd, cmd, value)
105+
}
106+
107+
static func setsockopt(_ fd: Int32, _ level: Int32, _ name: Int32,
108+
_ value: UnsafeRawPointer!, _ len: socklen_t) -> Int32 {
109+
Musl.setsockopt(fd, level, name, value, len)
110+
}
111+
112+
static func getsockopt(_ fd: Int32, _ level: Int32, _ name: Int32,
113+
_ value: UnsafeMutableRawPointer!, _ len: UnsafeMutablePointer<socklen_t>!) -> Int32 {
114+
Musl.getsockopt(fd, level, name, value, len)
115+
}
116+
117+
static func getpeername(_ fd: Int32, _ addr: UnsafeMutablePointer<sockaddr>!, _ len: UnsafeMutablePointer<socklen_t>!) -> Int32 {
118+
Musl.getpeername(fd, addr, len)
119+
}
120+
121+
static func getsockname(_ fd: Int32, _ addr: UnsafeMutablePointer<sockaddr>!, _ len: UnsafeMutablePointer<socklen_t>!) -> Int32 {
122+
Musl.getsockname(fd, addr, len)
123+
}
124+
125+
static func inet_ntop(_ domain: Int32, _ addr: UnsafeRawPointer!,
126+
_ buffer: UnsafeMutablePointer<CChar>!, _ addrLen: socklen_t) throws {
127+
if Musl.inet_ntop(domain, addr, buffer, addrLen) == nil {
128+
throw SocketError.makeFailed("inet_ntop")
129+
}
130+
}
131+
132+
static func inet_pton(_ domain: Int32, _ buffer: UnsafePointer<CChar>!, _ addr: UnsafeMutableRawPointer!) -> Int32 {
133+
Musl.inet_pton(domain, buffer, addr)
134+
}
135+
136+
static func bind(_ fd: Int32, _ addr: UnsafePointer<sockaddr>!, _ len: socklen_t) -> Int32 {
137+
Musl.bind(fd, addr, len)
138+
}
139+
140+
static func listen(_ fd: Int32, _ backlog: Int32) -> Int32 {
141+
Musl.listen(fd, backlog)
142+
}
143+
144+
static func accept(_ fd: Int32, _ addr: UnsafeMutablePointer<sockaddr>!, _ len: UnsafeMutablePointer<socklen_t>!) -> Int32 {
145+
Musl.accept(fd, addr, len)
146+
}
147+
148+
static func connect(_ fd: Int32, _ addr: UnsafePointer<sockaddr>!, _ len: socklen_t) -> Int32 {
149+
Musl.connect(fd, addr, len)
150+
}
151+
152+
static func read(_ fd: Int32, _ buffer: UnsafeMutableRawPointer!, _ nbyte: Int) -> Int {
153+
Musl.read(fd, buffer, nbyte)
154+
}
155+
156+
static func write(_ fd: Int32, _ buffer: UnsafeRawPointer!, _ nbyte: Int) -> Int {
157+
Musl.send(fd, buffer, nbyte, Int32(MSG_NOSIGNAL))
158+
}
159+
160+
static func close(_ fd: Int32) -> Int32 {
161+
Musl.close(fd)
162+
}
163+
164+
static func unlink(_ addr: UnsafePointer<CChar>!) -> Int32 {
165+
Musl.unlink(addr)
166+
}
167+
168+
static func poll(_ fds: UnsafeMutablePointer<pollfd>!, _ nfds: UInt32, _ tmo_p: Int32) -> Int32 {
169+
Musl.poll(fds, UInt(nfds), tmo_p)
170+
}
171+
172+
static func pollfd(fd: FileDescriptorType, events: Int16, revents: Int16) -> Musl.pollfd {
173+
Musl.pollfd(fd: fd, events: events, revents: revents)
174+
}
175+
}
176+
177+
#endif

FlyingSocks/Sources/SocketPool+ePoll.swift

+11
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,24 @@ extension EventNotification {
219219
private struct EPOLLEvents: OptionSet, Hashable {
220220
var rawValue: UInt32
221221

222+
#if canImport(Musl)
223+
static let read = EPOLLEvents(rawValue: UInt32(EPOLLIN))
224+
static let write = EPOLLEvents(rawValue: UInt32(EPOLLOUT))
225+
static let hup = EPOLLEvents(rawValue: UInt32(EPOLLHUP))
226+
static let rdhup = EPOLLEvents(rawValue: UInt32(EPOLLRDHUP))
227+
static let err = EPOLLEvents(rawValue: UInt32(EPOLLERR))
228+
static let pri = EPOLLEvents(rawValue: UInt32(EPOLLPRI))
229+
static let edgeTriggered = EPOLLEvents(rawValue: UInt32(EPOLLET))
230+
#else
222231
static let read = EPOLLEvents(rawValue: EPOLLIN.rawValue)
223232
static let write = EPOLLEvents(rawValue: EPOLLOUT.rawValue)
224233
static let hup = EPOLLEvents(rawValue: EPOLLHUP.rawValue)
225234
static let rdhup = EPOLLEvents(rawValue: EPOLLRDHUP.rawValue)
226235
static let err = EPOLLEvents(rawValue: EPOLLERR.rawValue)
227236
static let pri = EPOLLEvents(rawValue: EPOLLPRI.rawValue)
228237
static let edgeTriggered = EPOLLEvents(rawValue: EPOLLET.rawValue)
238+
#endif
239+
229240
}
230241

231242
private extension Socket.Events {

docker-run-tests.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ set -eu
55
docker run -it \
66
--rm \
77
--mount src="$(pwd)",target=/flyingfox,type=bind \
8-
swiftlang/swift:nightly-jammy \
8+
swift:latest \
99
/usr/bin/swift test --package-path /flyingfox

0 commit comments

Comments
 (0)