Skip to content

Commit 03562b0

Browse files
committed
Auto merge of #585 - jonhoo:res_init, r=alexcrichton
Add res_init The `res_init` function, while deprecated, is critical for making networked applications work correctly when switching between networks, or between being offline and online. By default, `getaddrinfo` and friends use a cached version of `/etc/resolv.conf`, which means that network changes are not picked up by applications after they first start up. This has bitten [Firefox](https://bugzilla.mozilla.org/show_bug.cgi?id=214538), [Pidgin](https://developer.pidgin.im/ticket/2825), [MongoDB](https://jira.mongodb.org/browse/DOCS-5700), and more in the past. The logic behind exposing only `res_init` is that it is the only `res_*` function that is frequently called directly by user applications. The other `res_*` functions provide low-level access to domain lookups, whereas `res_init` is useful even if the application itself is not concerned with doing lookups. Behind the scenes, `getaddrinfo` in glibc [ultimately calls](https://github.com/lattera/glibc/blob/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/resolv/nss_dns/dns-host.c#L196) `res_nsearch` with `&_res`. `res_init` operates directly on this global reference, and is thus more useful to expose for most applications than the non-deprecated `res_ninit` function (which operators on an arbitrary `res_state`). As far as I can tell, `res_init` is available in [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=res_init&manpath=SuSE+Linux/i386+11.3), [NetBSD](http://netbsd.gw.com/cgi-bin/man-cgi?res_init+3+NetBSD-6.1), [OpenBSD](http://man.openbsd.org/resolver.3), [Solaris](http://www.polarhome.com/service/man/?qf=res_init&tf=2&of=Solaris&sf=), [Linux](https://linux.die.net/man/3/res_init), and [macOS](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/res_init.3.html).
2 parents fd9d460 + be7e45f commit 03562b0

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

libc-test/build.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ fn main() {
7777
cfg.header("netinet/in.h");
7878
cfg.header("netinet/ip.h");
7979
cfg.header("netinet/tcp.h");
80+
cfg.header("resolv.h");
8081
cfg.header("pthread.h");
8182
cfg.header("dlfcn.h");
8283
cfg.header("signal.h");
@@ -473,6 +474,16 @@ fn main() {
473474
// it's in a header file?
474475
"endpwent" if android => true,
475476

477+
// Apparently res_init exists on Android, but isn't defined in a header:
478+
// https://mail.gnome.org/archives/commits-list/2013-May/msg01329.html
479+
"res_init" if android => true,
480+
481+
// On macOS and iOS, res_init is available, but requires linking with libresolv:
482+
// http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
483+
// See discussion for skipping here:
484+
// https://github.com/rust-lang/libc/pull/585#discussion_r114561460
485+
"res_init" if apple => true,
486+
476487
_ => false,
477488
}
478489
});

src/unix/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,14 @@ extern {
694694
res: *mut *mut addrinfo) -> ::c_int;
695695
pub fn freeaddrinfo(res: *mut addrinfo);
696696
pub fn gai_strerror(errcode: ::c_int) -> *const ::c_char;
697+
#[cfg_attr(any(
698+
all(target_os = "linux", not(target_env = "musl")),
699+
target_os = "freebsd",
700+
target_os = "dragonfly"),
701+
link_name = "__res_init")]
702+
#[cfg_attr(any(target_os = "macos", target_os = "ios"),
703+
link_name = "res_9_init")]
704+
pub fn res_init() -> ::c_int;
697705

698706
#[cfg_attr(target_os = "netbsd", link_name = "__gmtime_r50")]
699707
pub fn gmtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm;

0 commit comments

Comments
 (0)