The so-called abstract namespace is a Linux-specific feature that allows us to bind a UNIX domain socket to a name without that name being created in the file system. This provides a few potential advantages:
We don’t need to worry about possible collisions with existing names in the file system.
It is not necessary to unlink the socket pathname when we have finished using the socket. The abstract name is automatically removed when the socket is closed.
We don’t need to create a file-system pathname for the socket. This may be useful in a chroot environment, or if we don’t have write access to a file system.
To create an abstract binding, we specify the first byte of the sun_path field as a null byte (\0
). This distinguishes abstract socket names from conventional UNIX domain socket pathnames, which consist of a string of one or more nonnull bytes terminated by a null byte. The name of the abstract socket is then defined by the remaining bytes (including any null bytes) in sun_path up to the length defined for the size of the address structure (i.e., addrlen - sizeof(sa_family_t)).
Example 57-8 demonstrates the creation of an abstract socket binding.
Example 57-8. Creating an abstract socket binding
fromsockets/us_abstract_bind.c
struct sockaddr_un addr; memset(&addr, 0, sizeof(struct sockaddr_un)); /* Clear address structure */ addr.sun_family = AF_UNIX; /* UNIX domain address */ /* addr.sun_path[0] has already been set to 0 by memset() */ str = "xyz"; /* Abstract name is "\0xyz" */ strncpy(&addr.sun_path[1], str, strlen (str)); sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sockfd == -1) errExit("socket"); if (bind(sockfd, (struct sockaddr *) &addr, sizeof(sa_family_t) + strlen(str) + 1) == -1) errExit("bind"); fromsockets/us_abstract_bind.c
The fact that an initial null byte is used to distinguish an abstract socket name from a conventional socket name can have an unusual consequence. Suppose that the variable name happens to point to a zero-length string and that we attempt to bind a UNIX domain socket to a sun_path initialized as follows:
strncpy(addr.sun_path, name, sizeof(addr.sun_path) - 1);
On Linux, we’ll inadvertently create an abstract socket binding. However, such a code sequence is probably unintentional (i.e., a bug). On other UNIX implementations, the subsequent bind() would fail.