about summary refs log tree commit diff
path: root/src/libstd/sys_common
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-10-06 10:20:14 +0000
committerbors <bors@rust-lang.org>2017-10-06 10:20:14 +0000
commit3ed8b698421291f5057059da885cd670d76a47e9 (patch)
tree243914370c4ac9c3a93a0a16c2618644e4bb699d /src/libstd/sys_common
parented1cffdb21220f633b8b91f099a69fab4ef2b8f4 (diff)
parent9602fe1509f2d6ae274a42f61ca5b5cf0c3b9a6b (diff)
downloadrust-3ed8b698421291f5057059da885cd670d76a47e9.tar.gz
rust-3ed8b698421291f5057059da885cd670d76a47e9.zip
Auto merge of #44965 - oconnor663:res_init_glibc, r=dtolnay
replace libc::res_init with res_init_if_glibc_before_2_26

The previous workaround for gibc's res_init bug is not thread-safe on
other implementations of libc, and it can cause crashes. Use a runtime
check to make sure we only call res_init when we need to, which is also
when it's safe. See https://github.com/rust-lang/rust/issues/43592.

~This PR is returning an InvalidData IO error if the glibc version string fails to parse. We could also have treated that case as "not glibc", and gotten rid of the idea that these functions could return an error. (Though I'm not a huge fan of ignoring error returns from `res_init` in any case.) Do other folks agree with these design choices?~

I'm pretty new to hacking on libstd. Is there an easy way to build a toy rust program against my changes to test this, other than doing an entire `sudo make install` on my system? What's the usual workflow?
Diffstat (limited to 'src/libstd/sys_common')
-rw-r--r--src/libstd/sys_common/net.rs13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index 19dc841b9b5..c76b0bcf1c9 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -175,10 +175,15 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
             },
             #[cfg(unix)]
             Err(e) => {
-                // The lookup failure could be caused by using a stale /etc/resolv.conf.
-                // See https://github.com/rust-lang/rust/issues/41570.
-                // We therefore force a reload of the nameserver information.
-                c::res_init();
+                // 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