Skip to content

Commit 22a3a1e

Browse files
authored
Merge pull request #160 from gregcotten/abstract-unix-paths
Add support for unix "abstract namespace" addresses
2 parents 9d9dc1a + c0f9e6a commit 22a3a1e

File tree

6 files changed

+105
-1
lines changed

6 files changed

+105
-1
lines changed

FlyingSocks/Sources/Socket+Android.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,24 @@ extension Socket {
9999
return addr
100100
}
101101

102+
static func makeAbstractNamespaceUnix(name: String) -> Android.sockaddr_un {
103+
var addr: sockaddr_un = Android.sockaddr_un()
104+
addr.sun_family = sa_family_t(AF_UNIX)
105+
106+
_ = withUnsafeMutableBytes(of: &addr.sun_path) { raw in
107+
raw.initializeMemory(as: CChar.self, repeating: 0)
108+
}
109+
110+
let nameBytes = Array(name.utf8.prefix(107))
111+
nameBytes.withUnsafeBytes { src in
112+
withUnsafeMutableBytes(of: &addr.sun_path) { dst in
113+
dst[1 ..< 1 + src.count].copyBytes(from: src)
114+
}
115+
}
116+
117+
return addr
118+
}
119+
102120
static func socket(_ domain: Int32, _ type: Int32, _ protocol: Int32) -> FileDescriptorType {
103121
Android.socket(domain, type, `protocol`)
104122
}

FlyingSocks/Sources/Socket+Glibc.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,24 @@ extension Socket {
9696
return addr
9797
}
9898

99+
static func makeAbstractNamespaceUnix(name: String) -> Glibc.sockaddr_un {
100+
var addr: sockaddr_un = Glibc.sockaddr_un()
101+
addr.sun_family = sa_family_t(AF_UNIX)
102+
103+
_ = withUnsafeMutableBytes(of: &addr.sun_path) { raw in
104+
raw.initializeMemory(as: CChar.self, repeating: 0)
105+
}
106+
107+
let nameBytes = Array(name.utf8.prefix(107))
108+
nameBytes.withUnsafeBytes { src in
109+
withUnsafeMutableBytes(of: &addr.sun_path) { dst in
110+
dst[1 ..< 1 + src.count].copyBytes(from: src)
111+
}
112+
}
113+
114+
return addr
115+
}
116+
99117
static func socket(_ domain: Int32, _ type: Int32, _ protocol: Int32) -> FileDescriptorType {
100118
Glibc.socket(domain, type, `protocol`)
101119
}

FlyingSocks/Sources/Socket+Musl.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,24 @@ extension Socket {
9696
return addr
9797
}
9898

99+
static func makeAbstractNamespaceUnix(name: String) -> Musl.sockaddr_un {
100+
var addr: sockaddr_un = Musl.sockaddr_un()
101+
addr.sun_family = sa_family_t(AF_UNIX)
102+
103+
_ = withUnsafeMutableBytes(of: &addr.sun_path) { raw in
104+
raw.initializeMemory(as: CChar.self, repeating: 0)
105+
}
106+
107+
let nameBytes = Array(name.utf8.prefix(107))
108+
nameBytes.withUnsafeBytes { src in
109+
withUnsafeMutableBytes(of: &addr.sun_path) { dst in
110+
dst[1 ..< 1 + src.count].copyBytes(from: src)
111+
}
112+
}
113+
114+
return addr
115+
}
116+
99117
static func socket(_ domain: Int32, _ type: Int32, _ protocol: Int32) -> FileDescriptorType {
100118
Musl.socket(domain, type, `protocol`)
101119
}

FlyingSocks/Sources/Socket+WinSock2.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ extension Socket {
107107
return addr
108108
}
109109

110+
static func makeAbstractNamespaceUnix(name: String) -> WinSDK.sockaddr_un {
111+
var addr: sockaddr_un = WinSDK.sockaddr_un()
112+
addr.sun_family = ADDRESS_FAMILY(AF_UNIX)
113+
114+
_ = withUnsafeMutableBytes(of: &addr.sun_path) { raw in
115+
raw.initializeMemory(as: CChar.self, repeating: 0)
116+
}
117+
118+
let nameBytes = Array(name.utf8.prefix(107))
119+
nameBytes.withUnsafeBytes { src in
120+
withUnsafeMutableBytes(of: &addr.sun_path) { dst in
121+
dst[1 ..< 1 + src.count].copyBytes(from: src)
122+
}
123+
}
124+
125+
return addr
126+
}
127+
110128
static func fcntl(_ fd: FileDescriptorType, _ cmd: Int32) -> Int32 {
111129
return -1
112130
}

FlyingSocks/Sources/SocketAddress.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,15 @@ public extension SocketAddress where Self == sockaddr_in6 {
107107
}
108108

109109
public extension SocketAddress where Self == sockaddr_un {
110-
111110
static func unix(path: String) -> Self {
112111
Socket.makeAddressUnix(path: path)
113112
}
113+
114+
#if canImport(Glibc) || canImport(Musl) || canImport(Android) || canImport(WinSDK)
115+
static func unix(abstractNamespace: String) -> Self {
116+
Socket.makeAbstractNamespaceUnix(name: abstractNamespace)
117+
}
118+
#endif
114119
}
115120

116121
#if compiler(>=6.0)

FlyingSocks/Tests/SocketAddressTests.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,23 @@ struct SocketAddressTests {
148148
)
149149
}
150150

151+
#if canImport(Glibc) || canImport(Musl) || canImport(Android) || canImport(WinSDK)
152+
@Test
153+
func unixAbstractNamespace_IsCorrectlyDecodedFromStorage() throws {
154+
let storage = sockaddr_un
155+
.unix(abstractNamespace: "mygreatnamespace")
156+
.makeStorage()
157+
158+
var unix = try sockaddr_un.make(from: storage)
159+
let path = withUnsafePointer(to: &unix.sun_path.1) {
160+
return String(cString: $0)
161+
}
162+
#expect(
163+
path == "mygreatnamespace"
164+
)
165+
}
166+
#endif
167+
151168
@Test
152169
func unix_ThrowsInvalidAddress_WhenFamilyIncorrect() {
153170
let storage = sockaddr_in6
@@ -183,6 +200,16 @@ struct SocketAddressTests {
183200
)
184201
}
185202

203+
#if canImport(Glibc) || canImport(Musl) || canImport(Android) || canImport(WinSDK)
204+
@Test
205+
func unixAbstractNamespace_CheckSize() throws {
206+
let sun = sockaddr_un.unix(abstractNamespace: "some_great_namespace")
207+
#expect(
208+
sun.size == socklen_t(MemoryLayout<sockaddr_un>.size)
209+
)
210+
}
211+
#endif
212+
186213
@Test
187214
func unknown_CheckSize() throws {
188215
var sa = sockaddr()

0 commit comments

Comments
 (0)