Provided by: manpages-fr-dev_3.57d1p1-1_all bug

NOM

       select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - Multiplexage d'entrées-sorties synchrones

SYNOPSIS

       /* D'après POSIX.1-2001 */
       #include <sys/select.h>

       /* D'après les standards précédents */
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

       #include <sys/select.h>

       int pselect(int nfds, fd_set *readfds, fd_set *writefds,
                   fd_set *exceptfds, const struct timespec *timeout,
                   const sigset_t *sigmask);

   Exigences de macros de test de fonctionnalités pour la glibc (consultez feature_test_macros(7)) :

       pselect() : _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600

DESCRIPTION

       select()  et  pselect()  permettent  à  un  programme de surveiller plusieurs descripteurs de fichier, en
       attendant qu'au moins l'un de ces descripteurs  soit  « prêt »  pour  une  certaine  classe  d'opérations
       d'entrée-sortie.  Un  descripteur  de  fichier  est  considéré  comme  prêt s'il est possible d'effectuer
       l'opération correspondante (par exemple read(2)) sans bloquer.

       select() et pselect() ont un comportement identique, avec trois différences :

       (i)    La fonction select() utilise un délai exprimé avec une struct timeval (secondes et microsecondes),
              alors que pselect() utilise une struct timespec (secondes et nanosecondes).

       (ii)   La fonction select() peut modifier le  paramètre  timeout  pour  indiquer  le  temps  restant.  La
              fonction pselect() ne change pas ce paramètre.

       (iii)  La  fonction  select() n'a pas de paramètre sigmask et se comporte comme pselect() avec une valeur
              NULL pour sigmask

       Il y a trois ensembles indépendants de descripteurs surveillés simultanément. Ceux de l'ensemble  readfds
       seront surveillés pour vérifier si des caractères deviennent disponibles en lecture. Plus précisément, on
       vérifie  si un appel système de lecture ne bloquera pas — en particulier un descripteur en fin de fichier
       sera considéré comme prêt. Les descripteurs de l'ensemble writefds seront surveillés pour vérifier si une
       écriture  ne  bloquera  pas.  Ceux  de  exceptfds  seront  surveillés  pour  l'occurrence  de  conditions
       exceptionnelles.  En  sortie,  les  ensembles sont modifiés pour indiquer les descripteurs qui ont changé
       d'état. Chacun des trois ensemble de descripteurs peut être NULL si aucun descripteur de fichier ne  doit
       être surveillé pour cette classe d'événements.

       Quatre macros sont disponibles pour la manipulation des ensembles. FD_ZERO() efface un ensemble. FD_SET()
       ajoute  et  FD_CLR()  supprime  un descripteur dans un ensemble. FD_ISSET() vérifie si un descripteur est
       contenu dans un ensemble, principalement utile après le retour de select().

       nfds est le numéro du plus grand descripteur des 3 ensembles, plus 1.

       timeout est la durée pendant laquelle select() bloque en attendant  qu'un  descripteur  de  fichier  soit
       prêt.  Cette durée est arrondie à la granularité de l'horloge système, et peut être modifiée légèrement à
       cause des délais d'ordonnancement du noyau. Si les deux champs de la structure timeval  sont  nuls  alors
       select()  retourne immédiatement. (Ce qui sert pour des surveillances en polling). Si le timeout est NULL
       (aucune limite), select() peut bloquer indéfiniment.

       sigmask est un pointeur sur un masque de signaux (consultez sigprocmask(2)). S'il n'est pas  NULL,  alors
       pselect()  remplace d'abord le masque de signaux en cours par celui indiqué dans sigmask, puis invoque la
       fonction « select », et enfin restaure le masque de signaux à nouveau.

       Mise à part la différence de précision de l'argument timeout, l'appel pselect() suivant :

           ready = pselect(nfds, &readfds, &writefds, &exceptfds,
                           timeout, &sigmask);

       est équivalent à exécuter de façon atomique les appels suivants :

           sigset_t origmask;

           pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
           ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
           pthread_sigmask(SIG_SETMASK, &origmask, NULL);

       L'idée derrière pselect() est que pour l'attente d'un événement, que ce soit un signal ou  une  condition
       sur un descripteur, un test atomique est nécessaire pour éviter les situations de concurrence. (Supposons
       que  le  gestionnaire de signaux active un drapeau global et revienne. Alors un test de ce drapeau, suivi
       d'un appel select() peut bloquer indéfiniment si le signal arrive juste après le test mais avant l'appel.
       À l'inverse, pselect() permet de bloquer le signal d'abord, traiter les signaux déjà reçus, puis invoquer
       pselect() avec le sigmask, désiré, en évitant la situation de blocage.)

   Délai maximal
       Les structures temporelles concernées sont définies dans <sys/time.h> comme ceci :

           struct timeval {
               long    tv_sec;         /* secondes      */
               long    tv_usec;        /* microsecondes */
           };

       et

           struct timespec {
               long    tv_sec;         /* secondes     */
               long    tv_nsec;        /* nanosecondes */
           };

       (Toutefois, voir plus loin les versions POSIX.1-2001.)

       Certaines applications appellent select() avec trois ensembles de descripteurs vides,  nfds  nul,  et  un
       délai  timeout  non  nul, afin d'endormir, de manière portable, le processus avec une précision plus fine
       que la seconde.

       Sous Linux, la fonction select() modifie timeout pour indiquer le  temps  restant  mais  la  plupart  des
       autres  implémentations  ne  le  font  pas  (POSIX.1-2001 autorise les deux comportements). Ceci pose des
       problèmes à la fois pour porter sur d'autres systèmes du code développé  sous  Linux  qui  utilise  cette
       valeur  de  timeout  modifiée,  et  pour porter sous Linux du code qui réutilise plusieurs fois la struct
       timeval sans la réinitialiser. La meilleure attitude à adopter est de considérer timeout  comme  indéfini
       après le retour de select().

VALEUR RENVOYÉE

       En  cas de réussite select() et pselect() renvoient le nombre de descripteurs dans les trois ensembles de
       descripteurs renvoyés (c'est-à-dire le nombre total de bits à 1 dans readfds, writefds et exceptfds)  qui
       peut  être  nul  si  le  délai  d’expiration a été atteint avant que quoi que ce soit d'intéressant ne se
       produise. Elles renvoient -1 en cas d’échec, auquel cas errno contient le code d'erreur ;  les  ensembles
       de descripteurs de fichier ne sont pas modifiés et timeout n’est plus défini.

ERREURS

       EBADF  Un  descripteur  de fichier invalide était dans l'un des ensembles. (Peut-être un descripteur déjà
              fermé, ou sur lequel une erreur s'est produite.)

       EINTR  Un signal a été intercepté ; consultez signal(7).

       EINVAL nfds est négatif ou la valeur contenue dans timeout est invalide.

       ENOMEM Pas assez de mémoire pour le noyau.

VERSIONS

       pselect() a été ajouté à Linux dans le noyau 2.6.16. Précédemment, pselect() était émulé  dans  la  glibc
       (mais voir la section BOGUES).

CONFORMITÉ

       select()  est  conforme  à  POSIX.1-2001  et  BSD 4.4  (la  fonction  select() est apparue dans BSD 4.2).
       Généralement portable depuis ou vers des systèmes non-BSD supportant des clones de la couche sockets  BSD
       (y  compris  les  variantes du System V). Néanmoins, sachez que les variantes du System V définissent une
       variable de timeout avant le retour alors que les variantes BSD ne le font pas.

       pselect() est défini dans POSIX.1g, et dans POSIX.1-2001.

NOTES

       Un ensemble fd_set est un tampon de taille fixe.  Exécuter  FD_CLR()  ou  FD_SET()  avec  fd  négatif  ou
       supérieur  ou  égal à FD_SETSIZE résultera en un comportement indéfini. Plus encore, POSIX demande que fd
       soit un descripteur de fichier valide.

       En ce qui concerne les types impliqués, la situation classique est que les deux champs  de  la  structure
       timeval soient de type « long » (comme ci-dessus), et que la structure soit définie dans <sys/time.h>. La
       situation avec POSIX.1-2001 est

           struct timeval {
               time_t         tv_sec;     /* secondes */
               suseconds_t    tv_usec;    /* microsecondes */
           };

       avec  la structure définie dans <sys/select.h> et les types de données time_t et suseconds_t définis dans
       <sys/types.h>.

       Concernant les  prototypes,  on  demande  classiquement  l'inclusion  de  <time.h>  pour  select().  Avec
       POSIX.1-2001, on préfère inclure <sys/select.h> pour select() et pselect().

       Les  bibliothèques  libc4  et  libc5  n'avaient  pas d'en-tête <sys/select.h>, mais avec les glibc 2.0 et
       suivantes le fichier existe. Pour la glibc 2.0, le prototype de pselect() est toujours  erroné.  Avec  la
       glibc  2.1  à  2.2.1  le  prototype de pselect() est fourni si la constante _GNU_SOURCE est définie avant
       l'inclusion. Depuis la glibc 2.2.2, les exigences sont celles indiquées dans le SYNOPSIS.

   Programmes multithreadés
       Si un descripteur de fichier surveillé par select() est fermé dans  un  autre  thread,  le  résultat  est
       indéterminé.  Sur  certains  systèmes  UNIX,  select()  débloque  et  termine, avec une indication que le
       descripteur de fichier est prêt (une opération entrée/sortie ultérieur risque d'échouer avec une  erreur,
       sauf  si  le descripteur de fichier a été réouvert entre le moment où select() termine et l'exécution des
       opérations entrée/sortie). Sur Linux (et d'autres systèmes), la fermeture du descripteur de fichier  dans
       un  autre  thread  n'a  aucun  effet  sur  select().  En  résumé,  toute  application qui s'appuie sur un
       comportement particulier dans ce scénario doit être considérée comme boguée.

   Notes sur Linux
       L'interface pselect() décrite dans cette page  est  implémentée  par  la  glibc.  L'appel  système  Linux
       sous-jacent  est  appelé  pselect6().  Cet  appel  système  a un comportement quelque peu différent de la
       fonction d'enrobage de la glibc.

       L'appel système pselect6() de Linux modifie son argument timeout. Cependant, la fonction d'enrobage de la
       glibc cache ce comportement en utilisant une variable locale pour l'argument  timeout  qui  est  passé  à
       l'appel  système. Par conséquent, la fonction pselect() de glibc ne modifie pas son paramètre timeout, ce
       qui est le comportement prescrit par POSIX.1-2001.

       Le dernier argument de l'appel système pselect6() n'est pas un pointeur sigset_t *, mais une structure de
       la forme suivante :

           struct {
               const sigset_t *ss;     /* pointeur vers l'ensemble de signaux */
               size_t          ss_len; /* taille (en octet) de l'objet pointé
                                          par 'ss' */
           };

       Cela permet à l'appel système d'obtenir à la fois le pointeur à l'ensemble de signaux et sa taille,  tout
       en permettant à la plupart des architectures de ne prendre en charge qu'un maximum de 6 arguments pour un
       appel système.

BOGUES

       Glibc 2.0 fournissait une version de pselect() qui n'avait pas d'argument sigmask.

       À  partir  de  la  version  2.1,  la  glibc  fournissait  une  émulation  de  pselect()  implémentée avec
       sigprocmask(2) et select(). Cette implémentation était vulnérable  à  la  condition  de  concurrence  que
       pselect()  était conçu pour éviter. Les versions récentes de la glibc utilisent l'appel système pselect()
       (sans risque de concurrence) si le noyau le fournit.

       Sur les systèmes sans pselect, une gestion plus sûre (et plus portable) des signaux peut être obtenue  en
       utilisant un tube : un gestionnaire de signal écrit un octet dans un tube dont select() dans le programme
       principal  surveille l'autre extrémité. (Pour éviter la possibilité de blocage lors de l'écriture dans un
       tube peut-être plein, ou la lecture dans un tube peut-être vide, des entrées  et  sorties  non  blocantes
       sont utilisées pour la lecture et l'écriture dans le tube.)

       Sous  Linux,  select()  peut signaler un descripteur de fichier socket comme « prêt à lire » alors qu'une
       lecture suivante bloque. Cela peut, par exemple, survenir lorsque des données sont arrivées  mais,  après
       vérification,  ont  une  mauvaise  somme  de  contrôle et sont rejetées. Cela peut également arriver dans
       d'autres circonstances. Aussi, il est plus sûr d'utiliser O_NONBLOCK sur des sockets qui ne devraient pas
       bloquer.

       Sous Linux, select() modifie également timeout si l'appel est interrompu par un gestionnaire  de  signaux
       (code d'erreur EINTR). Ceci est interdit par POSIX.1-2001. L'appel système pselect() de Linux se comporte
       de la même façon, mais la glibc cache cette particularité en copiant timeout vers une variable locale, et
       en passant cette variable à l'appel système.

EXEMPLE

       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int
       main(void)
       {
           fd_set rfds;
           struct timeval tv;
           int retval;

           /* Surveiller stdin (fd 0) en attente d'entrées */
           FD_ZERO(&rfds);
           FD_SET(0, &rfds);

           /* Attends jusqu'à 5 secondes. */
           tv.tv_sec = 5;
           tv.tv_usec = 0;

           retval = select(1, &rfds, NULL, NULL, &tv);
           /* Considérer tv comme indéfini maintenant ! */

           if (retval == -1)
               perror("select()");
           else if (retval)
               printf("Des données sont disponibles maintenant\n");
               /* FD_ISSET(0, &rfds) est alors vrai. */
           else
               printf("Aucune donnée durant les cinq secondes.\n");

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       accept(2), connect(2), poll(2), read(2), recv(2), send(2), sigprocmask(2), write(2), epoll(7), time(7)

       Pour un tutoriel avec des exemples, consultez select_tut(2).

COLOPHON

       Cette page fait partie de la publication 3.57 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

       Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par
       l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>.

       Christophe      Blaess      <http://www.blaess.fr/christophe/>      (1996-2003),       Alain       Portal
       <http://manpagesfr.free.fr/>  (2003-2006).  Julien  Cristau  et  l'équipe  francophone  de  traduction de
       Debian (2006-2009).

       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> ».

Linux                                            24 janvier 2014                                       SELECT(2)