Add binding for res_init.
Some notes about the particularities of the changes:
res_init has been deprecated in favor of res_ninit, and many (but not
all) targets have therefore renamed the link name to __res_init. For
example, this happened in glibc in version 2.2:
https://bugzilla.redhat.com/show_bug.cgi?id=43822#c6
In these systems, res_init is #defined to __res_init in resolv.h, which
lets existing C programs continue to be compiled.
Unfortunately, this define doesn't automatically apply to our Rust code.
We therefore need to manually map the link name of res_init as
appropriate for each target:
macOS and iOS use res_9_init: https://github.com/practicalswift/osx/blob/3908694d6328baa293f0d7fc337348c01d13ed8f/src/libresolv/resolv.h#L316
Solaris uses res_init: https://java.net/projects/solaris/sources/on-src/content/usr/src/head/resolv.h
OpenBSD uses __res_init: https://github.com/openbsd/src/blob/f3b3b7c7ca9a921db3a5650eed40f2b2e4d731d8/include/resolv.h#L268
FreeBSD uses __res_init: https://github.com/freebsd/freebsd/blob/6911f4a88c9832e5985b788f5e84010424f9e020/include/resolv.h#L290
NetBSD uses __res_init: http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/include/resolv.h
glibc uses __res_init: https://github.com/lattera/glibc/blob/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/resolv/resolv.h#L259
eglibc uses __res_init: https://github.com/Xilinx/eglibc/blob/7f0bcce417c47aefad06ddfec7cd4ced3a4e10ff/resolv/resolv.h#L259
musl uses res_init: https://github.com/runtimejs/musl-libc/blob/0a11d7cb13e243782da36e2e5747b8b151933cca/include/resolv.h#L128
Android uses res_init: https://github.com/android/platform_bionic/blob/306ea559528255e19a5bcd68cc2a9b1afc2cfb27/libc/include/resolv.h#L57
One caveat here is that NetBSD doesn't seem to use the symbol name
__res_init yet, despite the redefine being present in resolv.h. At least
Travis fails for the netbsd target if __res_init is used. This may
change in the future.
iOS and macOS both unfortunately require linking with libresolv, despite
the symbols technically being available without libresolv:
resolv: http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
Android and OpenBSD fall in the same category.
diff --git a/libc-test/build.rs b/libc-test/build.rs
index 28ac5a5..cfee015 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -77,6 +77,7 @@
cfg.header("netinet/in.h");
cfg.header("netinet/ip.h");
cfg.header("netinet/tcp.h");
+ cfg.header("resolv.h");
cfg.header("pthread.h");
cfg.header("dlfcn.h");
cfg.header("signal.h");
diff --git a/src/unix/mod.rs b/src/unix/mod.rs
index 7ebf0d9..f83d8f2 100644
--- a/src/unix/mod.rs
+++ b/src/unix/mod.rs
@@ -206,9 +206,22 @@
cfg_if! {
if #[cfg(dox)] {
// on dox builds don't pull in anything
- } else if #[cfg(all(not(stdbuild), feature = "use_std"))] {
+ } else if #[cfg(all(not(stdbuild),
+ feature = "use_std",
+ not(any(target_os = "macos",
+ target_os = "ios",
+ target_os = "android",
+ target_os = "openbsd",
+ target_os = "bitrig")
+ )))] {
// cargo build, don't pull in anything extra as the libstd dep
// already pulls in all libs.
+ } else if #[cfg(all(not(stdbuild), feature = "use_std"))] {
+ // except on macOS and iOS, where we must link with lib resolv
+ // for res_init, despite libsystem_info including it:
+ // http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
+ #[link(name = "resolv")]
+ extern {}
} else if #[cfg(any(all(target_env = "musl", not(target_arch = "mips"))))] {
#[link(name = "c", kind = "static", cfg(target_feature = "crt-static"))]
#[link(name = "c", cfg(not(target_feature = "crt-static")))]
@@ -229,6 +242,7 @@
target_os = "bitrig"))] {
#[link(name = "c")]
#[link(name = "m")]
+ #[link(name = "resolv")]
extern {}
} else if #[cfg(target_os = "haiku")] {
#[link(name = "root")]
@@ -694,6 +708,17 @@
res: *mut *mut addrinfo) -> ::c_int;
pub fn freeaddrinfo(res: *mut addrinfo);
pub fn gai_strerror(errcode: ::c_int) -> *const ::c_char;
+ #[cfg_attr(all(unix,
+ not(target_os = "macos"),
+ not(target_os = "ios"),
+ not(target_os = "netbsd"),
+ not(target_os = "solaris"),
+ not(target_env = "musl")
+ ),
+ link_name = "__res_init")]
+ #[cfg_attr(any(target_os = "macos", target_os = "ios"),
+ link_name = "res_9_init")]
+ pub fn res_init() -> ::c_int;
#[cfg_attr(target_os = "netbsd", link_name = "__gmtime_r50")]
pub fn gmtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm;