bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

getaddrinfo windows fixes


From: Simon Josefsson
Subject: getaddrinfo windows fixes
Date: Wed, 21 Jun 2006 19:22:39 +0200
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/22.0.50 (gnu/linux)

I've noticed that getaddrinfo didn't exist in ws2_32.dll on Windows
2000.  The hack in the getaddrinfo module to define WINVER to 0x0501
seems like an incorrect approach.

Ideally, the replacement code should, during runtime, open ws2_32.dll
and check for the getaddrinfo symbol and use it if present.

Instead, the patch below will have the getaddrinfo module use the
gnulib implementation by default, since there is no prototypes without
the proper WINVER.  If you want to assume Windows XP, just define
WINVER to 0x0501 before invoking the check, and it will use the system
getaddrinfo.

This also adds some documentation and quickly written self tests for
the getaddrinfo module.

Opinions?

I've installed this.

Index: doc/gnulib.texi
===================================================================
RCS file: /sources/gnulib/gnulib/doc/gnulib.texi,v
retrieving revision 1.22
diff -u -p -r1.22 gnulib.texi
--- doc/gnulib.texi     19 Jun 2006 20:40:26 -0000      1.22
+++ doc/gnulib.texi     21 Jun 2006 17:19:25 -0000
@@ -89,6 +89,7 @@ Getting started:
 * Out of memory handling::
 * Library version handling::
 * Regular expressions::
+* Windows sockets::
 @end menu
 
 
@@ -294,6 +295,38 @@ generated automatically.
 @include regexprops-generic.texi
 
 
address@hidden Windows sockets
address@hidden Windows sockets
+
+There are several issues when building applications that should work
+under Windows.  The most problematic part is for applications that use
+sockets.
+
+Hopefully, we can add helpful notes to this section that will help you
+port your application to Windows using gnulib.
+
address@hidden Getaddrinfo and WINVER
+
+This was written for the getaddrinfo module, but may be applicable to
+other functions too.
+
+The getaddrinfo function exists in ws2tcpip.h and -lws2_32 on Windows
+XP.  The function declaration is present if @code{WINVER >= 0x0501}.
+Windows 2000 does not have getaddrinfo in its @file{WS2_32.dll}.
+
+Thus, if you want to assume Windows XP or later, you can add
+AC_DEFINE(WINVER, 0x0501) to avoid compiling to (partial) getaddrinfo
+implementation.
+
+If you want to support Windows 2000, don't do anything, but be aware
+that gnulib will use its own (partial) getaddrinfo implementation even
+on Windows XP.  Currently the code does not attempt to determine if
+the getaddrinfo function is available during runtime.
+
+Todo: Make getaddrinfo.c open the WS2_32.DLL and check for the
+getaddrinfo symbol and use it if present, otherwise fall back to our
+own implementation.
+
 @include gnulib-tool.texi
 
 
Index: lib/getaddrinfo.c
===================================================================
RCS file: /sources/gnulib/gnulib/lib/getaddrinfo.c,v
retrieving revision 1.7
diff -u -p -r1.7 getaddrinfo.c
--- lib/getaddrinfo.c   23 Sep 2005 19:41:05 -0000      1.7
+++ lib/getaddrinfo.c   21 Jun 2006 17:19:25 -0000
@@ -212,6 +212,7 @@ getaddrinfo (const char *restrict nodena
   tmp->ai_protocol = (hints) ? hints->ai_protocol : 0;
   tmp->ai_socktype = (hints) ? hints->ai_socktype : 0;
   tmp->ai_addr->sa_family = he->h_addrtype;
+  tmp->ai_family = he->h_addrtype;
 
   /* FIXME: If more than one address, create linked list of addrinfo's. */
 
Index: m4/getaddrinfo.m4
===================================================================
RCS file: /sources/gnulib/gnulib/m4/getaddrinfo.m4,v
retrieving revision 1.15
diff -u -p -r1.15 getaddrinfo.m4
--- m4/getaddrinfo.m4   28 Feb 2006 14:52:22 -0000      1.15
+++ m4/getaddrinfo.m4   21 Jun 2006 17:19:25 -0000
@@ -17,7 +17,6 @@ AC_DEFUN([gl_GETADDRINFO],
       LIBS="$LIBS -lws2_32"
       AC_TRY_LINK([
 #ifdef HAVE_WS2TCPIP_H
-#define WINVER 0x0501
 #include <ws2tcpip.h>
 #endif
 ], [getaddrinfo(0, 0, 0, 0);], gl_cv_w32_getaddrinfo=yes)
@@ -37,6 +36,22 @@ AC_DEFUN([gl_GETADDRINFO],
 AC_DEFUN([gl_PREREQ_GETADDRINFO], [
   AC_SEARCH_LIBS(gethostbyname, [inet nsl])
   AC_SEARCH_LIBS(getservbyname, [inet nsl socket xnet])
+  AC_CHECK_FUNCS(gethostbyname,, [
+    AC_CACHE_CHECK(for gethostbyname in winsock2.h and -lws2_32,
+                  gl_cv_w32_gethostbyname, [
+      gl_cv_w32_gethostbyname=no
+      am_save_LIBS="$LIBS"
+      LIBS="$LIBS -lws2_32"
+      AC_TRY_LINK([
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+], [gethostbyname(0);], gl_cv_w32_gethostbyname=yes)
+    LIBS="$am_save_LIBS"])
+    if test "$gl_cv_w32_gethostbyname" = "yes"; then
+      LIBS="$LIBS -lws2_32"
+    fi
+    ])
   AC_REQUIRE([gl_C_RESTRICT])
   AC_REQUIRE([gl_SOCKET_FAMILIES])
   AC_REQUIRE([gl_HEADER_SYS_SOCKET])
@@ -55,7 +70,6 @@ AC_DEFUN([gl_PREREQ_GETADDRINFO], [
 #include <netdb.h>
 #endif
 #ifdef HAVE_WS2TCPIP_H
-#define WINVER 0x0501
 #include <ws2tcpip.h>
 #endif
 ])
@@ -68,7 +82,6 @@ AC_DEFUN([gl_PREREQ_GETADDRINFO], [
 #include <netdb.h>
 #endif
 #ifdef HAVE_WS2TCPIP_H
-#define WINVER 0x0501
 #include <ws2tcpip.h>
 #endif
 ])
Index: modules/getaddrinfo-tests
===================================================================
RCS file: modules/getaddrinfo-tests
diff -N modules/getaddrinfo-tests
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ modules/getaddrinfo-tests   21 Jun 2006 17:19:25 -0000
@@ -0,0 +1,14 @@
+Files:
+tests/test-getaddrinfo.c
+
+Depends-on:
+inet_ntop
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-getaddrinfo$(EXEEXT)
+check_PROGRAMS += test-getaddrinfo
+
+License:
+LGPL
Index: tests/test-getaddrinfo.c
===================================================================
RCS file: tests/test-getaddrinfo.c
diff -N tests/test-getaddrinfo.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ tests/test-getaddrinfo.c    21 Jun 2006 17:19:25 -0000
@@ -0,0 +1,63 @@
+#include "config.h"
+#include "getaddrinfo.h"
+#include "inet_ntop.h"
+#include <stdio.h>
+#include <string.h>
+
+int simple (char *host, char *service)
+{
+  char buf[BUFSIZ];
+  struct addrinfo hints;
+  struct addrinfo *ai0, *ai;
+  int res;
+
+  printf ("Finding %s service %s...\n", host, service);
+
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_flags = AI_CANONNAME;
+  hints.ai_family = AF_INET;
+  hints.ai_socktype = SOCK_STREAM;
+  res = getaddrinfo (host, 0, 0, &ai0);
+
+  printf ("res %d: %s\n", res, gai_strerror (res));
+
+  if (res != 0)
+    return 1;
+
+  for (ai = ai0; ai; ai = ai->ai_next)
+    {
+      printf ("\tflags %x\n", ai->ai_flags);
+      printf ("\tfamily %x\n", ai->ai_family);
+      printf ("\tsocktype %x\n", ai->ai_socktype);
+      printf ("\tprotocol %x\n", ai->ai_protocol);
+      printf ("\taddrlen %d: ", ai->ai_addrlen);
+      printf ("\tFound %s\n",
+             inet_ntop (ai->ai_family,
+                        &((struct sockaddr_in *)
+                         ai->ai_addr)->sin_addr,
+                        buf, sizeof (buf) - 1));
+      if (ai->ai_canonname)
+       printf ("\tFound %s...\n", ai->ai_canonname);
+    }
+
+  freeaddrinfo (ai0);
+
+  return 0;
+}
+
+#define HOST1 "www.gnu.org"
+#define SERV1 "http"
+#define HOST2 "www.ibm.com"
+#define SERV2 "http"
+#define HOST3 "ibm.org"
+#define SERV3 "http"
+#define HOST4 "google.org"
+#define SERV4 "http"
+
+int main (void)
+{
+  return simple (HOST1, SERV1)
+    + simple (HOST2, SERV2)
+    + simple (HOST3, SERV3)
+    + simple (HOST4, SERV4);
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]