Isn't _res an internal function? If so, why is Wine using it?
On Mon, 2003-07-21 at 10:06, Mike McCormack wrote:
Newer versions of glibc don't exporting the _res symbol, but instead replace it with a function call of a different name. This breaks binary compatibility for code using _res compiled and linked with older versions of glibc. (iphlpapi uses _res)
Mike
ChangeLog:
- dlopen libc to avoid problems with glibc's _res symbol, which only
defined in older glibc versions
Index: configure.ac
RCS file: /home/wine/wine/configure.ac,v retrieving revision 1.166 diff -u -r1.166 configure.ac --- configure.ac 16 Jul 2003 23:37:22 -0000 1.166 +++ configure.ac 21 Jul 2003 02:45:13 -0000 @@ -911,8 +911,8 @@ WINE_GET_SONAME(jack,jack_client_new) WINE_GET_SONAME(ssl,SSL_library_init) WINE_GET_SONAME(crypto,BIO_new_socket)
- WINE_GET_SONAME(c, vsprintf)
fi
dnl **** Check for functions ****
Index: configure
RCS file: /home/wine/wine/configure,v retrieving revision 1.441 diff -u -r1.441 configure --- configure 16 Jul 2003 23:37:22 -0000 1.441 +++ configure 21 Jul 2003 02:45:21 -0000 @@ -2246,7 +2246,8 @@ echo "$as_me:$LINENO: $? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \
- '' \
- ''\
- '#include <stdlib.h>' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \
@@ -2260,8 +2261,8 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -$ac_declaration #include <stdlib.h> +$ac_declaration int main () { @@ -12977,8 +12978,72 @@ #define SONAME_LIBCRYPTO "$ac_cv_lib_soname_crypto" _ACEOF fi -fi
+echo "$as_me:$LINENO: checking for -lc soname" >&5 +echo $ECHO_N "checking for -lc soname... $ECHO_C" >&6 +if test "${ac_cv_lib_soname_c+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+else
- ac_get_soname_save_LIBS=$LIBS
+LIBS="-lc $LIBS"
- cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */
+/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
+char vsprintf (); +int +main () +{ +vsprintf ();
- ;
- return 0;
+} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: "$ac_link"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: $? = $ac_status" >&5
- (exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: "$ac_try"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: $? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_soname_c=`$ac_cv_path_LDD conftest$ac_exeext | grep libc\.so | sed 's/^[ ]*([^ ]*)[ ]*=>.*$/\1/'`
- if test "x$ac_cv_lib_soname_c" = "x"
- then
ac_cv_lib_soname_c="libc.so"
- fi
+else
- echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ac_cv_lib_soname_c="libc.so" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
- LIBS=$ac_get_soname_save_LIBS
+fi +echo "$as_me:$LINENO: result: $ac_cv_lib_soname_c" >&5 +echo "${ECHO_T}$ac_cv_lib_soname_c" >&6 +if test "x$ac_cv_lib_soname_c" != xNONE +then +cat >>confdefs.h <<_ACEOF +#define SONAME_LIBC "$ac_cv_lib_soname_c" +_ACEOF +fi +fi
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works Index: include/config.h.in =================================================================== RCS file: /home/wine/wine/include/config.h.in,v retrieving revision 1.157 diff -u -r1.157 config.h.in --- include/config.h.in 20 Jun 2003 23:26:56 -0000 1.157 +++ include/config.h.in 21 Jul 2003 02:45:22 -0000 @@ -53,6 +53,9 @@ /* Define to 1 if you have the <cups/cups.h> header file. */ #undef HAVE_CUPS_CUPS_H
+/* Define to the soname of the C library. */ +#undef SONAME_LIBC
/* Define to 1 if you have the <curses.h> header file. */ #undef HAVE_CURSES_H
Index: dlls/iphlpapi/Makefile.in
RCS file: /home/wine/wine/dlls/iphlpapi/Makefile.in,v retrieving revision 1.1 diff -u -r1.1 Makefile.in --- dlls/iphlpapi/Makefile.in 13 May 2003 03:32:20 -0000 1.1 +++ dlls/iphlpapi/Makefile.in 21 Jul 2003 02:45:22 -0000 @@ -7,6 +7,7 @@
LDDLLFLAGS = @LDDLLFLAGS@ SYMBOLFILE = $(MODULE).tmp.o +EXTRALIBS = @DLLIBS@
C_SRCS = \ ifenum.c \ Index: dlls/iphlpapi/iphlpapi_main.c =================================================================== RCS file: /home/wine/wine/dlls/iphlpapi/iphlpapi_main.c,v retrieving revision 1.4 diff -u -r1.4 iphlpapi_main.c --- dlls/iphlpapi/iphlpapi_main.c 23 Jun 2003 03:32:28 -0000 1.4 +++ dlls/iphlpapi/iphlpapi_main.c 21 Jul 2003 02:45:22 -0000 @@ -29,6 +29,8 @@ #include <arpa/nameser.h> #endif #include <resolv.h> +#include <wine/library.h> +#include <wine/port.h> #include "winbase.h" #include "iphlpapi.h" #include "ifenum.h" @@ -847,6 +849,35 @@ return getIPStats(pStats); }
+/******************************************************************
- IPHLPAPI_GetResolver
- Finds the location of the DNS server list for GetNetworkParams
- */
+#ifdef __GLIBC__ +struct __res_state *IPHLPAPI_GetResolverState() +{
- static struct __res_state *p_res;
- static struct __res_state *(*p__res_state)();
- static void *plibc;
- if( !plibc )
- {
plibc = wine_dlopen(SONAME_LIBC, RTLD_GLOBAL, NULL, 0 );
p__res_state = wine_dlsym(plibc, "__res_state", NULL, 0 );
p_res = wine_dlsym(plibc, "_res", NULL, 0 );
- }
- if( p__res_state )
return p__res_state();
- if( p_res )
return p_res;
- return NULL;
+} +#endif /* __GLIBC */
/******************************************************************
- GetNetworkParams (IPHLPAPI.@)
@@ -865,11 +896,22 @@ DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen) { DWORD size; +#ifdef __GLIBC__
- struct __res_state *p_res = IPHLPAPI_GetResolverState();
+#endif
int res_nscount = 0;
if (!pOutBufLen) return ERROR_INVALID_PARAMETER;
- size = sizeof(FIXED_INFO) + min(1, (_res.nscount - 1) *
+#ifdef __GLIBC__
- if( p_res )
- res_nscount = p_res->nscount;
+#else
- res_nscount = _res.nscount;
+#endif
- size = sizeof(FIXED_INFO) + min(1, (res_nscount - 1) * sizeof(IP_ADDR_STRING)); if (!pFixedInfo || *pOutBufLen < size) { *pOutBufLen = size;
@@ -881,14 +923,19 @@ GetComputerNameExA(ComputerNameDnsHostname, pFixedInfo->HostName, &size); size = sizeof(pFixedInfo->DomainName); GetComputerNameExA(ComputerNameDnsDomain, pFixedInfo->DomainName, &size);
- if (_res.nscount > 0) {
- if ( res_nscount > 0) { PIP_ADDR_STRING ptr; int i;
- for (i = 0, ptr = &pFixedInfo->DnsServerList; i < _res.nscount;
- for (i = 0, ptr = &pFixedInfo->DnsServerList; i < res_nscount; i++, ptr = ptr->Next) {
+#ifdef __GLIBC__
toIPAddressString(p_res->nsaddr_list[i].sin_addr.s_addr,
ptr->IpAddress.String);
+#else toIPAddressString(_res.nsaddr_list[i].sin_addr.s_addr, ptr->IpAddress.String); +#endif ptr->Next = (PIP_ADDR_STRING)((PBYTE)ptr + sizeof(IP_ADDRESS_STRING)); } }
Hi Mike,
No, unfortunately it's supposed to be a "well known" global symbol. It's even mentioned in the manual page for resolver(3).
Mike
RESOLVER(3) Linux Programmer's Manual RESOLVER(3)
NAME res_init, res_query, res_search, res_querydomain, res_mkquery, res_send, dn_comp, dn_expand - resolver rou- tines
SYNOPSIS #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> extern struct state _res;
Mike Hearn wrote:
Isn't _res an internal function? If so, why is Wine using it?
Mike McCormack said:
Hi Mike,
No, unfortunately it's supposed to be a "well known" global symbol. It's even mentioned in the manual page for resolver(3).
So is errno, but that doesn't exist either, but get's #defined to __get_errno_loc() (or something). _res turns to _res_state() I think.
PS. This breaks netscape-4.7?? on nptl + glibc as it uses _res
Stefan
On Mon, 2003-07-21 at 17:06, Stefan Jones wrote:
PS. This breaks netscape-4.7?? on nptl + glib as it uses _res
I'm going to investigate this further. The _res symbol is still available in the glibc binaries, and they have a policy of only versioning symbols, not breaking them. I feel there is more to this than meets the eye, although it's possible the glibc guys screwed up.