summaryrefslogtreecommitdiffstats
path: root/libc/inet/resolv.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/inet/resolv.c')
-rw-r--r--libc/inet/resolv.c99
1 files changed, 66 insertions, 33 deletions
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index c2df49224..f983229a4 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -1136,44 +1136,31 @@ struct hostent *gethostbyname2(const char *name, int family)
#ifdef L_res_init
-#undef _res
-struct __res_state _res;
-
-struct __res_state * weak_const_function __res_state (void)
-{
- return &_res;
-}
-
-#ifdef __UCLIBC_HAS_THREADS_NATIVE__
-__thread struct __res_state *__resp = &_res;
-#endif
-
int res_init(void)
{
- struct __res_state *rp = __res_state();
-
__close_nameservers();
__open_nameservers();
- rp->retrans = RES_TIMEOUT;
- rp->retry = 4;
- rp->options = RES_INIT;
- rp->id = (u_int) random();
- rp->nsaddr.sin_addr.s_addr = INADDR_ANY;
- rp->nsaddr.sin_family = AF_INET;
- rp->nsaddr.sin_port = htons(NAMESERVER_PORT);
- rp->ndots = 1;
- /** rp->pfcode = 0; **/
- rp->_vcsock = -1;
- /** rp->_flags = 0; **/
- /** rp->qhook = NULL; **/
- /** rp->rhook = NULL; **/
- /** rp->_u._ext.nsinit = 0; **/
BIGLOCK;
+ _res.retrans = RES_TIMEOUT;
+ _res.retry = 4;
+ _res.options = RES_INIT;
+ _res.id = (u_int) random();
+ _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
+ _res.nsaddr.sin_family = AF_INET;
+ _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+ _res.ndots = 1;
+ /** _res.pfcode = 0; **/
+ _res._vcsock = -1;
+ /** _res._flags = 0; **/
+ /** _res.qhook = NULL; **/
+ /** _res.rhook = NULL; **/
+ /** _res._u._ext.nsinit = 0; **/
+
if(__searchdomains) {
int i;
for(i=0; i<__searchdomains; i++) {
- rp->dnsrch[i] = __searchdomain[i];
+ _res.dnsrch[i] = __searchdomain[i];
}
}
@@ -1182,13 +1169,13 @@ int res_init(void)
struct in_addr a;
for(i=0; i<__nameservers; i++) {
if (inet_aton(__nameserver[i], &a)) {
- rp->nsaddr_list[i].sin_addr = a;
- rp->nsaddr_list[i].sin_family = AF_INET;
- rp->nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
+ _res.nsaddr_list[i].sin_addr = a;
+ _res.nsaddr_list[i].sin_family = AF_INET;
+ _res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
}
}
}
- rp->nscount = __nameservers;
+ _res.nscount = __nameservers;
BIGUNLOCK;
return(0);
@@ -1199,8 +1186,54 @@ void res_close( void )
return;
}
+/* This needs to be after the use of _res in res_init, above. */
+#undef _res
+
+/* The resolver state for use by single-threaded programs.
+ This differs from plain `struct __res_state _res;' in that it doesn't
+ create a common definition, but a plain symbol that resides in .bss,
+ which can have an alias. */
+struct __res_state _res __attribute__((section (".bss")));
+
+#if defined __UCLIBC_HAS_THREADS_NATIVE__ \
+ && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# undef __resp
+__thread struct __res_state *__resp = &_res;
+/*
+ * FIXME: Add usage of hidden attribute for this when used in the shared
+ * library. It currently crashes the linker when doing section
+ * relocations.
+ */
+extern __thread struct __res_state *__libc_resp
+ __attribute__ ((alias ("__resp")));
+#endif
+
#endif
+#ifdef L_res_state
+# if defined __UCLIBC_HAS_THREADS_NATIVE__ \
+ && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# undef _res
+extern struct __res_state _res;
+
+/* When threaded, _res may be a per-thread variable. */
+struct __res_state *
+weak_const_function
+__res_state (void)
+{
+ return &_res;
+}
+
+# else
+struct __res_state *
+__res_state (void)
+{
+ return __resp;
+}
+# endif
+hidden_def (__res_state)
+
+#endif
#ifdef L_res_query