1 | /* Test case for gethostbyname_r bug when buffer expansion required. */ |
2 | |
3 | #include <netdb.h> |
4 | #include <arpa/inet.h> |
5 | #include <errno.h> |
6 | #include <string.h> |
7 | #include <stdio.h> |
8 | #include <stdlib.h> |
9 | #include <unistd.h> |
10 | |
11 | int |
12 | main (void) |
13 | { |
14 | const char *host = "www.gnu.org" ; |
15 | |
16 | /* This code approximates the example code in the library manual. */ |
17 | |
18 | struct hostent hostbuf, *hp; |
19 | size_t hstbuflen; |
20 | char *tmphstbuf; |
21 | int res; |
22 | int herr; |
23 | |
24 | hstbuflen = 16; /* Make it way small to ensure ERANGE. */ |
25 | /* Allocate buffer, remember to free it to avoid memory leakage. */ |
26 | tmphstbuf = malloc (size: hstbuflen); |
27 | |
28 | while ((res = gethostbyname_r (name: host, result_buf: &hostbuf, buf: tmphstbuf, buflen: hstbuflen, |
29 | result: &hp, h_errnop: &herr)) == ERANGE) |
30 | { |
31 | /* Enlarge the buffer. */ |
32 | hstbuflen *= 2; |
33 | tmphstbuf = realloc (ptr: tmphstbuf, size: hstbuflen); |
34 | } |
35 | |
36 | if (res != 0 || hp == NULL) |
37 | { |
38 | printf (format: "gethostbyname_r failed: %s (errno: %m)\n" , strerror (errnum: res)); |
39 | |
40 | if (access (name: "/etc/resolv.conf" , R_OK)) |
41 | { |
42 | puts (s: "DNS probably not set up" ); |
43 | return 0; |
44 | } |
45 | |
46 | return 1; |
47 | } |
48 | |
49 | printf (format: "Got: %s %s\n" , hp->h_name, |
50 | inet_ntoa (in: *(struct in_addr *) hp->h_addr)); |
51 | return 0; |
52 | } |
53 | |