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));
> }
> }