summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2009-01-23 19:58:06 +0000
committerTom Lane2009-01-23 19:58:06 +0000
commitd23486fcd95d18ef5dfe1bb45fbd44da4db9a189 (patch)
treed947b8d2224cef144f2de61b1d48edd01db1b948
parenta4889a2988b049292389e7ef5d64c9988b97b582 (diff)
Tweak the existing special case for AIX in pg_getaddrinfo_all() to handle
yet another failure case in AIX's getaddrinfo(). Per report and patch by Andrew Chernow.
-rw-r--r--src/backend/libpq/ip.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/backend/libpq/ip.c b/src/backend/libpq/ip.c
index 192b73003f..f0302cde09 100644
--- a/src/backend/libpq/ip.c
+++ b/src/backend/libpq/ip.c
@@ -74,36 +74,46 @@ pg_getaddrinfo_all(const char *hostname, const char *servname,
return getaddrinfo_unix(servname, hintp, result);
#endif
+#ifndef _AIX
/* NULL has special meaning to getaddrinfo(). */
rc = getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
servname, hintp, result);
-#ifdef _AIX
+#else /* _AIX */
/*
- * It seems some versions of AIX's getaddrinfo don't reliably zero
- * sin_port when servname is NULL, so clean up after it.
+ * Various versions of AIX have various bugs in getaddrinfo()'s handling
+ * of the servname parameter, including failing entirely if it's not NULL
+ * and failing to zero sin_port when it is NULL :-(. Avoid these by
+ * always passing NULL and handling the port number for ourselves.
*/
- if (servname == NULL && rc == 0)
+ rc = getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
+ NULL, hintp, result);
+
+ if (rc == 0)
{
struct addrinfo *addr;
+ unsigned short port = 0;
+
+ if (servname && *servname)
+ port = atoi(servname);
for (addr = *result; addr; addr = addr->ai_next)
{
switch (addr->ai_family)
{
case AF_INET:
- ((struct sockaddr_in *) addr->ai_addr)->sin_port = htons(0);
+ ((struct sockaddr_in *) addr->ai_addr)->sin_port = htons(port);
break;
#ifdef HAVE_IPV6
case AF_INET6:
- ((struct sockaddr_in6 *) addr->ai_addr)->sin6_port = htons(0);
+ ((struct sockaddr_in6 *) addr->ai_addr)->sin6_port = htons(port);
break;
#endif
}
}
}
-#endif
+#endif /* _AIX */
return rc;
}