Provided by: manpages-fr_4.13-4_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.

   Format 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 */
           };

       Le champ sun_family contient toujours AF_UNIX. Dans Linux, sun_path a pour taille  108 octets.  Consultez
       NOTES, ci-dessous.

       Divers appels système (par exemple, bind(2), connect(2) et sendto(2)) prennent un argument sockaddr_un en
       entrée.  D’autres  appels système (par exemple, getsockname(2), getpeername(2), recvfrom(2) et accept(2))
       renvoient un argument de ce type.

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

       –  chemin d'accès : un socket de domaine UNIX peut être lié, avec bind(2), à un système de fichiers  dont
          le  chemin d'accès est une chaîne de caractères terminée par l’octet NULL. Lorsque l'adresse du socket
          est obtenue (avec un des appels système ci-dessus) sa longueur vaut

              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.

       –  sans_nom :  un  socket flux qui n'a pas été lié à un chemin d'accès avec bind(2) n'a pas de nom. De la
          même façon, les deux sockets créés avec socketpair(2) ne  sont  pas  nommés.  Lorsque  l'adresse  d'un
          socket  sans  nom  est  obtenue,  sa  longueur  vaut sizeof(sa_family_t) et il n'est pas nécessaire de
          vérifier sun_path.

       –  abstrait : une adresse de socket abstrait  se  distingue  d’un  socket  de  chemin  par  le  fait  que
          sun_path[0]  est un octet NULL (« \0 »). L'adresse du socket dans cet espace de noms est donnée par le
          reste des octets dans sun_path qui sont enrobés dans la longueur indiquée de la  structure  d'adresse.
          (Les  octets  NULL dans le nom n'ont pas de signification particulière.) Le nom n'a aucun rapport avec
          les chemins d'accès de systèmes de fichiers. Lorsque  l'adresse  d'un  socket  abstrait  est  obtenue,
          l'addrlen  obtenue est plus grande que sizeof(sa_family_t) (c'est-à-dire plus grande que 2), et le nom
          du socket est contenu dans les premiers bits (addrlen - sizeof(sa_family_t)) de 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
              Cette  option  de  socket  en  lecture  exclusivement renvoie les accréditations du processus pair
              connecté à ce socket. Les accréditations renvoyées sont celles effectives au moment de  l’appel  à
              connect(2) ou 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 »)
       Si un appel bind(2) indique addrlen comme sizeof(sa_family_t), ou si l'option de socket SO_PASSCRED était
       indiquée  pour  un  socket qui n'était pas lié explicitement à une adresse, alors le socket est autolié à
       une adresse abstraite. L'adresse est constituée d'un octet NULL suivi par cinq octets  de  l'ensemble  de
       caractères  [0-9a-f].  Le  nombre  d'adresses autoliées est donc limité à 2^20 (à partir de Linux 2.1.15,
       quand la fonctionnalité d'autolien a été ajoutée, huit octets étaient utilisés et  le  nombre  d'adresses
       autoliées était donc limité à 2^32. La modification à cinq octets est intervenue avec 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.

              La constante du noyau SCM_MAX_FD définit une limite au nombre de descripteurs de fichier  dans  la
              table.  Essayer  d’envoyer  une  table plus grande que cette limite provoque l’échec de sendmsg(2)
              avec l’erreur EINVAL. SCM_MAX_FD a la valeur 253 (ou 255 dans les noyaux avant 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é.

       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.

       Pour passer des descripteurs de fichier ou des accréditations à travers un socket  SOCK_STREAM,  il  faut
       envoyer ou recevoir au moins un octet de données non annexes dans le même appel sendmsg(2) ou recvmsg(2).

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

BOGUES

       Lors  de la liaison d’un socket à une adresse, Linux est une des implémentations qui ajoute un octet NULL
       final si aucun n’est fourni dans sun_path. Dans la plupart des cas cela ne pose  aucun  problème :  quand
       l’adresse  du socket est récupérée, elle sera plus grande d’un octet que celle fournie lors de la liaison
       du socket. Cependant, il existe un cas où un comportement déroutant peut se produire : si 108 octets  non
       NULL  sont  fournis quand un socket est lié, alors l’ajout de l’octet NULL final incorpore la longueur du
       nom de chemin au-delà de sizeof(sun_path). Par conséquent, lors de la récupération de l’adresse du socket
       (par exemple, à l’aide de accept(2)), si l’argument addrlen de l’entrée pour l’appel de récupération  est
       indiqué  comme  sizeof(struct sockaddr_un), alors la structure d’adresse renvoyée n’aura pas d’octet NULL
       final dans 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)
               /* Gérer l’erreur */ ;
           memset(addrp, 0, addrlen + 1);

           if (getsockname(sfd, (struct sockaddr *) addrp, &addrlen)) == -1)
               /* Gérer l’erreur */ ;

           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

       /*
        * Fichier connection.h
        */

       #define SOCKET_NAME "/tmp/9Lq7BNBnBycd6nxy.socket"
       #define BUFFER_SIZE 12

       /*
        * Fichier server.c
        */

       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/socket.h>
       #include <sys/un.h>
       #include <unistd.h>
       #include "connection.h"

       int
       main(int argc, char *argv[])
       {
           struct sockaddr_un name;
           int down_flag = 0;
           int ret;
           int connection_socket;
           int data_socket;
           int result;
           char buffer[BUFFER_SIZE];

           /* Création du socket local. */

           connection_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
           if (connection_socket == -1) {
               perror("socket");
               exit(EXIT_FAILURE);
           }

           /*
            * Pour la portabilité effacer la structure entière, puisque
            * quelques implémentations ont des champs (non standard)
            * supplémentaires dans la structure.
            */

           memset(&name, 0, sizeof(name));

           /* Liaison du socket au nom de socket. */

           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);
           }

           /*
            * Préparation à accepter les connexions. La taille de réserve
            * est réglée à 20. Aussi tandis qu’une requête est traitée,
            * d’autres peuvent être en attente.
            */

           ret = listen(connection_socket, 20);
           if (ret == -1) {
               perror("listen");
               exit(EXIT_FAILURE);
           }

           /* Ceci est la boucle principale pour gérer les connexions. */

           for (;;) {

               /* Attendre des connexions entrantes. */

               data_socket = accept(connection_socket, NULL, NULL);
               if (data_socket == -1) {
                   perror("accept");
                   exit(EXIT_FAILURE);
               }

               result = 0;
               for (;;) {

                   /* Attendre le prochain paquet de données. */

                   ret = read(data_socket, buffer, sizeof(buffer));
                   if (ret == -1) {
                       perror("read");
                       exit(EXIT_FAILURE);
                   }

                   /* Assurer que le tampon soit terminé par NULL. */

                   buffer[sizeof(buffer) - 1] = 0;

                   /* Gérer les commandes. */

                   if (!strncmp(buffer, "DOWN", sizeof(buffer))) {
                       down_flag = 1;
                       break;
                   }

                   if (!strncmp(buffer, "END", sizeof(buffer))) {
                       break;
                   }

                   /* Faire la somme des termes reçus. */

                   result += atoi(buffer);
               }

               /* Envoyer le résultat. */

               sprintf(buffer, "%d", result);
               ret = write(data_socket, buffer, sizeof(buffer));
               if (ret == -1) {
                   perror("write");
                   exit(EXIT_FAILURE);
               }

               /* Fermer le socket. */

               close(data_socket);

               /* Quitter avec la commande DOWN. */

               if (down_flag) {
                   break;
               }
           }

           close(connection_socket);

           /* Délier le socket. */

           unlink(SOCKET_NAME);

           exit(EXIT_SUCCESS);
       }

       /*
        * Fichier client.c
        */

       #include <errno.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/socket.h>
       #include <sys/un.h>
       #include <unistd.h>
       #include "connection.h"

       int
       main(int argc, char *argv[])
       {
           struct sockaddr_un addr;
           int ret;
           int data_socket;
           char buffer[BUFFER_SIZE];

           /* Création du socket local. */

           data_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
           if (data_socket == -1) {
               perror("socket");
               exit(EXIT_FAILURE);
           }

           /*
            * Pour la portabilité effacer la structure entière, puisque
            * quelques implémentations ont des champs (non standard)
            * supplémentaires dans la structure.
            */

           memset(&addr, 0, sizeof(addr));

           /* Connecter le socket à l’adresse de socket */

           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, "Le serveur est arrêté.\n");
               exit(EXIT_FAILURE);
           }

           /* Envoyer les arguments. */

           for (int i = 1; i < argc; ++i) {
               ret = write(data_socket, argv[i], strlen(argv[i]) + 1);
               if (ret == -1) {
                   perror("write");
                   break;
               }
           }

           /* Résultat de la requête. */

           strcpy(buffer, "END");
           ret = write(data_socket, buffer, strlen(buffer) + 1);
           if (ret == -1) {
               perror("write");
               exit(EXIT_FAILURE);
           }

           /* Recevoir le résultat. */

           ret = read(data_socket, buffer, sizeof(buffer));
           if (ret == -1) {
               perror("read");
               exit(EXIT_FAILURE);
           }

           /* Assurer que le tampon soit terminé par NULL. */

           buffer[sizeof(buffer) - 1] = 0;

           printf("Result = %s\n", buffer);

           /* Fermer le socket. */

           close(data_socket);

           exit(EXIT_SUCCESS);
       }

       Pour un exemple de l'utilisation de SCM_RIGHTS, consultez cmsg(3).

VOIR AUSSI

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

COLOPHON

       Cette page fait partie de la publication 5.10 du projet man-pages Linux. Une description du projet et des
       instructions pour signaler des anomalies et la dernière version de cette page  peuvent  être  trouvées  à
       l'adresse https://www.kernel.org/doc/man-pages/.

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.

Linux                                            1 novembre 2020                                         UNIX(7)