Protecting the world

from criminally bad code

uname

Synopsis

#include <sys/utsname.h>

int uname(struct utsname* name);

Description

The uname function populates a struct utsname with the following information about the local system:

  • the hostname;
  • the name and version of the operating system it is running; and
  • the type of hardware on which it is running.

Pitfalls

Buffers of the utsname structure may be too short

The information returned by uname is written into fixed-length buffers within the utsname structure. POSIX warns of the possibility that the space allowed for the hostname could be insufficient.

The buffer lengths are accessible to uname, so assuming a competent implementation there should be no risk of a buffer overrun. However, since neither the caller nor the callee are able to adjust the buffer lengths, the caller’s options are likely to be limited if they are too short.

The correct course of action under these circumstances is for uname to return -1. This unfortunately means that the caller cannot rely on any of the content of the utsname, but that is preferable to being told that the information was returned successfully when it was not.

(Ideally the implementation would prevent the hostname or any of the other fields from being set to a value that uname cannot return, but this is not necessarilly something that the POSIX library by itself has the ability to control.)

The hostname may or may not be fully qualified

On modern systems the hostname is often a DNS domain name with multiple components. Such names can be expressed in three ways:

  • In fully-qualified form, where all of the components are listed.
  • In unqualified form, where only the first component is listed.
  • In partially-qualified form, where some but not all of the components are listed.

POSIX does not specify which of these forms should be returned by uname. Some implementations do, but they are split between use of the unqualified name and the fully-qualified name.

For this reason, programs should be written to allow for the possibility that the hostname may or may not be qualified. This is can be done by canonicalising the result using uname, which will convert it to fully qualified form if that is possible.

Alternatives

Using gethostname

The gethostname function is not a full replacement for uname, however it does provide an alternative method for obtaining just the hostname, and it does allow the buffer length to be varied by the caller.

gethostname has a number of pitfalls of its own, making it not entirely straightforward to use, but unlike uname these can be worked around with care. Its main drawback is that it is not as widely available as uname, but this can be countered by using uname as a fallback.

Portability

  •  C90
  •  C99
  •  C++98
  •  C++11
  •  POSIX:1988
  •  POSIX:1990
  •  POSIX:2001
  •  POSIX:2008
  •  SVID1
  •  SVID2
  •  SVID3
  •  SVID4
  •  XPG3
  •  XPG4
  •  XPG4v2
  •  XPG5
  •  SUSv2
  •  SUSv3
  •  SUSv4

Further reading

  • uname, The Open Group Base Specifications, Issue 7, The Open Group, 2008
  • uname(2), Linux Programmer’s Manual, The Linux man-pages project
  • Platform Type Identification, The GNU C Library Reference Manual, The GNU Project