Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   unix    ( 7 )

сокеты для локального межпроцессного взаимодействия (sockets for local interprocess communication)

  Name  |  Synopsis  |  Description  |  Error  |  Versions  |  Note  |    Bugs    |  Examples  |  See also  |

Ошибки (баги) (Bugs)

When binding a socket to an address, Linux is one of the implementations that appends a null terminator if none is supplied in sun_path. In most cases this is unproblematic: when the socket address is retrieved, it will be one byte longer than that supplied when the socket was bound. However, there is one case where confusing behavior can result: if 108 non-null bytes are supplied when a socket is bound, then the addition of the null terminator takes the length of the pathname beyond sizeof(sun_path). Consequently, when retrieving the socket address (for example, via accept(2)), if the input addrlen argument for the retrieving call is specified as sizeof(struct sockaddr_un), then the returned address structure won't have a null terminator in sun_path.

In addition, some implementations don't require a null terminator when binding a socket (the addrlen argument is used to determine the length of sun_path) and when the socket address is retrieved on these implementations, there is no null terminator in sun_path.

Applications that retrieve socket addresses can (portably) code to handle the possibility that there is no null terminator in sun_path by respecting the fact that the number of valid bytes in the pathname is:

strnlen(addr.sun_path, addrlen - offsetof(sockaddr_un, sun_path))

Alternatively, an application can retrieve the socket address by allocating a buffer of size sizeof(struct sockaddr_un)+1 that is zeroed out before the retrieval. The retrieving call can specify addrlen as sizeof(struct sockaddr_un), and the extra zero byte ensures that there will be a null terminator for the string returned in sun_path:

void *addrp;

addrlen = sizeof(struct sockaddr_un); addrp = malloc(addrlen + 1); if (addrp == NULL) /* Handle error */ ; memset(addrp, 0, addrlen + 1);

if (getsockname(sfd, (struct sockaddr *) addrp, &addrlen)) == -1) /* handle error */ ;

printf("sun_path = %s\n", ((struct sockaddr_un *) addrp)->sun_path);

This sort of messiness can be avoided if it is guaranteed that the applications that create pathname sockets follow the rules outlined above under Pathname sockets.