Skip to content

Commit ad50bdf

Browse files
authored
Call getifaddrs and freeifaddrs dynamically on Android
Foundation's Host.swift uses getifaddrs and freeifaddrs, which currently causes Android 6.0 or below to fail to link. Change these functions so they are called using dlsym, which allows Android 6.0 to link while providing full support on later versions of Android.
1 parent de924e0 commit ad50bdf

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

Sources/Foundation/Host.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,32 @@ import CoreFoundation
2424
private func getnameinfo(_ addr: UnsafePointer<sockaddr>?, _ addrlen: socklen_t, _ host: UnsafeMutablePointer<Int8>?, _ hostlen: socklen_t, _ serv: UnsafeMutablePointer<Int8>?, _ servlen: socklen_t, _ flags: Int32) -> Int32 {
2525
return Glibc.getnameinfo(addr, addrlen, host, Int(hostlen), serv, Int(servlen), flags)
2626
}
27+
28+
// getifaddrs and freeifaddrs are not available in Android 6.0 or earlier, so call these functions dynamically.
29+
// This only happens during the initial lookup of the addresses and then the results are cached and _resolved is marked true.
30+
// If this API changes so these functions are called more frequently, it might be beneficial to cache the function pointers.
31+
32+
private typealias GetIfAddrsFunc = @convention(c) (UnsafeMutablePointer<UnsafeMutablePointer<ifaddrs>?>) -> Int32
33+
private func getifaddrs(_ ifap: UnsafeMutablePointer<UnsafeMutablePointer<ifaddrs>?>) -> Int32 {
34+
var result: Int32 = -1
35+
if let handle = dlopen("libc.so", RTLD_NOLOAD) {
36+
if let entry = dlsym(handle, "getifaddrs") {
37+
result = unsafeBitCast(entry, to: GetIfAddrsFunc.self)(ifap)
38+
}
39+
dlclose(handle)
40+
}
41+
return result
42+
}
43+
44+
private typealias FreeIfAddrsFunc = @convention(c) (UnsafeMutablePointer<ifaddrs>?) -> Void
45+
private func freeifaddrs(_ ifa: UnsafeMutablePointer<ifaddrs>?) {
46+
if let handle = dlopen("libc.so", RTLD_NOLOAD) {
47+
if let entry = dlsym(handle, "freeifaddrs") {
48+
unsafeBitCast(entry, to: FreeIfAddrsFunc.self)(ifa)
49+
}
50+
dlclose(handle)
51+
}
52+
}
2753
#endif
2854

2955
open class Host: NSObject {

0 commit comments

Comments
 (0)