Portable gethostname()

While gethostname() is present on almost all systems, it cannot be used directly in a portable way. The problems stem from differences in what is done when the caller does not provide a buffer large enough to contain the entire hostname. Most man pages say that the resulting hostname will be "truncated" when the buffer is too small. The definition of "truncate" varies from system to system and sometimes the system does not even behave as described in the man page.

Some systems provide a manifest constant such as MAXHOSTNAMELEN, which is meant to be used when allocating the buffer. Unfortunately, this constant is not located in a consistent place. On some systems it is in <sys/param.h>, and in others it is in <netdb.h>. Many systems don't bother to define a constant at all. On these systems, the man page usually instructs the programmer to use some magic number such as 256.

Experiments

Experiments were done on a number of systems to see how short buffers are handled. Here is a listing of the different things that happen:

Solution

To use gethostname() portably we must write a wrapper function which does two things:

We can use an algorithm that repeatedly calls gethostname() with ever bigger buffers until it is clear the hostname has not been truncated.

pgethostname.c is an implementation that has been tested several UNIX-like systems. It should compile without change on all modern systems.

pgethostname.man is a man page for pgethostname().