NOM
accept - Accepter une connexion sur une socket
SYNOPSIS
#include <sys/types.h> /* Voir NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
#define _GNU_SOURCE
#include <sys/socket.h>
int accept4(int sockfd, struct sockaddr *addr,
socklen_t *addrlen, int flags);
L’appel système accept() est employé avec les sockets utilisant un
protocole en mode connecté (SOCK_STREAM, SOCK_SEQPACKET). Il extrait la
première connexion de la file des connexions en attente de la socket
sockfd à l’écoute, crée une nouvelle socket et alloue pour cette socket
un nouveau descripteur de fichier qu’il renvoie. La nouvelle socket
n’est pas en état d’écoute. La socket originale sockfd n’est pas
modifiée par l’appel système.
L’argument sockfd est une socket qui a été créée avec la fonction
socket(2), attachée à une adresse avec bind(2), et attend des
connexions après un appel listen(2).
L’argument addr est un pointeur sur une structure sockaddr. La
structure sera remplie avec l’adresse du correspondant se connectant,
telle qu’elle est connue par la couche de communication. Le format
exact du paramètre addr dépend du domaine dans lequel la communication
s’établit (voir socket(2) et la page de manuel correspondant au
protocole). Quand addr vaut NULL, rien n’est rempli ; dans ce cas,
addrlen n’est pas utilisé et doit aussi valoir NULL.
addrlen est un paramètre-résultat : l’appelant doit l’initialiser de
telle sorte qu’il contienne la taille (en octets) de la structure
pointée par addr, et est renseigné au retour par la longueur réelle (en
octets) de l’adresse remplie.
L’adresse renvoyée est tronquée si le tampon fourni est trop petit ;
dans ce cas, addrlen renverra une valeur supérieure à celle fournie
lors de l’appel.
S’il n’y a pas de connexion en attente dans la file, et si la socket
n’est pas marquée comme non‐bloquante, accept() se met en attente d’une
connexion. Si la socket est non‐bloquante, et qu’aucune connexion n’est
présente dans la file, accept() retourne une erreur EAGAIN ou
EWOULDBLOCK.
Pour être prévenu de l’arrivée d’une connexion sur une socket on peut
utiliser select(2) ou poll(2). Un événement « lecture » sera délivré
lorsqu’une tentative de connexion aura lieu, et on pourra alors appeler
accept() pour la valider. Autrement, on peut configurer la socket pour
qu’elle envoie un signal SIGIO lorsqu’une activité la concernant se
produit, voir socket(7) pour plus de détails.
Pour certains protocoles nécessitant une confirmation explicite, comme
DECNet, accept() peut être considéré comme extrayant simplement la
connexion suivante de la file, sans demander de confirmation. On peut
effectuer la confirmation par une simple lecture ou écriture sur le
nouveau descripteur, et le rejet en fermant la nouvelle socket. Pour le
moment, seul DECNet se comporte ainsi sous Linux.
Si flags vaut 0, alors accept4() est identique à accept(). Les valeurs
suivantes peuvent être combinées dans flags par un OU binaire pour
obtenir un comportement différent :
SOCK_NONBLOCK Définir l’attribut d’état de fichier O_NONBLOCK sur le
nouveau descripteur de fichier ouvert. Utiliser cet
attribut économise des appels à fcntl(2) qui
permettrait d’obtenir le même résultat.
SOCK_CLOEXEC Définir l’attribut « close-on-exec » (FD_CLOEXEC) sur
le nouveau descripteur de fichier. Consultez la
description de l’attribut O_CLOEXEC dans open(2) pour
savoir quand ça peut être utile.
VALEUR RENVOYÉE
S’ils réussissent, ces appels système renvoient un entier positif ou
nul, qui est un descripteur pour la socket acceptée. En cas d’erreur,
ils renvoient -1 et remplissent errno avec le code d’erreur.
Traitement des erreurs
Sous Linux, accept() (et accept4()) renvoie les erreurs réseau déjà en
attente sur la socket comme une erreur de l’appel système. Ce
comportement diffère d’autres implémentations des sockets BSD. Pour un
comportement fiable, une application doit détecter les erreurs réseau
définies par le protocole après le accept() et les traiter comme des
erreurs EAGAIN, en réitérant le mécanisme. Dans le cas de TCP/IP, ces
erreurs sont ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET,
EHOSTUNREACH, EOPNOTSUPP, et ENETUNREACH.
ERREURS
EAGAIN ou EWOULDBLOCK
La socket est marquée comme étant non bloquante et aucune
connexion n’est présente pour être acceptée. POSIX.1-2001 permet
de renvoyer l’une ou l’autre des erreurs dans ce cas et n’exige
pas que ces constantes aient la même valeur. Une application
portable devrait donc tester les deux possibilités.
EBADF Le descripteur est invalide.
ECONNABORTED
Une connexion a été abandonnée.
EFAULT addr n’est pas dans l’espace d’adressage accessible en écriture.
EINTR L’appel système a été interrompu par l’arrivée d’un signal avant
qu’une connexion valide ne survienne ; voir signal(7).
EINVAL La socket n’est pas en attente de connexions, ou addrlen est
invalide (par exemple négatif).
EINVAL (accept4()) flags contient une valeur incorrecte.
EMFILE La limite du nombre total de descripteurs de fichier ouverts par
processus a été atteinte.
ENFILE La limite du nombre total de fichiers ouverts sur le système a
été atteinte.
ENOBUFS, ENOMEM
Par assez de mémoire disponible. En général, cette erreur due à
la taille limitée du tampon des sockets, et pas à la mémoire
système proprement dite.
ENOTSOCK
Le descripteur n’est pas celui d’une socket.
EOPNOTSUPP
La socket de référence n’est pas de type SOCK_STREAM.
EPROTO Erreur de protocole.
De plus, la version Linux de accept() peut échouer si :
EPERM Les règles du pare-feu interdisent la connexion.
De plus il peut se produire des erreurs réseau dépendant du protocole
de la socket. Certains noyaux Linux peuvent renvoyer d’autres erreurs
comme ENOSR, ESOCKTNOSUPPORT, EPROTONOSUPPORT, ETIMEDOUT. L’erreur
ERESTARTSYS peut être rencontrée durant un suivi dans un débogueur.
VERSIONS
L’appel système accept4() est disponible depuis Linux 2.6.28 ; la prise
en charge dans la glibc est disponible depuis la version 2.10.
CONFORMITÉ
accept() : POSIX.1-2001, SVr4, BSD 4.4 (accept() est apparu dans
BSD4.2).
accept4() est une extension non standard de Linux.
Avec la version Linux de accept(), la nouvelle socket n’hérite pas des
attributs comme O_NONBLOCK et O_ASYNC de la socket en écoute. Ce
comportement est différent de l’implémentation BSD de référence. Les
programmes portables ne doivent pas s’appuyer sur cette particularité,
et doivent reconfigurer les attributs sur la socket renvoyée par
accept().
NOTES
POSIX.1-2001 ne requiert pas l’inclusion de <sys/types.h>, et cet
en‐tête n’est pas nécessaire sous Linux. Cependant, il doit être inclus
sous certaines implémentations historiques (BSD), et les applications
portables devraient probablement l’utiliser.
Il n’y a pas nécessairement de connexion en attente après la réception
de SIGIO ou après que select(2) ou poll(2) indiquent quelque chose à
lire. En effet la connexion peut avoir été annulée à cause d’une erreur
réseau asynchrone ou par un autre thread avant que accept() ne se
termine. Si cela se produit, l’appel bloquera en attendant une autre
connexion. Pour s’assurer que accept() ne bloquera jamais, la socket
sockfd transmise doit avoir l’attribut O_NONBLOCK (voir socket(7)).
Le type socklen_t
Le troisième argument de accept() était, à l’origine, déclaré comme un
int * (ceci dans libc4 et libc5 ainsi que pour beaucoup d’autres
systèmes comme BSD 4.x, SunOS 4, SGI). Une proposition de standard
POSIX.1g l’a modifié en size_t * et c’est ce qu’utilise SunOS 5. Les
dernières propositions POSIX en ont fait un socklen_t *, ce que suivent
la Single Unix Specification et la glibc2. Pour citer Linus Torvalds :
« Toute bibliothèque sensée doit garder "socklen_t" équivalent à un
int. Toute autre chose invaliderait tout le niveau des sockets BSD.
POSIX l’avait d’abord remplacé par un size_t, et je m’en suis plaint
violemment (ainsi que d’autres heureusement, mais de toute évidence,
pas assez). Le remplacement par un size_t est complètement stupide car
size_t a rarement la même taille qu’un int sur les architectures
64 bits par exemple. Et il doit avoir la même taille qu’un "int" parce
que c’était l’interface des sockets BSD. Quoi qu’il en soit, les gens
de POSIX ont compris et ont créé un "socklen_t". Ils n’auraient jamais
dû y toucher, mais une fois commencé, ils ont décidé de créer un type
spécifique, pour des raisons inavouées (probablement quelqu’un qui ne
veut pas perdre la face en expliquant que le premier travail était
stupide et ils ont simplement renommé leur bricolage). »
EXEMPLE
Voir bind(2).
VOIR AUSSI
bind(2), connect(2), listen(2), select(2), socket(2), socket(7)
COLOPHON
Cette page fait partie de la publication 3.23 du projet man-pages
Linux. Une description du projet et des instructions pour signaler des
anomalies peuvent être trouvées à l’adresse
http://www.kernel.org/doc/man-pages/.
TRADUCTION
Cette page de manuel a été traduite et mise à jour par Christophe
Blaess <http://www.blaess.fr/christophe/> entre 1996 et 2003, puis par
Alain Portal <aportal AT univ-montp2 DOT fr> jusqu’en 2006, et mise à
disposition sur http://manpagesfr.free.fr/.
Les mises à jour et corrections de la version présente dans Debian sont
directement gérées par Julien Cristau <jcristau@debian.org> et l’équipe
francophone de traduction de Debian.
Veuillez signaler toute erreur de traduction en écrivant à
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document
en utilisant la commande « man -L C <section> <page_de_man> ».