Avoid problems with glibc's _res symbol

Mike Hearn mike at theoretic.com
Mon Jul 21 04:26:05 CDT 2003


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




More information about the wine-devel mailing list