From: Simon Josefsson Date: Wed, 21 Jun 2006 17:22:32 +0000 (+0000) Subject: Fix getaddrinfo on Windows 2000. X-Git-Tag: cvs-readonly~2334 X-Git-Url: http://erislabs.net/gitweb/?a=commitdiff_plain;h=7225c1675c9a7105efee3299a8f53782c13aeab6;p=gnulib.git Fix getaddrinfo on Windows 2000. --- diff --git a/doc/gnulib.texi b/doc/gnulib.texi index c61ab571a..6d62e8760 100644 --- a/doc/gnulib.texi +++ b/doc/gnulib.texi @@ -1,5 +1,5 @@ \input texinfo @c -*-texinfo-*- -@comment $Id: gnulib.texi,v 1.22 2006-06-19 20:40:26 karl Exp $ +@comment $Id: gnulib.texi,v 1.23 2006-06-21 17:22:32 jas Exp $ @comment %**start of header @setfilename gnulib.info @settitle GNU Gnulib @@ -7,7 +7,7 @@ @syncodeindex pg cp @comment %**end of header -@set UPDATED $Date: 2006-06-19 20:40:26 $ +@set UPDATED $Date: 2006-06-21 17:22:32 $ @copying This manual is for GNU Gnulib (updated @value{UPDATED}), @@ -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 +@node Windows sockets +@section 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. + +@subsection 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 diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c index 7ea696778..d2029ae37 100644 --- a/lib/getaddrinfo.c +++ b/lib/getaddrinfo.c @@ -212,6 +212,7 @@ getaddrinfo (const char *restrict nodename, 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. */ diff --git a/m4/getaddrinfo.m4 b/m4/getaddrinfo.m4 index c36719078..fef311ff1 100644 --- a/m4/getaddrinfo.m4 +++ b/m4/getaddrinfo.m4 @@ -17,7 +17,6 @@ AC_DEFUN([gl_GETADDRINFO], LIBS="$LIBS -lws2_32" AC_TRY_LINK([ #ifdef HAVE_WS2TCPIP_H -#define WINVER 0x0501 #include #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 +#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 #endif #ifdef HAVE_WS2TCPIP_H -#define WINVER 0x0501 #include #endif ]) @@ -68,7 +82,6 @@ AC_DEFUN([gl_PREREQ_GETADDRINFO], [ #include #endif #ifdef HAVE_WS2TCPIP_H -#define WINVER 0x0501 #include #endif ]) diff --git a/modules/getaddrinfo-tests b/modules/getaddrinfo-tests new file mode 100644 index 000000000..86d70c25b --- /dev/null +++ b/modules/getaddrinfo-tests @@ -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 diff --git a/tests/test-getaddrinfo.c b/tests/test-getaddrinfo.c new file mode 100644 index 000000000..adf29e4d6 --- /dev/null +++ b/tests/test-getaddrinfo.c @@ -0,0 +1,63 @@ +#include "config.h" +#include "getaddrinfo.h" +#include "inet_ntop.h" +#include +#include + +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); +}