Provided by: manpages-fr_4.26.0-1_all bug

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.

Pages du manuel de Linux 6.9.1                    15 juin 2024                                           UNIX(7)