Provided by: manpages-fr-dev_3.32d0.2p4-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é de statut. 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 une limite supérieure au temps passé dans select() avant son  retour.  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;

           sigprocmask(SIG_SETMASK, &sigmask, &origmask);
           ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
           sigprocmask(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 retournés (c'est-à-dire le nombre total de bits à 1 dans
       readfds, writefds, exceptfds) qui peut être nul si le délai de timeout a expiré avant  que
       quoi  que  ce  soit d'intéressant ne se produise. Ils retournent -1 s'ils échouent, auquel
       cas errno contient le code d'erreur ; les ensembles et timeout ne sont  plus  définis,  ne
       vous fiez plus à leur contenu après une erreur.

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

   Notes sur Linux
       L'appel  système  pselect()  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 argument timeout, ce qui  est  le  comportement  prescrit  par
       POSIX.1-2001.

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é).

       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

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

       D'autres pages ayant un vague rapport : accept(2), connect(2), poll(2), read(2),  recv(2),
       send(2), sigprocmask(2), write(2), epoll(7), time(7)

COLOPHON

       Cette  page  fait partie de la publication 3.32 du projet man-pages Linux. Une description
       du projet et des  instructions  pour  signaler  des  anomalies  peuvent  être  trouvées  à
       l'adresse <URL:http://www.kernel.org/doc/man-pages/>.

TRADUCTION

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

       Christophe   Blaess   <URL:http://www.blaess.fr/christophe/>   (1996-2003),  Alain  Portal
       <URL: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> ».