Skip to content

Commit 449d70f

Browse files
committed
Android build fixes
1 parent de184b0 commit 449d70f

File tree

9 files changed

+206
-6
lines changed

9 files changed

+206
-6
lines changed

CSystemLinux/include/CSystemLinux.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
See https://swift.org/LICENSE.txt for license information
88
*/
99

10-
#ifdef __linux__
10+
#pragma once
11+
12+
#ifdef __ANDROID__
13+
#include <linux/eventpoll.h>
14+
#include <poll.h>
15+
#endif
1116

17+
#ifdef __linux__
1218
#include <sys/epoll.h>
1319
#include <sys/eventfd.h>
14-
1520
#endif
16-

FlyingSocks/Sources/Mutex.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,12 @@ extension Mutex {
129129
}
130130
}
131131

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

134134
#if canImport(Musl)
135135
import Musl
136+
#elseif canImport(Bionic)
137+
import Android
136138
#else
137139
import Glibc
138140
#endif
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
//
2+
// Socket+Android.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(Android)
33+
import Android
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 = Android.in_addr(s_addr: Android.in_addr_t(0))
46+
47+
static func makeAddressINET(port: UInt16) -> Android.sockaddr_in {
48+
Android.sockaddr_in(
49+
sin_family: sa_family_t(AF_INET),
50+
sin_port: port.bigEndian,
51+
sin_addr: in_addr_any,
52+
__pad: (0, 0, 0, 0, 0, 0, 0, 0)
53+
)
54+
}
55+
56+
static func makeAddressINET6(port: UInt16) -> Android.sockaddr_in6 {
57+
Android.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) -> Android.sockaddr_in6 {
67+
Android.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) -> Android.sockaddr_un {
77+
var addr = Android.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+
Android.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+
_ = Android.socketpair(domain, type, `protocol`, &sockets)
96+
return (sockets[0], sockets[1])
97+
}
98+
99+
static func fcntl(_ fd: Int32, _ cmd: Int32) -> Int32 {
100+
Android.fcntl(fd, cmd)
101+
}
102+
103+
static func fcntl(_ fd: Int32, _ cmd: Int32, _ value: Int32) -> Int32 {
104+
Android.fcntl(fd, cmd, value)
105+
}
106+
107+
static func setsockopt(_ fd: Int32, _ level: Int32, _ name: Int32,
108+
_ value: UnsafeRawPointer!, _ len: socklen_t) -> Int32 {
109+
Android.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+
Android.getsockopt(fd, level, name, value, len)
115+
}
116+
117+
static func getpeername(_ fd: Int32, _ addr: UnsafeMutablePointer<sockaddr>!, _ len: UnsafeMutablePointer<socklen_t>!) -> Int32 {
118+
Android.getpeername(fd, addr, len)
119+
}
120+
121+
static func getsockname(_ fd: Int32, _ addr: UnsafeMutablePointer<sockaddr>!, _ len: UnsafeMutablePointer<socklen_t>!) -> Int32 {
122+
Android.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 Android.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+
Android.inet_pton(domain, buffer, addr)
134+
}
135+
136+
static func bind(_ fd: Int32, _ addr: UnsafePointer<sockaddr>!, _ len: socklen_t) -> Int32 {
137+
Android.bind(fd, addr, len)
138+
}
139+
140+
static func listen(_ fd: Int32, _ backlog: Int32) -> Int32 {
141+
Android.listen(fd, backlog)
142+
}
143+
144+
static func accept(_ fd: Int32, _ addr: UnsafeMutablePointer<sockaddr>!, _ len: UnsafeMutablePointer<socklen_t>!) -> Int32 {
145+
Android.accept(fd, addr, len)
146+
}
147+
148+
static func connect(_ fd: Int32, _ addr: UnsafePointer<sockaddr>!, _ len: socklen_t) -> Int32 {
149+
Android.connect(fd, addr, len)
150+
}
151+
152+
static func read(_ fd: Int32, _ buffer: UnsafeMutableRawPointer!, _ nbyte: Int) -> Int {
153+
Android.read(fd, buffer, nbyte)
154+
}
155+
156+
static func write(_ fd: Int32, _ buffer: UnsafeRawPointer!, _ nbyte: Int) -> Int {
157+
Android.send(fd, buffer, nbyte, Int32(MSG_NOSIGNAL))
158+
}
159+
160+
static func close(_ fd: Int32) -> Int32 {
161+
Android.close(fd)
162+
}
163+
164+
static func unlink(_ addr: UnsafePointer<CChar>!) -> Int32 {
165+
Android.unlink(addr)
166+
}
167+
168+
static func poll(_ fds: UnsafeMutablePointer<pollfd>!, _ nfds: UInt32, _ tmo_p: Int32) -> Int32 {
169+
Android.poll(fds, nfds_t(nfds), tmo_p)
170+
}
171+
172+
static func pollfd(fd: FileDescriptorType, events: Int16, revents: Int16) -> Android.pollfd {
173+
Android.pollfd(fd: fd, events: events, revents: revents)
174+
}
175+
}
176+
177+
#endif

FlyingSocks/Sources/Socket.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
#if canImport(WinSDK)
3333
import WinSDK.WinSock2
34+
#elseif canImport(Android)
35+
@_exported import Android
3436
#endif
3537
import Foundation
3638

FlyingSocks/Sources/SocketAddress.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,13 @@
3232
import Foundation
3333
#if canImport(WinSDK)
3434
import WinSDK.WinSock2
35+
#elseif canImport(Android)
36+
import Android
3537
#endif
3638

39+
#if canImport(CSystemLinux)
40+
import CSystemLinux
41+
#endif
3742

3843
public protocol SocketAddress: Sendable {
3944
static var family: sa_family_t { get }

FlyingSocks/Sources/SocketError.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
//
3131

3232
import Foundation
33+
#if canImport(Android)
34+
import Android
35+
#endif
3336

3437
public enum SocketError: LocalizedError, Equatable {
3538
case failed(type: String, errno: Int32, message: String)

FlyingSocks/Sources/SocketPool+Poll.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
#if canImport(WinSDK)
3333
import WinSDK.WinSock2
34+
#elseif canImport(Android)
35+
import Android
3436
#endif
3537
import Foundation
3638

FlyingSocks/Sources/SocketPool+ePoll.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,12 @@ extension EventNotification {
219219
private struct EPOLLEvents: OptionSet, Hashable {
220220
var rawValue: UInt32
221221

222-
#if canImport(Musl)
222+
#if canImport(Android)
223+
// from linux/eventpoll.h, not imported by clang importer
224+
private static let EPOLLET: UInt32 = 1 << 31;
225+
#endif
226+
227+
#if canImport(Musl) || canImport(Android)
223228
static let read = EPOLLEvents(rawValue: UInt32(EPOLLIN))
224229
static let write = EPOLLEvents(rawValue: UInt32(EPOLLOUT))
225230
static let hup = EPOLLEvents(rawValue: UInt32(EPOLLHUP))

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ let package = Package(
2626
),
2727
.target(
2828
name: "FlyingSocks",
29-
dependencies: [.target(name: "CSystemLinux", condition: .when(platforms: [.linux]))],
29+
dependencies: [.target(name: "CSystemLinux", condition: .when(platforms: [.linux, .android]))],
3030
path: "FlyingSocks/Sources",
3131
swiftSettings: .upcomingFeatures
3232
),

0 commit comments

Comments
 (0)