|
8 | 8 | * |
9 | 9 | * |
10 | 10 | * IDENTIFICATION |
11 | | - * $PostgreSQL: pgsql/src/backend/libpq/ip.c,v 1.43 2009/01/01 17:23:42 momjian Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/libpq/ip.c,v 1.44 2009/01/23 19:58:06 tgl Exp $ |
12 | 12 | * |
13 | 13 | * This file and the IPV6 implementation were initially provided by |
14 | 14 | * Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design |
@@ -74,36 +74,46 @@ pg_getaddrinfo_all(const char *hostname, const char *servname, |
74 | 74 | returngetaddrinfo_unix(servname,hintp,result); |
75 | 75 | #endif |
76 | 76 |
|
| 77 | +#ifndef_AIX |
77 | 78 | /* NULL has special meaning to getaddrinfo(). */ |
78 | 79 | rc=getaddrinfo((!hostname||hostname[0]=='\0') ?NULL :hostname, |
79 | 80 | servname,hintp,result); |
80 | 81 |
|
81 | | -#ifdef_AIX |
| 82 | +#else/*_AIX */ |
82 | 83 |
|
83 | 84 | /* |
84 | | - * It seems some versions of AIX's getaddrinfo don't reliably zero |
85 | | - * sin_port when servname is NULL, so clean up after it. |
| 85 | + * Various versions of AIX have various bugs in getaddrinfo()'s handling |
| 86 | + * of the servname parameter, including failing entirely if it's not NULL |
| 87 | + * and failing to zero sin_port when it is NULL :-(. Avoid these by |
| 88 | + * always passing NULL and handling the port number for ourselves. |
86 | 89 | */ |
87 | | -if (servname==NULL&&rc==0) |
| 90 | +rc=getaddrinfo((!hostname||hostname[0]=='\0') ?NULL :hostname, |
| 91 | +NULL,hintp,result); |
| 92 | + |
| 93 | +if (rc==0) |
88 | 94 | { |
89 | 95 | structaddrinfo*addr; |
| 96 | +unsigned shortport=0; |
| 97 | + |
| 98 | +if (servname&&*servname) |
| 99 | +port=atoi(servname); |
90 | 100 |
|
91 | 101 | for (addr=*result;addr;addr=addr->ai_next) |
92 | 102 | { |
93 | 103 | switch (addr->ai_family) |
94 | 104 | { |
95 | 105 | caseAF_INET: |
96 | | -((structsockaddr_in*)addr->ai_addr)->sin_port=htons(0); |
| 106 | +((structsockaddr_in*)addr->ai_addr)->sin_port=htons(port); |
97 | 107 | break; |
98 | 108 | #ifdefHAVE_IPV6 |
99 | 109 | caseAF_INET6: |
100 | | -((structsockaddr_in6*)addr->ai_addr)->sin6_port=htons(0); |
| 110 | +((structsockaddr_in6*)addr->ai_addr)->sin6_port=htons(port); |
101 | 111 | break; |
102 | 112 | #endif |
103 | 113 | } |
104 | 114 | } |
105 | 115 | } |
106 | | -#endif |
| 116 | +#endif/* _AIX */ |
107 | 117 |
|
108 | 118 | returnrc; |
109 | 119 | } |
|