Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition)
11.19 gethostbyname_r and gethostbyaddr_r Functions
There are two ways to make a nonre-entrant function such as gethostbyname re-entrant .
We will now discuss the Solaris 2.x re-entrant functions for name-to-address and address-to-name resolution.
Four additional arguments are required for each function. result is a hostent structure allocated by the caller. It is filled in by the function. On success, this pointer is also the return value of the function. buf is a buffer allocated by the caller and buflen is its size. This buffer will contain the c nonical hostname, the alias pointers, the alias strings, the address pointers, and the actual addresses. All the pointers in the structure pointed to by result point into this buffer. How big should this buffer be? Unfortunately, all that most man pages say is something vague like, "The buffer must be large enough to hold all of the data associated with the host entry." Current implementations of gethostbyname can return up to 35 alias pointers and 35 address pointers, and internally use an 8192-byte buffer to hold alias names and addresses. So, a buffer size of 8192 bytes should be adequate. If an error occurs, the error code is returned through the h_errnop pointer, not through the global h_errno . Unfortunately, this problem of re-entrancy is even worse than it appears. First, there is no standard regarding re-entrancy and gethostbyname and gethostbyaddr . The POSIX specification says that gethostbyname and gethostbyaddr need not be re-entrant. Unix 98 just says that these two functions need not be thread-safe. Second, there is no standard for the _r functions. What we have shown in this section (for example purposes) are two of the _r functions provided by Solaris 2.x. Linux provides similar _r functions, except that instead of returning the hostent as the return value of the function, the hostent is returned using a value-result parameter as the next to last function argument. It returns the success of the lookup as the return value from the function as well as in the h_errno argument. Digital Unix 4.0 and HP-UX 10.30 have versions of these functions with different arguments. The first two arguments for gethostbyname_r are the same as the Solaris version, but the remaining three arguments for the Solaris version are combined into a new hostent_data structure (which must be allocated by the caller), and a pointer to this structure is the third and final argument. The normal functions gethostbyname and gethostbyaddr in Digital Unix 4.0 and HP-UX 10.30 are re-entrant by using thread-specific data (Section 26.5). An interesting history of the development of the Solaris 2.x _r functions is in [Maslen 1997]. Lastly, while a re-entrant version of gethostbyname may provide safety from different threads calling it at the same time, this says nothing about the re-entrancy of the underlying resolver functions. |