UNIX(7) Miscellaneous Information Manual UNIX(7) NOM unix - Sockets pour communications locales entre processus SYNOPSIS #include #include 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 a communiquer efficacement entre processus sur la meme machine. Traditionnellement, les sockets de domaine UNIX peuvent ne pas etre nommes ou bien etre lies a un chemin d'acces de systeme de fichiers, lequel sera marque comme etant de type socket. Linux gere egalement un espace de noms abstrait, independant du systeme de fichiers. Les types de sockets valables dans le domaine UNIX sont : SOCK_STREAM pour un socket oriente flux et SOCK_DGRAM pour un socket oriente datagramme qui preserve les limites entre messages (comme sur la plupart des implementations UNIX, les sockets datagramme de domaine UNIX sont toujours fiables et ne reordonnent pas les datagrammes), et (depuis Linux 2.6.4) SOCK_SEQPACKET pour un socket oriente connexion, preservant les limites entre messages et delivrant les messages dans l'ordre ou ils ont ete envoyes. Les sockets de domaine UNIX prennent en charge la transmission de descripteurs de fichier ou d'accreditations d'un processus a l'autre en utilisant des donnees annexes. Formats d'adresse Une adresse de socket de domaine UNIX est representee dans la structure suivante : struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[108]; /* Chemin d'acces */ }; The sun_family field always contains AF_UNIX. On Linux, sun_path is 108 bytes in size; see also BUGS, below. Divers appels systeme (par exemple, bind(2), connect(2) et sendto(2)) prennent un argument sockaddr_un en entree. D'autres appels systeme (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 : 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 egale a la meme valeur que sizeof(sa_family_t), mais quelques autres implementations incluent d'autres champs avant sun_path, aussi l'expression offsetof() plus portable decrit la taille de la structure d'adresse.) Pour plus de details sur les sockets chemin, voir ci-apres. 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'acces Lors de la liaison d'un socket a un chemin, quelques regles doivent etre observees pour une portabilite maximale et une facilite de codage : - Le chemin dans sun_path doit etre termine par un octet NULL ; - La taille du chemin, y compris l'octet NULL final, ne doit pas exceder la taille de sun_path ; - L'argument addrlen decrivant 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 etre indique comme sizeof(struct sockaddr_un). Il y a quelques variations dans la facon dont les implementations gerent les adresses de socket de domaine UNIX qui ne suivent pas les regles ci-dessus.Par exemple, quelques implementations (mais pas toutes) ajoutent un octet NULL final si aucun n'est present dans le sun_path fourni. Lors du codage d'applications portables, il faut penser que certaines implementations ont un sun_path aussi court que 92 octets. Divers appels systeme (accept(2), recvfrom(2), getsockname(2), getpeername(2)) renvoient les structures d'adresse de socket. Lorsque applique a des sockets de domaine UNIX, l'argument << value-result >> addrlen fourni a l'appel devrait etre initialise comme ci-dessus. Au renvoi, l'argument est regle pour indiquer la taille reelle de la structure d'adresse. L'appelant devrait verifier la valeur renvoyee dans cet argument. Si la valeur de sortie excede la valeur d'entree, alors il n'y a aucune garantie qu'un octet NULL final soit present dans sun_path. (Consultez BOGUES.) Permissions et appartenance des sockets chemin d'acces Dans l'implementation de Linux, les sockets chemin d'acces respectent les permissions du repertoire dans lequel ils sont. La creation d'un nouveau socket echoue si le processus n'a pas les permissions d'ecriture et de recherche (execution) dans le repertoire ou le socket est cree. Dans Linux, la connexion a un objet de socket flux necessite la permission en ecriture sur ce socket. De meme, l'envoi d'un datagramme a un socket datagramme necessite la permission en ecriture sur ce socket. POSIX ne fait aucune declaration sur les effets des permissions sur un fichier de socket, et sur certains systemes (par exemple, les BSD anciens) les permissions de socket sont ignorees. Les programmes portables ne devraient pas se fier a cette fonctionnalite pour la securite. Lors de la creation d'un nouveau socket, le proprietaire et le groupe d'un fichier de socket sont definis selon les regles habituelles. Le fichier de socket a toutes les permissions activees, autres que celles desactivees par le processus umask(2). Le proprietaire, le groupe et les permissions d'un socket chemin d'acces peuvent etre modifies (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 proprietaire et les permissions de l'objet (avec fchown(2) et fchmod(2)) n'a aucun effet sur l'accessibilite du socket. Les sockets abstraits disparaissent automatiquement quand toutes les references de socket ouvertes sont refermees. 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 indiquees avec un type SOL_SOCKET meme si elles sont specifiques a AF_UNIX. Elles peuvent etre definies 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 reception des accreditations du processus emetteur dans un message SCM_CREDENTIALS annexe dans chaque message recu ulterieur. Les accreditations renvoyees sont celles indiquees par l'emetteur en utilisant SCM_CREDENTIALS ou celles par defaut qui incluent le PID, l'ID utilisateur reel et l'ID groupe reel de l'emetteur si celui-ci ne precise pas les donnees auxiliaires SCM_CREDENTIALS. Lorsque cette option est active et le socket non encore connecte, un nom unique dans l'espace de noms abstrait sera genere automatiquement. La valeur donnee comme argument pour setsockopt(2) et renvoyee comme resultat de getsockopt(2) est un indicateur booleen entier. SO_PASSSEC Activer la reception de l'etiquette de securite SELinux du socket pair dans un message annexe de type SCM_SECURITY (voir ci-dessous). La valeur donnee comme argument pour setsockopt(2) et renvoyee comme resultat de getsockopt(2) est un indicateur booleen entier. L'option SO_PASSSEC est geree par les sockets datagramme de domaine UNIX depuis Linux 2.6.18. La prise en charge pour les sockets flux de domaine UNIX a ete ajoutee 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 definie la macro de test de fonctionnalite _GNU_SOURCE pour obtenir la definition de cette structure a partir de . L'utilisation de cette option est possible seulement pour les sockets flux AF_UNIX connectes et pour les pairs de sockets flux et datagramme AF_UNIX crees en utilisant socketpair(2). SO_PEERSEC Cette option de socket en lecture exclusivement renvoie le contexte de securite du socket pair connecte a ce socket. Par defaut, cela sera le meme que le contexte de securite du processus ayant cree le socket pair a moins qu'il ne soit ecrase 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 indiquee en octets dans lequel la chaine de contexte de securite sera copiee. Si la taille du tampon est inferieure a celle de la chaine du contexte de securite, alors getsockopt(2) renvoie -1, definit errno a ERANGE et renvoie la taille requise a 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'etre suffisant. Redimensionner le tampon a la taille renvoyee et reessayer peuvent etre necessaires. La chaine de contexte de securite peut inclure un octet NULL final dans la taille renvoyee, mais il n'est pas garanti que ce soit fait : un contexte de securite << abc >> peut etre represente soit par {'a','b','c'} de taille 3, ou {'a','b','c','\0'} de taille 4, qui sont consideres comme interchangeables. La chaine peut etre affichee, mais ne contient pas d'octet NULL final, et elle est dans un encodage non precise (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 connectes et aussi, depuis Linux 4.18, pour les pairs de socket flux et datagramme crees en utilisant socketpair(2). Fonctionnalite 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 decrivent des details specifiques aux domaines et des fonctionnalites 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 donnees 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 parametre flags de recv(2) n'etait 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 superieure a la taille des datagrammes sortants. Cette limite est calculee comme le double de la valeur de l'option, moins 32 octets utilises par le surdebit. Messages annexes Les donnees annexes sont envoyees et recues en utilisant sendmsg(2) et recvmsg(2). Pour des raisons historiques, les messages annexes listes ci-dessous sont indiques avec un type SOL_SOCKET meme s'ils sont specifiques AF_UNIX. Pour les envoyer, definissez le champ cmsg_level de la structure cmsghdr a SOL_SOCKET et le champ cmsg_type au type. Pour plus de details, consultez cmsg(3). SCM_RIGHTS Envoyer ou recevoir un jeu de descripteurs de fichier ouverts d'un autre processus. La partie donnees contient un tableau d'entiers de descripteurs de fichier. Couramment, cette operation est appelee << passage d'un descripteur de fichier >> a un autre processus. Cependant, plus precisement, ce qui a ete passe est une reference a une description de fichier ouvert (consultez open(2)), et, dans le processus recepteur, il est probable qu'un numero different de descripteur de fichier sera utilise. Semantiquement, cette operation est equivalente a dupliquer (dup(2)) un descripteur de fichier dans une table de descripteurs de fichier d'un autre processus. Si le tampon utilise pour recevoir les donnees annexes contenant les descripteurs de fichier est trop petit (ou absent), alors les donnees annexes sont tronquees (ou ignorees) et les descripteurs de fichier en exces sont automatiquement clos dans le processus recepteur. Si le nombre de descripteurs de fichier recus dans les donnees annexes conduit le processus a depasser la limite de ressources RLIMIT_NOFILE (consultez getrlimit(2)), les descripteurs de fichier en exces sont automatiquement clos dans le processus recepteur. 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 accreditations UNIX. Cela peut servir a l'authentification. Les accreditations sont passees en message annexe struct ucred. Cette structure est definie dans comme ceci : struct ucred { pid_t pid; /* PID processus emetteur */ uid_t uid; /* UID processus emetteur */ gid_t gid; /* GID processus emetteur */ }; Depuis la glibc 2.8, la macro de test de fonctionnalites _GNU_SOURCE doit etre definie (avant d'inclure tout fichier d'en-tete) afin d'obtenir la definition de cette structure. Les accreditations que l'emetteur envoie sont verifiees par le noyau. Un processus privilegie est autorise a indiquer des valeurs qui ne correspondent pas aux siennes. L'emetteur doit indiquer son propre PID (sauf s'il a la capacite CAP_SYS_ADMIN), auquel cas le PID de n'importe quel processus existants peut etre indique, son ID utilisateur reel, son ID utilisateur effectif ou son << saved set-user-ID >> (sauf s'il a la capacite CAP_SETUID) et son ID groupe reel, son ID groupe effectif ou son << saved set-group-ID >> (sauf s'il a la capacite CAP_SETGID). Pour recevoir un message struct ucred, l'option SO_PASSCRED doit etre activee sur le socket. SCM_SECURITY Recevoir le contexte de securite SELinux (l'etiquette de securite) du socket pair. Les donnees annexes recues sont une chaine terminee par un octet NULL final contenant le contexte de securite. Le recepteur doit au moins allouer NAME_MAX octets dans la partie donnees du message annexe pour ces donnees. Pour recevoir le contexte de securite, l'option SO_PASSSEC doit etre activee sur le socket (voir ci-dessus). Lors de l'envoi des donnees annexes avec sendmsg(2), seul un element de chacun des types ci-dessus peut etre inclus dans le message envoye. Au moins un octet des donnees reelles doit etre envoye lors de l'envoi des donnees annexes. Sur Linux, cela est necessaire pour envoyer avec succes les donnees annexes sur un socket flux de domaine UNIX. Lors de l'envoi des donnees annexes a travers un socket datagramme de domaine UNIX, il n'est pas necessaire sur Linux d'envoyer en accompagnement une donnee quelconque reelle. Cependant, les applications portables devraient aussi inclure au moins un octet des donnees reelles lors de l'envoi de donnees annexes a travers un socket datagramme. Lors de la reception a partir d'un socket flux, les donnees annexes forment une sorte de barriere pour les donnees recues. Par exemple, en supposant que l'emetteur transmet comme suit : (1) sendmsg(2) de quatre octets sans donnees annexes. (2) sendmsg(2) d'un octet avec donnees annexes. (3) sendmsg(2) de quatre octets sans donnees annexes. En supposant que le recepteur realise maintenant des appels recvmsg(2) avec chacun une taille de tampon de 20 octets, le premier appel recevra 5 octets de donnees, avec les donnees annexes envoyees par le second appel sendmsg(2). Le prochain appel recevra les 4 octets de donnees restants. Si l'espace alloue pour recevoir les donnees annexes entrantes est trop petit, alors ces donnees sont tronquees au nombre d'en-tetes qui peuvent loger dans le tampon fourni (ou, dans le cas de liste de descripteurs de fichier SCM_RIGHTS, cette liste peut etre tronquee). Si aucun tampon n'est fourni pour les donnees annexes entrantes (c'est-a-dire si le champ msg_control de la structure msghdr fourni a recvmsg(2) est NULL), alors les donnees annexes entrantes sont ignorees. Dans les deux cas, l'indicateur MSG_CTRUNC sera regle dans la valeur msg.msg_flags renvoyee 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 etre : SIOCINQ Pour les sockets SOCK_STREAM, cet appel renvoie la quantite de donnees non lues dans le tampon de reception. Le socket ne doit pas etre dans l'etat LISTEN, sinon l'erreur EINVAL est renvoyee. SIOCINQ est defini dans . Une alternative est d'utiliser le synonyme FIONREAD defini dans . Pour les sockets SOCK_DGRAM, la valeur renvoyee est la meme que pour les sockets datagramme de domaine Internet. Consultez udp(7). ERREURS EADDRINUSE L'adresse locale indiquee est deja utilisee ou l'objet de socket de systeme de fichiers existe deja. EBADF Cette erreur peut survenir pour sendmsg(2) lors de l'envoi d'un descripteur de fichier pour des donnees annexes au travers d'un socket de domaine UNIX (consultez la description de SCM_RIGHTS ci-dessus) et indique que le numero de descripteur de fichier envoye n'est pas valable (par exemple, ce n'est pas un descripteur de fichier ouvert). ECONNREFUSED L'adresse distante indiquee par connect(2) n'etait pas un socket en ecoute. Cette erreur peut egalement se produire si le nom de chemin cible n'est pas un socket. ECONNRESET Le socket distant a ete ferme de maniere inattendue. EFAULT Adresse memoire utilisateur incorrecte. EINVAL Argument passe non valable. Une cause habituelle est que la valeur de AF_UNIX n'etait pas indiquee dans le champ sun_type des adresses passees ou que le socket etait dans un etat non valable pour l'operation appliquee. EISCONN connect(2) a ete appelee sur un socket deja connecte ou l'adresse cible a ete indiquee sur un socket connecte. ENFILE La limite du nombre total de fichiers ouverts pour le systeme entier a ete atteinte. ENOENT Le chemin de l'adresse distante indiquee a connect(2) n'existait pas. ENOMEM Plus assez de memoire. ENOTCONN L'operation necessite une adresse cible, mais le socket n'est pas connecte. EOPNOTSUPP Operation de flux appelee sur un socket non oriente flux ou tentative d'utiliser une option de donnees hors-bande. EPERM L'emetteur a transmis des accreditations incorrectes dans struct ucred. EPIPE Le socket distant a ete ferme a cause d'un socket flux. Si active, un signal SIGPIPE est emis egalement. Cela peut etre evite 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 accreditations (SCM_CREDENTIALS), l'appelant a indique un PID ne correspondant a aucun processus existant. ETOOMANYREFS Cette erreur peut se produire pour sendmsg(2) lors de l'envoi d'un descripteur de fichier pour des donnees annexes a 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 >> excede la limite de ressources RLIMIT_NOFILE et si l'appelant n'a pas la capacite CAP_SYS_RESOURCE. Un descripteur de fichier en cours est un descripteur qui a ete envoye en utilisant sendmsg(2) mais qui n'a pas encore ete accepte dans le processus recepteur en utilisant recvmsg(2). Cette erreur est decelee depuis Linux 4.5 (et dans quelques versions precedentes dans lesquelles le correctif a ete retroporte). Dans les versions du noyau precedentes, il etait possible d'avoir un nombre illimite 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 facon qu'il ne soit pas pris en compte pour la limite de ressources RLIMIT_NOFILE. D'autres erreurs peuvent etre declenchees par la couche generique de socket ou par le systeme de fichiers lors de la generation d'un objet socket de systeme de fichiers. Consultez les pages de manuel correspondantes pour plus de details. VERSIONS SCM_CREDENTIALS et l'espace de noms abstrait ont ete introduits avec Linux 2.2 et ne doivent pas etre utilises dans des programmes portables. (Certains systemes derives de BSD prennent aussi en charge le passage d'accreditations, mais les details d'implementation different). NOTES Lier un socket avec un nom de fichier cree un socket dans le systeme de fichiers que l'appelant doit detruire lorsqu'il n'est plus utile (en utilisant unlink(2)). La semantique habituelle la plus proche d'UNIX s'applique ; le socket peut etre delie a tout moment et sera finalement supprime du systeme de fichiers lorsque sa derniere reference sera fermee. 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 donnees hors-bande. BOGUES Lors de la liaison d'un socket a une adresse, Linux est une des implementations qui ajoute un octet NULL final si aucun n'est fourni dans sun_path. Dans la plupart des cas cela ne pose aucun probleme : quand l'adresse du socket est recuperee, elle sera plus grande d'un octet que celle fournie lors de la liaison du socket. Cependant, il existe un cas ou un comportement deroutant peut se produire : si 108 octets non NULL sont fournis quand un socket est lie, alors l'ajout de l'octet NULL final incorpore la longueur du nom de chemin au-dela de sizeof(sun_path). Par consequent, lors de la recuperation de l'adresse du socket (par exemple, a l'aide de accept(2)), si l'argument addrlen de l'entree pour l'appel de recuperation est indique comme sizeof(struct sockaddr_un), alors la structure d'adresse renvoyee n'aura pas d'octet NULL final dans sun_path. De plus, quelques implementations n'ont pas besoin d'octet NULL final lors de liaison d'un socket (l'argument addrlen est utilise pour determiner la taille de sun_path) et lorsqu'une adresse de socket est recuperee sur ces implementations, il n'y a pas d'octet NULL final dans sun_path. Les applications qui recuperent les adresses de socket peuvent coder (de maniere portable) pour gerer la possibilite d'absence d'octet NULL final dans sun_path en respectant le fait que le nombre d'octets autorises dans le nom de chemin est : strnlen(addr.sun_path, addrlen - offsetof(sockaddr_un, sun_path)) Sinon, une application peut recuperer l'adresse de socket en allouant un tampon de taille sizeof(struct sockaddr_un)+1 mis a zero avant la recuperation. L'appel de recuperation peut preciser addrlen comme sizeof(struct sockaddr_un) et l'octet zero supplementaire assure qu'il y aura un octet NULL final dans la chaine renvoyee 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 desordre peut etre evite s'il est garanti que les applications qui creent les sockets de chemin suivent les regles exposees ci-dessus dans Sockets chemin d'acces. EXEMPLES Le code suivant demontre l'utilisation de sockets de paquets ordonnes pour une communication inter-processus locale. Il est constitue 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 separes. Le serveur traite les messages entrants comme des entiers et fait leur somme. Le client envoie la chaine 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 appele avec l'argument de ligne de commande << DOWN >>. La sortie suivante a ete enregistree alors que le serveur fonctionnait en arriere-plan et en executant le client de facon repetee. L'execution du programme du serveur se termine quand il recoit 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 */ #define SOCKET_NAME "/tmp/9Lq7BNBnBycd6nxy.socket" #define BUFFER_SIZE 12 /* * File server.c */ #include #include #include #include #include #include #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]; /* 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. */ ret = read(data_socket, buffer, sizeof(buffer)); if (ret == -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; break; } if (!strncmp(buffer, "END", sizeof(buffer))) { break; } /* Add received summand. */ result += atoi(buffer); } /* Send result. */ sprintf(buffer, "%d", result); ret = write(data_socket, buffer, sizeof(buffer)); if (ret == -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 #include #include #include #include #include #include #include "connection.h" int main(int argc, char *argv[]) { struct sockaddr_un addr; int ret; int data_socket; 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 (size_t i = 1; i < argc; ++i) { ret = write(data_socket, argv[i], strlen(argv[i]) + 1); if (ret == -1) { perror("write"); break; } } /* Request result. */ strcpy(buffer, "END"); ret = write(data_socket, buffer, strlen(buffer) + 1); if (ret == -1) { perror("write"); exit(EXIT_FAILURE); } /* Receive result. */ ret = read(data_socket, buffer, sizeof(buffer)); if (ret == -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 francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Paul Guillonneau Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 21 decembre 2023 UNIX(7)