55 * found in the LICENSE file. 
66 */ 
77
8+ #define  _GNU_SOURCE 
9+ 
10+ #include  <assert.h> 
811#include  <arpa/inet.h> 
912#include  <sys/socket.h> 
1013#include  <assert.h> 
1114#include  <errno.h> 
1215#include  <netdb.h> 
16+ #include  <stdbool.h> 
1317#include  <stdio.h> 
1418#include  <stdlib.h> 
1519#include  <string.h> 
16- #ifdef  __EMSCRIPTEN__ 
17- #include  <emscripten.h> 
18- #endif 
20+ #include  <netdb.h> 
21+ 
22+ void  print_sockaddr (struct  sockaddr_in  * sa4 , int  socktype , int  counter ) {
23+   printf ("addr[%d] v4: (socktype=%d family=%d) %s:%d\n" , counter , socktype , sa4 -> sin_family , inet_ntoa (sa4 -> sin_addr ), ntohs (sa4 -> sin_port ));
24+ }
25+ 
26+ void  print_sockaddr6 (struct  sockaddr_in6  * sa6 , int  socktype , int  counter ) {
27+   char  buf [1024 ];
28+   printf ("addr[%d] v6: (socktype=%d family=%d) %s:%d\n" , counter , socktype , sa6 -> sin6_family , inet_ntop (sa6 -> sin6_family , & sa6 -> sin6_addr , buf , sizeof (buf )), ntohs (sa6 -> sin6_port ));
29+ }
30+ 
31+ void  print_addrinfo_next (struct  addrinfo  * info , int  counter ) {
32+   if  (info -> ai_family  ==  AF_INET ) {
33+     print_sockaddr (((struct  sockaddr_in * )info -> ai_addr ), info -> ai_socktype , counter );
34+   } else  if  (info -> ai_family  ==  AF_INET6 ) {
35+     print_sockaddr6 (((struct  sockaddr_in6 * )info -> ai_addr ), info -> ai_socktype , counter );
36+   } else  {
37+     assert (false);
38+   }
39+   if  (info -> ai_next ) {
40+     print_addrinfo_next (info -> ai_next , counter + 1 );
41+   }
42+ }
43+ 
44+ void  print_addrinfo (struct  addrinfo  * info ) {
45+   print_addrinfo_next (info , 0 );
46+ }
47+ 
48+ #define  CHECK_ERR (code , expected )                                              \
49+   do {                                                                         \
50+     const char* err = gai_strerror(code);                                      \
51+     printf("%s -> %s\n", #code, err);                                          \
52+     assert(strcmp(err, expected) == 0);                                        \
53+   } while (0)
1954
2055int  main () {
2156  struct  addrinfo  hints ;
@@ -24,9 +59,15 @@ int main() {
2459  struct  sockaddr_in6  * sa6 ;
2560  int  err ;
2661
62+   char  buf [1024 ];
63+   printf ("in6addr_loopback: %s\n" , inet_ntop (AF_INET6 , & in6addr_loopback , buf , sizeof (buf )));
64+ 
2765  // no name or service 
2866  //err = getaddrinfo(NULL, NULL, NULL, &servinfo); 
29-   // XXX musl follows the spec precisely, and it does not allow both to be NULL, despite documenting EAI_NONAME as the right result for that case  assert(err == EAI_NONAME); 
67+ 
68+   // XXX musl follows the spec precisely, and it does not allow both to be NULL, 
69+   // despite documenting EAI_NONAME as the right result for that case 
70+   // assert(err == EAI_NONAME); 
3071
3172  // invalid socket type 
3273  memset (& hints , 0 , sizeof (hints ));
@@ -63,6 +104,7 @@ int main() {
63104  hints .ai_socktype  =  SOCK_STREAM ;
64105  err  =  getaddrinfo (NULL , "80" , & hints , & servinfo );
65106  assert (!err );
107+   print_addrinfo (servinfo );
66108  sa4  =  ((struct  sockaddr_in * )servinfo -> ai_addr );
67109  assert (servinfo -> ai_family  ==  AF_INET );
68110  assert (servinfo -> ai_socktype  ==  SOCK_STREAM );
@@ -77,9 +119,13 @@ int main() {
77119  err  =  getaddrinfo (NULL , "81" , & hints , & servinfo );
78120  assert (!err );
79121  sa6  =  ((struct  sockaddr_in6 * )servinfo -> ai_addr );
122+   print_addrinfo (servinfo );
80123  assert (servinfo -> ai_family  ==  AF_INET6 );
81124  assert (servinfo -> ai_socktype  ==  SOCK_STREAM );
82-   memcmp (& sa6 -> sin6_addr , & in6addr_loopback , sizeof (in6addr_loopback ));
125+ #ifndef  __EMSCRIPTEN__ 
126+   // TODO(sbc): This assert currently fails under emscripten, but should not 
127+   assert (memcmp (& sa6 -> sin6_addr , & in6addr_loopback , sizeof (in6addr_loopback )) ==  0 );
128+ #endif 
83129  assert (sa6 -> sin6_port  ==  ntohs (81 ));
84130  freeaddrinfo (servinfo );
85131
@@ -91,6 +137,7 @@ int main() {
91137  err  =  getaddrinfo (NULL , "82" , & hints , & servinfo );
92138  assert (!err );
93139  sa4  =  ((struct  sockaddr_in * )servinfo -> ai_addr );
140+   print_addrinfo (servinfo );
94141  assert (servinfo -> ai_family  ==  AF_INET );
95142  assert (servinfo -> ai_socktype  ==  SOCK_STREAM );
96143  assert (* (uint32_t * )& (sa4 -> sin_addr ) ==  0 );
@@ -104,6 +151,7 @@ int main() {
104151  err  =  getaddrinfo ("1.2.3.4" , "83" , & hints , & servinfo );
105152  assert (!err );
106153  sa4  =  ((struct  sockaddr_in * )servinfo -> ai_addr );
154+   print_addrinfo (servinfo );
107155  assert (servinfo -> ai_family  ==  AF_INET );
108156  assert (servinfo -> ai_socktype  ==  SOCK_DGRAM );
109157  assert (* (uint32_t * )& (sa4 -> sin_addr ) ==  67305985 );
@@ -118,6 +166,7 @@ int main() {
118166  err  =  getaddrinfo ("1.2.3.4" , "84" , & hints , & servinfo );
119167  assert (!err );
120168  sa6  =  ((struct  sockaddr_in6 * )servinfo -> ai_addr );
169+   print_addrinfo (servinfo );
121170  assert (servinfo -> ai_family  ==  AF_INET6 );
122171  assert (servinfo -> ai_socktype  ==  SOCK_STREAM );
123172  assert (* ((uint32_t * )& (sa6 -> sin6_addr )+ 2 ) ==  htonl (0xffff ));
@@ -143,6 +192,7 @@ int main() {
143192  err  =  getaddrinfo ("2001:0db8:85a3:0042:1000:8a2e:0370:7334" , "86" , & hints , & servinfo );
144193  assert (!err );
145194  sa6  =  ((struct  sockaddr_in6 * )servinfo -> ai_addr );
195+   print_addrinfo (servinfo );
146196  assert (servinfo -> ai_family  ==  AF_INET6 );
147197  assert (servinfo -> ai_socktype  ==  SOCK_DGRAM );
148198  assert (* ((uint32_t * )& (sa6 -> sin6_addr )+ 0 ) ==  -1207107296 );
@@ -178,6 +228,7 @@ int main() {
178228  err  =  getaddrinfo ("www.mozilla.org" , "89" , & hints , & servinfo );
179229  assert (!err );
180230  sa4  =  ((struct  sockaddr_in * )servinfo -> ai_addr );
231+   print_addrinfo (servinfo );
181232  assert (servinfo -> ai_family  ==  AF_INET );
182233  assert (servinfo -> ai_socktype  ==  SOCK_STREAM );
183234  assert (sa4 -> sin_port  ==  ntohs (89 ));
@@ -187,9 +238,10 @@ int main() {
187238  memset (& hints , 0 , sizeof (hints ));
188239  hints .ai_family  =  AF_INET6 ;
189240  hints .ai_socktype  =  SOCK_STREAM ;
190-   err  =  getaddrinfo ("www.mozilla.org " , "90" , & hints , & servinfo );
241+   err  =  getaddrinfo ("www.google.com " , "90" , & hints , & servinfo );
191242  assert (!err );
192243  sa6  =  ((struct  sockaddr_in6 * )servinfo -> ai_addr );
244+   print_addrinfo (servinfo );
193245  assert (servinfo -> ai_family  ==  AF_INET6 );
194246  assert (servinfo -> ai_socktype  ==  SOCK_STREAM );
195247  assert (* ((uint32_t * )& (sa6 -> sin6_addr )+ 0 ) !=  0  || 
@@ -210,52 +262,55 @@ int main() {
210262  // test numeric host 
211263  err  =  getaddrinfo ("1.2.3.4" , "85" , NULL , & servinfo );
212264  assert (!err );
265+   print_addrinfo (servinfo );
213266  sa4  =  ((struct  sockaddr_in * )servinfo -> ai_addr );
214267  assert (servinfo -> ai_family  ==  AF_INET );
215268  assert (servinfo -> ai_socktype  ==  SOCK_STREAM );
216269  assert (servinfo -> ai_protocol  ==  IPPROTO_TCP );
217270  assert (sa4 -> sin_port  ==  ntohs (85 ));
218-   assert (servinfo -> ai_next  ==  NULL );
219271  freeaddrinfo (servinfo );
220272
221273  // test non-numeric host 
222274  err  =  getaddrinfo ("www.mozilla.org" , "89" , NULL , & servinfo );
223275  assert (!err );
276+   print_addrinfo (servinfo );
224277  sa4  =  ((struct  sockaddr_in * )servinfo -> ai_addr );
225278  assert (servinfo -> ai_family  ==  AF_INET );
226279  assert (servinfo -> ai_socktype  ==  SOCK_STREAM );
227280  assert (servinfo -> ai_protocol  ==  IPPROTO_TCP );
228281  assert (sa4 -> sin_port  ==  ntohs (89 ));
229-   assert (servinfo -> ai_next  ==  NULL );
230282  freeaddrinfo (servinfo );
231283
232284  // test loopback resolution 
233-   err  =  getaddrinfo (NULL , "80" , NULL , & servinfo );
285+   hints .ai_family  =  AF_INET ;
286+   err  =  getaddrinfo (NULL , "80" , & hints , & servinfo );
234287  assert (!err );
288+   print_addrinfo (servinfo );
235289  sa4  =  ((struct  sockaddr_in * )servinfo -> ai_addr );
236290  assert (servinfo -> ai_family  ==  AF_INET );
237291  assert (servinfo -> ai_socktype  ==  SOCK_STREAM );
238292  assert (servinfo -> ai_protocol  ==  IPPROTO_TCP );
239293  assert (sa4 -> sin_port  ==  ntohs (80 ));
240-   assert (servinfo -> ai_next  ==  NULL );
241294  freeaddrinfo (servinfo );
242295
296+ #ifdef  __EMSCRIPTEN__ 
243297  // test gai_strerror 
244-   assert (strcmp (gai_strerror (0 ), "Unknown error" ) ==  0 );
245-   assert (strcmp (gai_strerror (EAI_BADFLAGS ), "Invalid flags" ) ==  0 );
246-   assert (strcmp (gai_strerror (EAI_NONAME ), "Name does not resolve" ) ==  0 );
247-   assert (strcmp (gai_strerror (EAI_AGAIN ), "Try again" ) ==  0 );
248-   assert (strcmp (gai_strerror (EAI_FAIL ), "Non-recoverable error" ) ==  0 );
249-   assert (strcmp (gai_strerror (EAI_FAMILY ), "Unrecognized address family or invalid length" ) ==  0 );
250-   assert (strcmp (gai_strerror (EAI_SOCKTYPE ), "Unrecognized socket type" ) ==  0 );
251-   assert (strcmp (gai_strerror (EAI_SERVICE ), "Unrecognized service" ) ==  0 );
252-   assert (strcmp (gai_strerror (EAI_MEMORY ), "Out of memory" ) ==  0 );
253-   assert (strcmp (gai_strerror (EAI_SYSTEM ), "System error" ) ==  0 );
254-   assert (strcmp (gai_strerror (EAI_OVERFLOW ), "Overflow" ) ==  0 );
255-   assert (strcmp (gai_strerror (EAI_NODATA ), "Name has no usable address" ) ==  0 );
256-   assert (strcmp (gai_strerror (-9 ), "Unknown error" ) ==  0 );
257-   assert (strcmp (gai_strerror (-13 ), "Unknown error" ) ==  0 );
258-   assert (strcmp (gai_strerror (-100 ), "Unknown error" ) ==  0 );
298+   CHECK_ERR (0 , "Unknown error" );
299+   CHECK_ERR (EAI_BADFLAGS , "Invalid flags" );
300+   CHECK_ERR (EAI_NONAME , "Name does not resolve" );
301+   CHECK_ERR (EAI_AGAIN , "Try again" );
302+   CHECK_ERR (EAI_FAIL , "Non-recoverable error" );
303+   CHECK_ERR (EAI_FAMILY , "Unrecognized address family or invalid length" );
304+   CHECK_ERR (EAI_SOCKTYPE , "Unrecognized socket type" );
305+   CHECK_ERR (EAI_SERVICE , "Unrecognized service" );
306+   CHECK_ERR (EAI_MEMORY , "Out of memory" );
307+   CHECK_ERR (EAI_SYSTEM , "System error" );
308+   CHECK_ERR (EAI_OVERFLOW , "Overflow" );
309+   CHECK_ERR (EAI_NODATA , "Name has no usable address" );
310+   CHECK_ERR (-9 , "Unknown error" );
311+   CHECK_ERR (-13 , "Unknown error" );
312+   CHECK_ERR (-100 , "Unknown error" );
313+ #endif 
259314
260315  puts ("success" );
261316
0 commit comments