Avoid problems with glibc's _res symbol

Mike McCormack mike at codeweavers.com
Mon Jul 21 04:06:03 CDT 2003


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

-------------- next part --------------
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-patches mailing list