\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
@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}),
* Out of memory handling::
* Library version handling::
* Regular expressions::
+* Windows sockets::
@end menu
@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
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. */
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)
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])
#include <netdb.h>
#endif
#ifdef HAVE_WS2TCPIP_H
-#define WINVER 0x0501
#include <ws2tcpip.h>
#endif
])
#include <netdb.h>
#endif
#ifdef HAVE_WS2TCPIP_H
-#define WINVER 0x0501
#include <ws2tcpip.h>
#endif
])
--- /dev/null
+Files:
+tests/test-getaddrinfo.c
+
+Depends-on:
+inet_ntop
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-getaddrinfo$(EXEEXT)
+check_PROGRAMS += test-getaddrinfo
+
+License:
+LGPL
--- /dev/null
+#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);
+}