diff --git a/src/backend/libpq/ip.c b/src/backend/libpq/ip.c
index ef3ef04902cc5caa36502f6201c58724ca50e59f..67e92654d1c043aac83caee82005756595606947 100644
--- a/src/backend/libpq/ip.c
+++ b/src/backend/libpq/ip.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/libpq/ip.c,v 1.43 2009/01/01 17:23:42 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/libpq/ip.c,v 1.44 2009/01/23 19:58:06 tgl Exp $
  *
  * This file and the IPV6 implementation were initially provided by
  * Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
@@ -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;
 }