PATCH: (enhanced) getaddrinfo
Marcus Meissner
marcus at jet.franken.de
Fri Nov 11 02:30:36 CST 2005
Hi,
Again, now hopefully final :)
- correct all out of memory conditions (except the realloc case,
but this is really borderline)
- noted that we do not need to convert hints.
Ciao, Marcus
Changelog:
Implemented getaddrinfo() and freeaddrinfo(), based
on patch by Mike Hearn.
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.412
diff -u -r1.412 configure.ac
--- configure.ac 31 Oct 2005 21:10:38 -0000 1.412
+++ configure.ac 11 Nov 2005 08:28:14 -0000
@@ -1158,6 +1158,7 @@
ftruncate \
futimes \
futimesat \
+ getaddrinfo \
getnetbyname \
getopt_long \
getpagesize \
Index: dlls/winsock/socket.c
===================================================================
RCS file: /home/wine/wine/dlls/winsock/socket.c,v
retrieving revision 1.193
diff -u -r1.193 socket.c
--- dlls/winsock/socket.c 5 Nov 2005 10:43:27 -0000 1.193
+++ dlls/winsock/socket.c 11 Nov 2005 08:28:16 -0000
@@ -3,6 +3,7 @@
* (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
*
* Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
+ * (C) 2005 Mike Hearn
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -2865,6 +2865,129 @@
return retval;
}
+/***********************************************************************
+ * freeaddrinfo (WS2_32.@)
+ */
+void WINAPI WS_freeaddrinfo(struct WS_addrinfo *res)
+{
+ while (res) {
+ struct WS_addrinfo *next;
+
+ if (res->ai_canonname)
+ HeapFree(GetProcessHeap(),0,res->ai_canonname);
+ if (res->ai_addr)
+ HeapFree(GetProcessHeap(),0,res->ai_addr);
+ next = res->ai_next;
+ HeapFree(GetProcessHeap(),0,res);
+ res = next;
+ }
+}
+
+/***********************************************************************
+ * GetAddrInfoA (WS2_32.@)
+ * getaddrinfo (WS2_32.@)
+ */
+int WINAPI GetAddrInfoA(CHAR *nodename, CHAR *servname,
+ const struct addrinfo *hints, struct WS_addrinfo **res)
+{
+#if HAVE_GETADDRINFO
+ struct addrinfo *unixaires = NULL;
+ BOOL node_lowered = FALSE, serv_lowered = FALSE;
+ int result;
+
+ if (nodename) {
+ if (!(nodename = strdup_lower(nodename))) return WSA_NOT_ENOUGH_MEMORY;
+ node_lowered = TRUE;
+ }
+
+ if (servname) {
+ if (!(servname = strdup_lower(servname))) {
+ if (node_lowered) HeapFree(GetProcessHeap(), 0, nodename);
+ return WSA_NOT_ENOUGH_MEMORY;
+ }
+ serv_lowered = TRUE;
+ }
+
+ /* NOTE: In theory we would need to convert "hints" too.
+ * However the addrinfo fields that vary between Windows and UNIX are
+ * defined to be 0 or NULL for "hints" , so it is safe to use
+ * the windows struct.
+ */
+
+ /* getaddrinfo(3) is thread safe, no need to wrap in CS */
+ result = getaddrinfo(nodename, servname, hints, &unixaires);
+
+ TRACE("%s, %s %p -> %p %d\n", nodename, servname, hints, res, result);
+
+ if (node_lowered) HeapFree(GetProcessHeap(), 0, nodename);
+ if (serv_lowered) HeapFree(GetProcessHeap(), 0, servname);
+
+ if (!result) {
+ struct addrinfo *xuai = unixaires;
+ struct WS_addrinfo **xai = res;
+
+ *xai = NULL;
+ while (xuai) {
+ struct WS_addrinfo *ai = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(struct WS_addrinfo));
+ int len;
+
+ if (!ai)
+ goto outofmem;
+
+ *xai = ai;xai = &ai->ai_next;
+ ai->ai_flags = xuai->ai_flags;
+ ai->ai_family = xuai->ai_family;
+ ai->ai_socktype = xuai->ai_socktype;
+ ai->ai_protocol = xuai->ai_protocol;
+ if (xuai->ai_canonname) {
+ TRACE("canon name - %s\n",debugstr_a(xuai->ai_canonname));
+ ai->ai_canonname = HeapAlloc(GetProcessHeap(),0,strlen(xuai->ai_canonname)+1);
+ if (!ai->ai_canonname)
+ goto outofmem;
+ strcpy(ai->ai_canonname,xuai->ai_canonname);
+ }
+ len = xuai->ai_addrlen;
+ ai->ai_addr = HeapAlloc(GetProcessHeap(),0,len);
+ if (!ai->ai_addr)
+ goto outofmem;
+ ai->ai_addrlen = len;
+ do {
+ int winlen = ai->ai_addrlen;
+
+ if (!ws_sockaddr_u2ws(xuai->ai_addr, xuai->ai_addrlen, ai->ai_addr, &winlen))
+ break;
+ len = 2*len;
+ ai->ai_addr = HeapReAlloc(GetProcessHeap(),0,ai->ai_addr,len);
+ if (!ai->ai_addr)
+ goto outofmem;
+ ai->ai_addrlen = len;
+ } while (1);
+ xuai = xuai->ai_next;
+ }
+ freeaddrinfo(unixaires);
+ }
+ return result;
+
+outofmem:
+ if (*res) WS_freeaddrinfo(*res);
+ if (unixaires) freeaddrinfo(unixaires);
+ *res = NULL;
+ return WSA_NOT_ENOUGH_MEMORY;
+#else
+ FIXME("getaddrinfo() failed, not found during buildtime.\n");
+ return EAI_FAIL;
+#endif
+}
+
+/***********************************************************************
+ * GetAddrInfoW (WS2_32.@)
+ */
+int WINAPI GetAddrInfoW(WCHAR *nodename, WCHAR *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ FIXME("empty stub!\n");
+ return EAI_FAIL;
+}
/***********************************************************************
* getservbyport (WS2_32.56)
Index: dlls/winsock/ws2_32.spec
===================================================================
RCS file: /home/wine/wine/dlls/winsock/ws2_32.spec,v
retrieving revision 1.42
diff -u -r1.42 ws2_32.spec
--- dlls/winsock/ws2_32.spec 1 Aug 2005 10:56:49 -0000 1.42
+++ dlls/winsock/ws2_32.spec 11 Nov 2005 08:28:16 -0000
@@ -113,6 +113,8 @@
@ stub WSCUpdateProvider
@ stub WSCWriteNameSpaceOrder
@ stdcall WSCWriteProviderOrder(ptr long)
-@ stub freeaddrinfo
-@ stub getaddrinfo
+@ stdcall freeaddrinfo(ptr) WS_freeaddrinfo
+@ stdcall getaddrinfo(str str ptr ptr) GetAddrInfoA
+@ stdcall GetAddrInfoW(wstr wstr ptr ptr)
+@ stdcall GetAddrInfoA(str str ptr ptr)
@ stub getnameinfo
More information about the wine-patches
mailing list