Only link res_init() on GNU/*nix
To workaround a bug in glibc <= 2.26 lookup_host() calls res_init() based on the glibc version detected at runtime. While this avoids calling res_init() on platforms where it's not required we will still end up linking against the symbol. This causes an issue on macOS where res_init() is implemented in a separate library (libresolv.9.dylib) from the main libc. While this is harmless for standalone programs it becomes a problem if Rust code is statically linked against another program. If the linked program doesn't already specify -lresolv it will cause the link to fail. This is captured in issue #46797 Fix this by hooking in to the glibc workaround in `cvt_gai` and only activating it for the "gnu" environment on Unix This should include all glibc platforms while excluding musl, windows-gnu, macOS, FreeBSD, etc. This has the side benefit of removing the #[cfg] in sys_common; only unix.rs has code related to the workaround now.
This commit is contained in:
@@ -166,27 +166,9 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
|
||||
hints.ai_socktype = c::SOCK_STREAM;
|
||||
let mut res = ptr::null_mut();
|
||||
unsafe {
|
||||
match cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)) {
|
||||
Ok(_) => {
|
||||
Ok(LookupHost { original: res, cur: res })
|
||||
},
|
||||
#[cfg(unix)]
|
||||
Err(e) => {
|
||||
// If we're running glibc prior to version 2.26, the lookup
|
||||
// failure could be caused by caching a stale /etc/resolv.conf.
|
||||
// We need to call libc::res_init() to clear the cache. But we
|
||||
// shouldn't call it in on any other platform, because other
|
||||
// res_init implementations aren't thread-safe. See
|
||||
// https://github.com/rust-lang/rust/issues/41570 and
|
||||
// https://github.com/rust-lang/rust/issues/43592.
|
||||
use sys::net::res_init_if_glibc_before_2_26;
|
||||
let _ = res_init_if_glibc_before_2_26();
|
||||
Err(e)
|
||||
},
|
||||
// the cfg is needed here to avoid an "unreachable pattern" warning
|
||||
#[cfg(not(unix))]
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)).map(|_| {
|
||||
LookupHost { original: res, cur: res }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user