From: David Nadlinger Subject: ws2_32: getaddrinfo(NULL, "", ...) on OS X. Message-Id: <4F2AAC08.1050603@klickverbot.at> Date: Thu, 02 Feb 2012 16:30:16 +0100 If getaddrinfo() is passed a null host and an empty port string, it still resolves to 127.0.0.1/0.0.0.0 on Windows and Linux, but fails on OS X. The added workaround (rewriting the port to "0") works on both Linux and OS X. Tested on OS X 10.7.2, Arch Linux (Kernel 3.1.4, glibc 2.14.1) and Ubuntu Oneric, and verified against Windows Server 2008 R2. See http://klickverbot.at/p/getaddrinfo for a detailed comparison of the edge case behavior on the different OSes. --- dlls/ws2_32/socket.c | 9 +++++++-- dlls/ws2_32/tests/sock.c | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 81e5d1c..48c337d 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -4824,7 +4824,7 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr int result; struct addrinfo unixhints, *punixhints = NULL; char *hostname = NULL; - const char *node; + const char *node, *serv; if (!nodename && !servname) return WSAHOST_NOT_FOUND; @@ -4838,6 +4838,11 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr else node = nodename; + if (!nodename && !servname[0]) + serv = "0"; + else + serv = servname; + if (hints) { punixhints = &unixhints; @@ -4858,7 +4863,7 @@ int WINAPI WS_getaddrinfo(LPCSTR nodename, LPCSTR servname, const struct WS_addr } /* getaddrinfo(3) is thread safe, no need to wrap in CS */ - result = getaddrinfo(node, servname, punixhints, &unixaires); + result = getaddrinfo(node, serv, punixhints, &unixaires); TRACE("%s, %s %p -> %p %d\n", debugstr_a(nodename), debugstr_a(servname), hints, res, result); HeapFree(GetProcessHeap(), 0, hostname); diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 2de23c9..69db59d 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4236,6 +4236,12 @@ static void test_getaddrinfo(void) pfreeaddrinfo(result); result = NULL; + ret = pgetaddrinfo(NULL, "", NULL, &result); + ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); + ok(result != NULL, "getaddrinfo failed\n"); + pfreeaddrinfo(result); + + result = NULL; ret = pgetaddrinfo(NULL, "0", NULL, &result); ok(!ret, "getaddrinfo failed with %d\n", WSAGetLastError()); ok(result != NULL, "getaddrinfo failed\n");