|
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 | }
|
|