about summary refs log tree commit diff
path: root/src/libstd/sys_common
diff options
context:
space:
mode:
authorRyan Cumming <etaoins@gmail.com>2018-01-10 20:13:03 +1100
committerRyan Cumming <etaoins@gmail.com>2018-01-16 06:30:44 +1100
commit090a968fe7680cce0d3aa8fde25a5dc48948e43e (patch)
tree6cb438656baf3111f840ff1a6ca405453da10bf3 /src/libstd/sys_common
parent8ff449d505728276e822ca9a80c1e7b2da8288a2 (diff)
downloadrust-090a968fe7680cce0d3aa8fde25a5dc48948e43e.tar.gz
rust-090a968fe7680cce0d3aa8fde25a5dc48948e43e.zip
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.
Diffstat (limited to 'src/libstd/sys_common')
-rw-r--r--src/libstd/sys_common/net.rs24
1 files changed, 3 insertions, 21 deletions
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index c70b39995eb..b841afe1a51 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -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 }
+        })
     }
 }