Man page - unix(7)

Packages contains this manual

Available languages:

en fr pl ja ru zh_TW zh_CN

Manual

UNIX

NOM
SYNOPSIS
DESCRIPTION
Formats d’adresse
Sockets chemin d’accùs
Permissions et appartenance des sockets chemin d’accùs
Sockets abstraits
Options de socket
FonctionnalitĂ© d’autolien (« autobind »)
API des sockets
Messages annexes
Ioctls
ERREURS
VERSIONS
NOTES
BOGUES
EXEMPLES
Sortie de l’exemple
Source du programme
VOIR AUSSI
TRADUCTION

NOM

unix – Sockets pour communications locales entre processus

SYNOPSIS

#include <sys/socket.h>
#include <sys/un.h>

unix_socket = socket(AF_UNIX, type, 0);
error
= socketpair(AF_UNIX, type, 0, int * sv );

DESCRIPTION

La famille de sockets AF_UNIX (aussi connue sous le nom de AF_LOCAL ) sert Ă  communiquer efficacement entre processus sur la mĂȘme machine. Traditionnellement, les sockets de domaine UNIX peuvent ne pas ĂȘtre nommĂ©s ou bien ĂȘtre liĂ©s Ă  un chemin d’accĂšs de systĂšme de fichiers, lequel sera marquĂ© comme Ă©tant de type socket. Linux gĂšre Ă©galement un espace de noms abstrait, indĂ©pendant du systĂšme de fichiers.

Les types de sockets valables dans le domaine UNIX sont : SOCK_STREAM pour un socket orientĂ© flux et SOCK_DGRAM pour un socket orientĂ© datagramme qui prĂ©serve les limites entre messages (comme sur la plupart des implĂ©mentations UNIX, les sockets datagramme de domaine UNIX sont toujours fiables et ne rĂ©ordonnent pas les datagrammes), et (depuis Linux 2.6.4) SOCK_SEQPACKET pour un socket orientĂ© connexion, prĂ©servant les limites entre messages et dĂ©livrant les messages dans l’ordre oĂč ils ont Ă©tĂ© envoyĂ©s.

Les sockets de domaine UNIX prennent en charge la transmission de descripteurs de fichier ou d’accrĂ©ditations d’un processus Ă  l’autre en utilisant des donnĂ©es annexes.

Formats d’adresse

Une adresse de socket de domaine UNIX est représentée dans la structure suivante :

struct sockaddr_un {
sa_family_t sun_family; /* AF_UNIX */
char sun_path[108]; /* Chemin d’accùs */
};

The sun_family field always contains AF_UNIX . On Linux, sun_path is 108 bytes in size; see also BUGS, below.

Various system calls (for example, bind (2), connect (2), and sendto (2)) take a sockaddr_un argument as input. Some other system calls (for example, getsockname (2), getpeername (2), recvfrom (2), and accept (2)) return an argument of this type.

Trois types d’adresse sont remarquables dans la structure sockaddr_un :
pathname

a UNIX domain socket can be bound to a null-terminated filesystem pathname using bind (2). When the address of a pathname socket is returned (by one of the system calls noted above), its length is

offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1

et sun_path contient le chemin avec un octet NULL final. (Dans Linux, l’expression ci-dessus offsetof () est Ă©gale Ă  la mĂȘme valeur que sizeof(sa_family_t) , mais quelques autres implĂ©mentations incluent d’autres champs avant sun_path , aussi l’expression offsetof () plus portable dĂ©crit la taille de la structure d’adresse.)

Pour plus de détails sur les sockets chemin, voir ci-aprÚs.

unnamed

A stream socket that has not been bound to a pathname using bind (2) has no name. Likewise, the two sockets created by socketpair (2) are unnamed. When the address of an unnamed socket is returned, its length is sizeof(sa_family_t) , and sun_path should not be inspected.

abstract

an abstract socket address is distinguished (from a pathname socket) by the fact that sun_path[0] is a null byte ('\0'). The socket’s address in this namespace is given by the additional bytes in sun_path that are covered by the specified length of the address structure. (Null bytes in the name have no special significance.) The name has no connection with filesystem pathnames. When the address of an abstract socket is returned, the returned addrlen is greater than sizeof(sa_family_t) (i.e., greater than 2), and the name of the socket is contained in the first (addrlen - sizeof(sa_family_t)) bytes of sun_path .

Sockets chemin d’accùs

Lors de la liaison d’un socket Ă  un chemin, quelques rĂšgles doivent ĂȘtre observĂ©es pour une portabilitĂ© maximale et une facilitĂ© de codage :

-

Le chemin dans sun_path doit ĂȘtre terminĂ© par un octet NULL ;

-

La taille du chemin, y compris l’octet NULL final, ne doit pas excĂ©der la taille de sun_path ;

-

L’argument addrlen dĂ©crivant la structure enfermant sockaddr_un doit avoir une valeur d’au moins :

offsetof(struct sockaddr_un, sun_path)+strlen(addr.sun_path)+1

ou, plus simplement, addrlen peut ĂȘtre indiquĂ© comme sizeof(struct sockaddr_un) .

Il y a quelques variations dans la façon dont les implĂ©mentations gĂšrent les adresses de socket de domaine UNIX qui ne suivent pas les rĂšgles ci-dessus.Par exemple, quelques implĂ©mentations (mais pas toutes) ajoutent un octet NULL final si aucun n’est prĂ©sent dans le sun_path fourni.

Lors du codage d’applications portables, il faut penser que certaines implĂ©mentations ont un sun_path aussi court que 92 octets.

Divers appels systĂšme ( accept (2), recvfrom (2), getsockname (2), getpeername (2)) renvoient les structures d’adresse de socket. Lorsque appliquĂ© Ă  des sockets de domaine UNIX, l’argument « value-result » addrlen fourni Ă  l’appel devrait ĂȘtre initialisĂ© comme ci-dessus. Au renvoi, l’argument est rĂ©glĂ© pour indiquer la taille rĂ©elle de la structure d’adresse. L’appelant devrait vĂ©rifier la valeur renvoyĂ©e dans cet argument. Si la valeur de sortie excĂšde la valeur d’entrĂ©e, alors il n’y a aucune garantie qu’un octet NULL final soit prĂ©sent dans sun_path . (Consultez BOGUES.)

Permissions et appartenance des sockets chemin d’accùs

Dans l’implĂ©mentation de Linux, les sockets chemin d’accĂšs respectent les permissions du rĂ©pertoire dans lequel ils sont. La crĂ©ation d’un nouveau socket Ă©choue si le processus n’a pas les permissions d’écriture et de recherche (exĂ©cution) dans le rĂ©pertoire oĂč le socket est créé.

Dans Linux, la connexion Ă  un objet de socket flux nĂ©cessite la permission en Ă©criture sur ce socket. De mĂȘme, l’envoi d’un datagramme Ă  un socket datagramme nĂ©cessite la permission en Ă©criture sur ce socket. POSIX ne fait aucune dĂ©claration sur les effets des permissions sur un fichier de socket, et sur certains systĂšmes (par exemple, les BSD anciens) les permissions de socket sont ignorĂ©es. Les programmes portables ne devraient pas se fier Ă  cette fonctionnalitĂ© pour la sĂ©curitĂ©.

Lors de la crĂ©ation d’un nouveau socket, le propriĂ©taire et le groupe d’un fichier de socket sont dĂ©finis selon les rĂšgles habituelles. Le fichier de socket a toutes les permissions activĂ©es, autres que celles dĂ©sactivĂ©es par le processus umask (2).

Le propriĂ©taire, le groupe et les permissions d’un socket chemin d’accĂšs peuvent ĂȘtre modifiĂ©s (avec chown (2) et chmod (2)).

Sockets abstraits

Les permissions de socket n’ont aucun sens pour les sockets abstraits : le processus umask (2) n’a aucun effet lors de la liaison d’un socket abstrait et modifier le propriĂ©taire et les permissions de l’objet (avec fchown (2) et fchmod (2)) n’a aucun effet sur l’accessibilitĂ© du socket.

Les sockets abstraits disparaissent automatiquement quand toutes les références de socket ouvertes sont refermées.

L’espace de noms de sockets abstraits est une extension non portable de Linux.

Options de socket

Pour des raisons historiques, les options de ces sockets sont indiquĂ©es avec un type SOL_SOCKET mĂȘme si elles sont spĂ©cifiques Ă  AF_UNIX . Elles peuvent ĂȘtre dĂ©finies avec setsockopt (2) et lues avec getsockopt (2) en indiquant SOL_SOCKET comme famille de sockets.
SO_PASSCRED

Activer cette option de socket provoque la rĂ©ception des accrĂ©ditations du processus Ă©metteur dans un message SCM_CREDENTIALS annexe dans chaque message reçu ultĂ©rieur. Les accrĂ©ditations renvoyĂ©es sont celles indiquĂ©es par l’émetteur en utilisant SCM_CREDENTIALS ou celles par dĂ©faut qui incluent le PID, l’ID utilisateur rĂ©el et l’ID groupe rĂ©el de l’émetteur si celui-ci ne prĂ©cise pas les donnĂ©es auxiliaires SCM_CREDENTIALS .

Lorsque cette option est active et le socket non encore connectĂ©, un nom unique dans l’espace de noms abstrait sera gĂ©nĂ©rĂ© automatiquement.

La valeur donnée comme argument pour setsockopt (2) et renvoyée comme résultat de getsockopt (2) est un indicateur booléen entier.

SO_PASSSEC

Activer la rĂ©ception de l’étiquette de sĂ©curitĂ© SELinux du socket pair dans un message annexe de type SCM_SECURITY (voir ci-dessous).

La valeur donnée comme argument pour setsockopt (2) et renvoyée comme résultat de getsockopt (2) est un indicateur booléen entier.

L’option SO_PASSSEC est gĂ©rĂ©e par les sockets datagramme de domaine UNIX depuis Linux 2.6.18. La prise en charge pour les sockets flux de domaine UNIX a Ă©tĂ© ajoutĂ©e dans Linux 4.2.

SO_PEEK_OFF

Consulter socket (7).

SO_PEERCRED

This read-only socket option returns the credentials of the peer process connected to this socket. The returned credentials are those that were in effect at the time of the call to connect (2), listen (2), or socketpair (2).

L’argument de getsockopt (2) est un pointeur vers une structure ucred . Est dĂ©finie la macro de test de fonctionnalitĂ© _GNU_SOURCE pour obtenir la dĂ©finition de cette structure Ă  partir de <sys/socket.h> .

L’utilisation de cette option est possible seulement pour les sockets flux AF_UNIX connectĂ©s et pour les pairs de sockets flux et datagramme AF_UNIX créés en utilisant socketpair (2).

SO_PEERSEC

Cette option de socket en lecture exclusivement renvoie le contexte de sĂ©curitĂ© du socket pair connectĂ© Ă  ce socket. Par dĂ©faut, cela sera le mĂȘme que le contexte de sĂ©curitĂ© du processus ayant créé le socket pair Ă  moins qu’il ne soit Ă©crasĂ© par la politique ou par un processus ayant les permissions requises.

L’argument de getsockopt (2) est un pointeur vers un tampon de la longueur indiquĂ©e en octets dans lequel la chaĂźne de contexte de sĂ©curitĂ© sera copiĂ©e. Si la taille du tampon est infĂ©rieure Ă  celle de la chaĂźne du contexte de sĂ©curitĂ©, alors getsockopt (2) renvoie -1 , dĂ©finit errno Ă  ERANGE et renvoie la taille requise Ă  l’aide de optlen . L’appelant doit allouer initialement au moins NAME_MAX octets pour le tampon, bien que cela ne soit pas garanti d’ĂȘtre suffisant. Redimensionner le tampon Ă  la taille renvoyĂ©e et rĂ©essayer peuvent ĂȘtre nĂ©cessaires.

La chaĂźne de contexte de sĂ©curitĂ© peut inclure un octet NULL final dans la taille renvoyĂ©e, mais il n’est pas garanti que ce soit fait : un contexte de sĂ©curitĂ© « abc » peut ĂȘtre reprĂ©sentĂ© soit par {’a’,’b’,’c’} de taille 3, ou {’a’,’b’,’c’,’\0’} de taille 4, qui sont considĂ©rĂ©s comme interchangeables. La chaĂźne peut ĂȘtre affichĂ©e, mais ne contient pas d’octet NULL final, et elle est dans un encodage non prĂ©cisĂ© (en particulier, il n’est pas garanti que ce soit ASCII ou UTF-8).

L’utilisation de cette option pour les sockets dans la famille d’adresses AF_UNIX est prise en charge depuis Linux 2.6.2 pour les sockets flux connectĂ©s et aussi, depuis Linux 4.18, pour les pairs de socket flux et datagramme créés en utilisant socketpair (2).

FonctionnalitĂ© d’autolien (« autobind »)

If a bind (2) call specifies addrlen as sizeof(sa_family_t) , or the SO_PASSCRED socket option was specified for a socket that was not explicitly bound to an address, then the socket is autobound to an abstract address. The address consists of a null byte followed by 5 bytes in the character set [0-9a-f] . Thus, there is a limit of 2^20 autobind addresses. (From Linux 2.1.15, when the autobind feature was added, 8 bytes were used, and the limit was thus 2^32 autobind addresses. The change to 5 bytes came in Linux 2.3.15.)

API des sockets

Les paragraphes suivants dĂ©crivent des dĂ©tails spĂ©cifiques aux domaines et des fonctionnalitĂ©s de l’API des sockets de domaine UNIX non prises en charge sous Linux.

Les sockets de domaine UNIX ne prennent pas en charge la transmission de donnĂ©es hors-bande (l’indicateur MSG_OOB de send (2) et recv (2)).

L’indicateur MSG_MORE de send (2) n’est pas pris en charge sur les sockets de domaine UNIX.

Avant Linux 3.4, l’utilisation de MSG_TRUNC dans le paramĂštre flags de recv (2) n’était pas prise en charge par les sockets de domaine UNIX.

L’option SO_SNDBUF de socket a un effet pour les sockets de domaine UNIX, mais l’option SO_RCVBUF n’en a pas. Pour les sockets datagramme, la valeur SO_SNDBUF impose une limite supĂ©rieure Ă  la taille des datagrammes sortants. Cette limite est calculĂ©e comme le double de la valeur de l’option, moins 32 octets utilisĂ©s par le surdĂ©bit.

Messages annexes

Les donnĂ©es annexes sont envoyĂ©es et reçues en utilisant sendmsg (2) et recvmsg (2). Pour des raisons historiques, les messages annexes listĂ©s ci-dessous sont indiquĂ©s avec un type SOL_SOCKET mĂȘme s’ils sont spĂ©cifiques AF_UNIX . Pour les envoyer, dĂ©finissez le champ cmsg_level de la structure cmsghdr Ă  SOL_SOCKET et le champ cmsg_type au type. Pour plus de dĂ©tails, consultez cmsg (3).
SCM_RIGHTS

Envoyer ou recevoir un jeu de descripteurs de fichier ouverts d’un autre processus. La partie donnĂ©es contient un tableau d’entiers de descripteurs de fichier.

Couramment, cette opĂ©ration est appelĂ©e « passage d’un descripteur de fichier » Ă  un autre processus. Cependant, plus prĂ©cisĂ©ment, ce qui a Ă©tĂ© passĂ© est une rĂ©fĂ©rence Ă  une description de fichier ouvert (consultez open (2)), et, dans le processus rĂ©cepteur, il est probable qu’un numĂ©ro diffĂ©rent de descripteur de fichier sera utilisĂ©. SĂ©mantiquement, cette opĂ©ration est Ă©quivalente Ă  dupliquer ( dup (2)) un descripteur de fichier dans une table de descripteurs de fichier d’un autre processus.

Si le tampon utilisé pour recevoir les données annexes contenant les descripteurs de fichier est trop petit (ou absent), alors les données annexes sont tronquées (ou ignorées) et les descripteurs de fichier en excÚs sont automatiquement clos dans le processus récepteur.

Si le nombre de descripteurs de fichier reçus dans les données annexes conduit le processus à dépasser la limite de ressources RLIMIT_NOFILE (consultez getrlimit (2)), les descripteurs de fichier en excÚs sont automatiquement clos dans le processus récepteur.

The kernel constant SCM_MAX_FD defines a limit on the number of file descriptors in the array. Attempting to send an array larger than this limit causes sendmsg (2) to fail with the error EINVAL . SCM_MAX_FD has the value 253 (or 255 before Linux 2.6.38).

SCM_CREDENTIALS

Envoyer ou recevoir les accrĂ©ditations UNIX. Cela peut servir Ă  l’authentification. Les accrĂ©ditations sont passĂ©es en message annexe struct ucred . Cette structure est dĂ©finie dans <sys/socket.h> comme ceci :

struct ucred {
pid_t pid; /* PID processus émetteur */
uid_t uid; /* UID processus émetteur */
gid_t gid; /* GID processus émetteur */
};

Depuis la glibc 2.8, la macro de test de fonctionnalitĂ©s _GNU_SOURCE doit ĂȘtre dĂ©finie (avant d’inclure tout fichier d’en-tĂȘte) afin d’obtenir la dĂ©finition de cette structure.

Les accrĂ©ditations que l’émetteur envoie sont vĂ©rifiĂ©es par le noyau. Un processus privilĂ©giĂ© est autorisĂ© Ă  indiquer des valeurs qui ne correspondent pas aux siennes. L’émetteur doit indiquer son propre PID (sauf s’il a la capacitĂ© CAP_SYS_ADMIN ), auquel cas le PID de n’importe quel processus existants peut ĂȘtre indiquĂ©, son ID utilisateur rĂ©el, son ID utilisateur effectif ou son « saved set-user-ID » (sauf s’il a la capacitĂ© CAP_SETUID ) et son ID groupe rĂ©el, son ID groupe effectif ou son « saved set-group-ID » (sauf s’il a la capacitĂ© CAP_SETGID ).

Pour recevoir un message struct ucred , l’option SO_PASSCRED doit ĂȘtre activĂ©e sur le socket.

SCM_SECURITY

Recevoir le contexte de sĂ©curitĂ© SELinux (l’étiquette de sĂ©curitĂ©) du socket pair. Les donnĂ©es annexes reçues sont une chaĂźne terminĂ©e par un octet NULL final contenant le contexte de sĂ©curitĂ©. Le rĂ©cepteur doit au moins allouer NAME_MAX octets dans la partie donnĂ©es du message annexe pour ces donnĂ©es.

Pour recevoir le contexte de sĂ©curitĂ©, l’option SO_PASSSEC doit ĂȘtre activĂ©e sur le socket (voir ci-dessus).

Lors de l’envoi des donnĂ©es annexes avec sendmsg (2), seul un Ă©lĂ©ment de chacun des types ci-dessus peut ĂȘtre inclus dans le message envoyĂ©.

Au moins un octet des donnĂ©es rĂ©elles doit ĂȘtre envoyĂ© lors de l’envoi des donnĂ©es annexes. Sur Linux, cela est nĂ©cessaire pour envoyer avec succĂšs les donnĂ©es annexes sur un socket flux de domaine UNIX. Lors de l’envoi des donnĂ©es annexes Ă  travers un socket datagramme de domaine UNIX, il n’est pas nĂ©cessaire sur Linux d’envoyer en accompagnement une donnĂ©e quelconque rĂ©elle. Cependant, les applications portables devraient aussi inclure au moins un octet des donnĂ©es rĂ©elles lors de l’envoi de donnĂ©es annexes Ă  travers un socket datagramme.

Lors de la rĂ©ception Ă  partir d’un socket flux, les donnĂ©es annexes forment une sorte de barriĂšre pour les donnĂ©es reçues. Par exemple, en supposant que l’émetteur transmet comme suit :

(1)

sendmsg (2) de quatre octets sans données annexes.

(2)

sendmsg (2) d’un octet avec donnĂ©es annexes.

(3)

sendmsg (2) de quatre octets sans données annexes.

En supposant que le récepteur réalise maintenant des appels recvmsg (2) avec chacun une taille de tampon de 20 octets, le premier appel recevra 5 octets de données, avec les données annexes envoyées par le second appel sendmsg (2). Le prochain appel recevra les 4 octets de données restants.

Si l’espace allouĂ© pour recevoir les donnĂ©es annexes entrantes est trop petit, alors ces donnĂ©es sont tronquĂ©es au nombre d’en-tĂȘtes qui peuvent loger dans le tampon fourni (ou, dans le cas de liste de descripteurs de fichier SCM_RIGHTS , cette liste peut ĂȘtre tronquĂ©e). Si aucun tampon n’est fourni pour les donnĂ©es annexes entrantes (c’est-Ă -dire si le champ msg_control de la structure msghdr fourni Ă  recvmsg (2) est NULL), alors les donnĂ©es annexes entrantes sont ignorĂ©es. Dans les deux cas, l’indicateur MSG_CTRUNC sera rĂ©glĂ© dans la valeur msg.msg_flags renvoyĂ©e par recvmsg (2).

Ioctls

Les appels ioctl (2) suivants renvoient des informations dans value . La syntaxe correcte est :

int value ;
error
= ioctl( unix_socket , ioctl_type , & value );

ioctl_type peut ĂȘtre :
SIOCINQ

Pour les sockets SOCK_STREAM , cet appel renvoie la quantitĂ© de donnĂ©es non lues dans le tampon de rĂ©ception. Le socket ne doit pas ĂȘtre dans l’état LISTEN, sinon l’erreur EINVAL est renvoyĂ©e. SIOCINQ est dĂ©fini dans <linux/sockios.h> . Une alternative est d’utiliser le synonyme FIONREAD dĂ©fini dans <sys/ioctl.h> . Pour les sockets SOCK_DGRAM , la valeur renvoyĂ©e est la mĂȘme que pour les sockets datagramme de domaine Internet. Consultez udp (7).

ERREURS

EADDRINUSE

L’adresse locale indiquĂ©e est dĂ©jĂ  utilisĂ©e ou l’objet de socket de systĂšme de fichiers existe dĂ©jĂ .

EBADF

Cette erreur peut survenir pour sendmsg (2) lors de l’envoi d’un descripteur de fichier pour des donnĂ©es annexes au travers d’un socket de domaine UNIX (consultez la description de SCM_RIGHTS ci-dessus) et indique que le numĂ©ro de descripteur de fichier envoyĂ© n’est pas valable (par exemple, ce n’est pas un descripteur de fichier ouvert).

ECONNREFUSED

L’adresse distante indiquĂ©e par connect (2) n’était pas un socket en Ă©coute. Cette erreur peut Ă©galement se produire si le nom de chemin cible n’est pas un socket.

ECONNRESET

Le socket distant a été fermé de maniÚre inattendue.

EFAULT

Adresse mémoire utilisateur incorrecte.

EINVAL

Argument passĂ© non valable. Une cause habituelle est que la valeur de AF_UNIX n’était pas indiquĂ©e dans le champ sun_type des adresses passĂ©es ou que le socket Ă©tait dans un Ă©tat non valable pour l’opĂ©ration appliquĂ©e.

EISCONN

connect (2) a Ă©tĂ© appelĂ©e sur un socket dĂ©jĂ  connectĂ© ou l’adresse cible a Ă©tĂ© indiquĂ©e sur un socket connectĂ©.

ENFILE

La limite du nombre total de fichiers ouverts pour le systÚme entier a été atteinte.

ENOENT

Le chemin de l’adresse distante indiquĂ©e Ă  connect (2) n’existait pas.

ENOMEM

Plus assez de mémoire.

ENOTCONN

L’opĂ©ration nĂ©cessite une adresse cible, mais le socket n’est pas connectĂ©.

EOPNOTSUPP

OpĂ©ration de flux appelĂ©e sur un socket non orientĂ© flux ou tentative d’utiliser une option de donnĂ©es hors-bande.

EPERM

L’émetteur a transmis des accrĂ©ditations incorrectes dans struct ucred .

EPIPE

Le socket distant a Ă©tĂ© fermĂ© Ă  cause d’un socket flux. Si activĂ©, un signal SIGPIPE est Ă©mis Ă©galement. Cela peut ĂȘtre Ă©vitĂ© en passant l’indicateur MSG_NOSIGNAL dans send (2) ou sendmsg (2).

EPROTONOSUPPORT

Le protocole fourni n’est pas AF_UNIX .

EPROTOTYPE

Le socket distant ne correspond pas au type de socket local ( SOCK_DGRAM versus SOCK_STREAM )

ESOCKTNOSUPPORT

Type de socket inconnu.

ESRCH

Lors de l’envoi d’un message annexe contenant des accrĂ©ditations ( SCM_CREDENTIALS ), l’appelant a indiquĂ© un PID ne correspondant Ă  aucun processus existant.

ETOOMANYREFS

Cette erreur peut se produire pour sendmsg (2) lors de l’envoi d’un descripteur de fichier pour des donnĂ©es annexes Ă  travers un socket de domaine UNIX (consultez la description de SCM_RIGHTS , ci-dessus). Cela se produit si le nombre de descripteurs de fichier « en cours » excĂšde la limite de ressources RLIMIT_NOFILE et si l’appelant n’a pas la capacitĂ© CAP_SYS_RESOURCE . Un descripteur de fichier en cours est un descripteur qui a Ă©tĂ© envoyĂ© en utilisant sendmsg (2) mais qui n’a pas encore Ă©tĂ© acceptĂ© dans le processus rĂ©cepteur en utilisant recvmsg (2).

Cette erreur est dĂ©celĂ©e depuis Linux 4.5 (et dans quelques versions prĂ©cĂ©dentes dans lesquelles le correctif a Ă©tĂ© rĂ©troportĂ©). Dans les versions du noyau prĂ©cĂ©dentes, il Ă©tait possible d’avoir un nombre illimitĂ© de descripteurs de fichier en cours en envoyant chaque descripteur de fichier avec sendmsg (2) et ensuite en fermant le descripteur de fichier de telle façon qu’il ne soit pas pris en compte pour la limite de ressources RLIMIT_NOFILE .

D’autres erreurs peuvent ĂȘtre dĂ©clenchĂ©es par la couche gĂ©nĂ©rique de socket ou par le systĂšme de fichiers lors de la gĂ©nĂ©ration d’un objet socket de systĂšme de fichiers. Consultez les pages de manuel correspondantes pour plus de dĂ©tails.

VERSIONS

SCM_CREDENTIALS et l’espace de noms abstrait ont Ă©tĂ© introduits avec Linux 2.2 et ne doivent pas ĂȘtre utilisĂ©s dans des programmes portables. (Certains systĂšmes dĂ©rivĂ©s de BSD prennent aussi en charge le passage d’accrĂ©ditations, mais les dĂ©tails d’implĂ©mentation diffĂšrent).

NOTES

Lier un socket avec un nom de fichier crĂ©e un socket dans le systĂšme de fichiers que l’appelant doit dĂ©truire lorsqu’il n’est plus utile (en utilisant unlink (2)). La sĂ©mantique habituelle la plus proche d’UNIX s’applique ; le socket peut ĂȘtre dĂ©liĂ© Ă  tout moment et sera finalement supprimĂ© du systĂšme de fichiers lorsque sa derniĂšre rĂ©fĂ©rence sera fermĂ©e.

To pass file descriptors or credentials over a SOCK_STREAM socket, you must send or receive at least one byte of nonancillary data in the same sendmsg (2) or recvmsg (2) call.

Les sockets flux de domaine UNIX ne prennent pas en charge la notion de données hors-bande.

BOGUES

When binding a socket to an address, Linux is one of the implementations that append 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 .

De plus, quelques implĂ©mentations n’ont pas besoin d’octet NULL final lors de liaison d’un socket (l’argument addrlen est utilisĂ© pour dĂ©terminer la taille de sun_path ) et lorsqu’une adresse de socket est rĂ©cupĂ©rĂ©e sur ces implĂ©mentations, il n’y a pas d’octet NULL final dans sun_path .

Les applications qui rĂ©cupĂšrent les adresses de socket peuvent coder (de maniĂšre portable) pour gĂ©rer la possibilitĂ© d’absence d’octet NULL final dans sun_path en respectant le fait que le nombre d’octets autorisĂ©s dans le nom de chemin est :

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

Sinon, une application peut rĂ©cupĂ©rer l’adresse de socket en allouant un tampon de taille sizeof(struct sockaddr_un)+1 mis Ă  zĂ©ro avant la rĂ©cupĂ©ration. L’appel de rĂ©cupĂ©ration peut prĂ©ciser addrlen comme sizeof(struct sockaddr_un) et l’octet zĂ©ro supplĂ©mentaire assure qu’il y aura un octet NULL final dans la chaĂźne renvoyĂ©e dans 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);

Cette sorte de dĂ©sordre peut ĂȘtre Ă©vitĂ© s’il est garanti que les applications qui crĂ©ent les sockets de chemin suivent les rĂšgles exposĂ©es ci-dessus dans Sockets chemin d’accĂšs .

EXEMPLES

Le code suivant dĂ©montre l’utilisation de sockets de paquets ordonnĂ©s pour une communication inter-processus locale. Il est constituĂ© de deux programmes. Le programme serveur attend une connexion d’un programme client. Le client envoie chacun de ses arguments de ligne de commande dans des messages sĂ©parĂ©s. Le serveur traite les messages entrants comme des entiers et fait leur somme. Le client envoie la chaĂźne de commande « END ». Le serveur renvoie un message contenant la somme des entiers du client. Le client affiche la somme et quitte. Le serveur attend la connexion d’un nouveau client. Pour stopper le serveur, le client est appelĂ© avec l’argument de ligne de commande « DOWN ».

La sortie suivante a Ă©tĂ© enregistrĂ©e alors que le serveur fonctionnait en arriĂšre-plan et en exĂ©cutant le client de façon rĂ©pĂ©tĂ©e. L’exĂ©cution du programme du serveur se termine quand il reçoit la commande « DOWN ».

Sortie de l’exemple

$ ./server &
[1] 25887
$ ./client 3 4
Result = 7
$ ./client 11 -5
Result = 6
$ ./client DOWN
Result = 0
[1]+ Done ./server
$

Source du programme

/*
* File connection.h
*/
#ifndef CONNECTION_H
#define CONNECTION_H
#define SOCKET_NAME "/tmp/9Lq7BNBnBycd6nxy.socket"
#define BUFFER_SIZE 12
#endif // include guard

/*
* File server.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include "connection.h"
int
main(void)
{
int down_flag = 0;
int ret;
int connection_socket;
int data_socket;
int result;
ssize_t r, w;
struct sockaddr_un name;
char buffer[BUFFER_SIZE];
/* Create local socket. */
connection_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (connection_socket == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
/*
* For portability clear the whole structure, since some
* implementations have additional (nonstandard) fields in
* the structure.
*/
memset(&name, 0, sizeof(name));
/* Bind socket to socket name. */
name.sun_family = AF_UNIX;
strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path) - 1);
ret = bind(connection_socket, (const struct sockaddr *) &name,
sizeof(name));
if (ret == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
/*
* Prepare for accepting connections. The backlog size is set
* to 20. So while one request is being processed other requests
* can be waiting.
*/
ret = listen(connection_socket, 20);
if (ret == -1) {
perror("listen");
exit(EXIT_FAILURE);
}
/* This is the main loop for handling connections. */
for (;;) {
/* Wait for incoming connection. */
data_socket = accept(connection_socket, NULL, NULL);
if (data_socket == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
result = 0;
for (;;) {
/* Wait for next data packet. */
r = read(data_socket, buffer, sizeof(buffer));
if (r == -1) {
perror("read");
exit(EXIT_FAILURE);
}
/* Ensure buffer is 0-terminated. */
buffer[sizeof(buffer) - 1] = 0;
/* Handle commands. */
if (!strncmp(buffer, "DOWN", sizeof(buffer))) {
down_flag = 1;
continue;
}
if (!strncmp(buffer, "END", sizeof(buffer))) {
break;
}
if (down_flag) {
continue;
}
/* Add received summand. */
result += atoi(buffer);
}
/* Send result. */
sprintf(buffer, "%d", result);
w = write(data_socket, buffer, sizeof(buffer));
if (w == -1) {
perror("write");
exit(EXIT_FAILURE);
}
/* Close socket. */
close(data_socket);
/* Quit on DOWN command. */
if (down_flag) {
break;
}
}
close(connection_socket);
/* Unlink the socket. */
unlink(SOCKET_NAME);
exit(EXIT_SUCCESS);
}

/*
* File client.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include "connection.h"
int
main(int argc, char *argv[])
{
int ret;
int data_socket;
ssize_t r, w;
struct sockaddr_un addr;
char buffer[BUFFER_SIZE];
/* Create local socket. */
data_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (data_socket == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
/*
* For portability clear the whole structure, since some
* implementations have additional (nonstandard) fields in
* the structure.
*/
memset(&addr, 0, sizeof(addr));
/* Connect socket to socket address. */
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
ret = connect(data_socket, (const struct sockaddr *) &addr,
sizeof(addr));
if (ret == -1) {
fprintf(stderr, "The server is down.\n");
exit(EXIT_FAILURE);
}
/* Send arguments. */
for (int i = 1; i < argc; ++i) {
w = write(data_socket, argv[i], strlen(argv[i]) + 1);
if (w == -1) {
perror("write");
break;
}
}
/* Request result. */
strcpy(buffer, "END");
w = write(data_socket, buffer, strlen(buffer) + 1);
if (w == -1) {
perror("write");
exit(EXIT_FAILURE);
}
/* Receive result. */
r = read(data_socket, buffer, sizeof(buffer));
if (r == -1) {
perror("read");
exit(EXIT_FAILURE);
}
/* Ensure buffer is 0-terminated. */
buffer[sizeof(buffer) - 1] = 0;
printf("Result = %s\n", buffer);
/* Close socket. */
close(data_socket);
exit(EXIT_SUCCESS);
}

For examples of the use of SCM_RIGHTS , see cmsg (3) and seccomp_unotify (2).

VOIR AUSSI

recvmsg (2), sendmsg (2), socket (2), socketpair (2), cmsg (3), capabilities (7), credentials (7), socket (7), udp (7)

TRADUCTION

La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Paul Guillonneau <guillonneau.jeanpaul@free.fr>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n’y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org .