Provided by: manpages-fr-dev_3.27fr1.4-1_all bug

NOM

       select,  pselect,  FD_CLR,  FD_ISSET,  FD_SET,  FD_ZERO  - Multiplexage
       d'entrees-sorties synchrones

SYNOPSIS

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

       /* D'apres les standards precedents */
       #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 fonctionnalites  pour  la  glibc  (consultez
   feature_test_macros(7)) :

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

DESCRIPTION

       select() et pselect() permettent a un programme de surveiller plusieurs
       descripteurs  de  fichier,  en  attendant  qu'au  moins  l'un  de   ces
       descripteurs  soit  << pret >>  pour  une  certaine classe d'operations
       d'entree-sortie. Un descripteur de fichier  est  considere  comme  pret
       s'il  est  possible d'effectuer l'operation correspondante (par exemple
       read(2)) sans bloquer.

       select()  et  pselect()  ont  un  comportement  identique,  avec  trois
       differences :

       (i)    La  fonction  select()  utilise un delai exprime avec une struct
              timeval (secondes et microsecondes), alors que pselect() utilise
              une struct timespec (secondes et nanosecondes).

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

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

       Il  y  a  trois  ensembles  independants  de  descripteurs   surveilles
       simultanement.  Ceux  de  l'ensemble  readfds  seront  surveilles  pour
       verifier si des caracteres  deviennent  disponibles  en  lecture.  Plus
       precisement,  on verifie si un appel systeme de lecture ne bloquera pas
       -- en particulier un descripteur en fin de fichier sera considere comme
       pret.  Les  descripteurs  de l'ensemble writefds seront surveilles pour
       verifier si une ecriture ne bloquera  pas.  Ceux  de  exceptfds  seront
       surveilles  pour l'occurrence de conditions exceptionnelles. En sortie,
       les ensembles sont modifies pour  indiquer  les  descripteurs  qui  ont
       change  de  statut. Chacun des trois ensemble de descripteurs peut etre
       NULL si aucun descripteur de fichier ne doit etre surveille pour  cette
       classe d'evenements.

       Quatre  macros  sont  disponibles  pour  la manipulation des ensembles.
       FD_ZERO()  efface  un  ensemble.  FD_SET()  et  FD_CLR()  ajoutent   et
       suppriment  un  descripteur  dans un ensemble. FD_ISSET() verifie si un
       descripteur est contenu dans un ensemble, principalement utile apres le
       retour de select().

       nfds est le numero du plus grand descripteur des 3 ensembles, plus 1.

       timeout  est  une  limite superieure au temps passe dans select() avant
       son retour. Si les deux champs de la structure timeval sont nuls  alors
       select() retourne immediatement. (Ce qui sert pour des surveillances en
       polling). Si le timeout est NULL (aucune limite), select() peut bloquer
       indefiniment.

       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 indique dans sigmask, puis
       invoque la fonction  << select >>,  et  enfin  restaure  le  masque  de
       signaux a nouveau.

       Mise  a  part la difference de precision de l'argument timeout, l'appel
       pselect() suivant :

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

       est equivalent a executer de facon 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'idee derriere pselect() est que pour l'attente d'un evenement, que ce
       soit  un  signal  ou une condition sur un descripteur, un test atomique
       est necessaire pour eviter 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
       indefiniment  si  le  signal  arrive  juste  apres  le  test mais avant
       l'appel. A l'inverse, pselect() permet de bloquer  le  signal  d'abord,
       traiter  les  signaux  deja  recus,  puis  invoquer  pselect()  avec le
       sigmask, desire, en evitant la situation de blocage.)

   D'elai maximal
       Les structures temporelles concernees sont definies  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  delai  timeout  non  nul,  afin
       d'endormir,  de  maniere portable, le processus avec une precision plus
       fine que la seconde.

       Sous Linux, la fonction select() modifie timeout pour indiquer le temps
       restant  mais  la  plupart  des  autres  implementations ne le font pas
       (POSIX.1-2001 autorise les deux comportements). Ceci pose des problemes
       a  la  fois  pour  porter  sur d'autres systemes du code developpe sous
       Linux qui utilise cette valeur de timeout modifiee, et pour porter sous
       Linux  du  code  qui reutilise plusieurs fois la struct timeval sans la
       reinitialiser. La  meilleure  attitude  a  adopter  est  de  considerer
       timeout comme indefini apres le retour de select().

VALEUR RENVOY'EE

       En  cas  de  reussite  select()  et  pselect()  renvoient  le nombre de
       descripteurs  dans  les  trois  ensembles  de  descripteurs   retournes
       (c'est-a-dire  le  nombre  total  de  bits  a 1 dans readfds, writefds,
       exceptfds) qui peut etre nul si le delai de timeout a expire avant  que
       quoi  que ce soit d'interessant ne se produise. Ils retournent -1 s'ils
       echouent, auquel cas errno contient le code d'erreur ; les ensembles et
       timeout  ne  sont  plus definis, ne vous fiez plus a leur contenu apres
       une erreur.

ERREURS

       EBADF  Un  descripteur  de  fichier  invalide  etait  dans   l'un   des
              ensembles.  (Peut-etre  un descripteur deja ferme, ou sur lequel
              une erreur s'est produite.)

       EINTR  Un signal a ete intercepte ; consultez signal(7).

       EINVAL nfds  est  negatif  ou  la  valeur  contenue  dans  timeout  est
              invalide.

       ENOMEM Pas assez de memoire pour le noyau.

VERSIONS

       pselect()  a  ete  ajoute  a  Linux dans le noyau 2.6.16. Precedemment,
       pselect() etait emule dans la glibc (mais voir la section BOGUES).

CONFORMIT'E

       select() est conforme a POSIX.1-2001 et BSD 4.4 (la  fonction  select()
       est  apparue  dans  BSD 4.2).  Generalement portable depuis ou vers des
       systemes non-BSD supportant des clones de  la  couche  sockets  BSD  (y
       compris les variantes du System V). Neanmoins, 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 defini dans POSIX.1g, et dans POSIX.1-2001.

NOTES

       Un  ensemble  fd_set est un tampon de taille fixe. Executer FD_CLR() ou
       FD_SET() avec fd negatif ou superieur ou egal a FD_SETSIZE resultera en
       un  comportement  indefini.  Plus  encore, POSIX demande que fd soit un
       descripteur de fichier valide.

       En ce qui concerne les types impliques, la situation classique est  que
       les  deux  champs  de  la  structure  timeval soient de type << long >>
       (comme ci-dessus), et que la structure soit definie 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 definie dans <sys/select.h> et les types de donnees
       time_t et suseconds_t definis dans <sys/types.h>.

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

       Les   bibliotheques   libc4   et   libc5   n'avaient   pas    d'en-tete
       <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 errone.  Avec
       la  glibc  2.1  a  2.2.1  le  prototype  de  pselect() est fourni si la
       constante _GNU_SOURCE est definie avant l'inclusion.  Depuis  la  glibc
       2.2.2, les exigences sont celles indiquees dans le SYNOPSIS.

   Notes sur Linux
       L'appel  systeme  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 passe a
       l'appel systeme. Par consequent, 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.

       A  partir  de  la  version  2.1,  la glibc fournissait une emulation de
       pselect()  implementee   avec   sigprocmask(2)   et   select().   Cette
       implementation  etait  vulnerable  a  la  condition  de concurrence que
       pselect() etait concu pour eviter. Les versions recentes  de  la  glibc
       utilisent  l'appel systeme pselect() (sans risque de concurrence) si le
       noyau le fournit.

       Sur les systemes sans pselect, une gestion plus sure (et plus portable)
       des  signaux peut etre obtenue en utilisant un tube (un gestionnaire de
       signal ecrit un octet dans un tube  dont  select()  dans  le  programme
       principal surveille l'autre extremite).

       Sous  Linux,  select()  peut  signaler un descripteur de fichier socket
       comme << pret a lire >> alors  qu'une  lecture  suivante  bloque.  Cela
       peut,  par  exemple,  survenir  lorsque des donnees sont arrivees mais,
       apres  verification,  ont  une  mauvaise  somme  de  controle  et  sont
       rejetees.  Cela  peut  egalement  arriver  dans d'autres circonstances.
       Aussi, il est plus sur d'utiliser O_NONBLOCK sur  des  sockets  qui  ne
       devraient pas bloquer.

       Sous   Linux,   select()  modifie  egalement  timeout  si  l'appel  est
       interrompu par un gestionnaire de signaux (code d'erreur  EINTR).  Ceci
       est  interdit  par  POSIX.1-2001. L'appel systeme pselect() de Linux se
       comporte de la meme facon, mais la glibc cache cette  particularite  en
       copiant  timeout vers une variable locale, et en passant cette variable
       a l'appel systeme.

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'entrees */
           FD_ZERO(&rfds);
           FD_SET(0, &rfds);

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

           retval = select(1, &rfds, NULL, NULL, &tv);
           /* Considerer tv comme indefini maintenant ! */

           if (retval == -1)
               perror("select()");
           else if (retval)
               printf("Des donnees sont disponibles maintenant\n");
               /* FD_ISSET(0, &rfds) est alors vrai. */
           else
               printf("Aucune donnee 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.27 du projet man-pages
       Linux. Une description du projet et des instructions pour signaler  des
       anomalies       peuvent       etre       trouvees      a      l'adresse
       <URL:http://www.kernel.org/doc/man-pages/>.

TRADUCTION

       Depuis 2010, cette traduction est maintenue a l'aide  de  l'outil  po4a
       <URL:http://po4a.alioth.debian.org/>   par   l'equipe   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'equipe francophone de traduction de Debian (2006-2009).

       Veuillez   signaler   toute   erreur   de   traduction  en  ecrivant  a
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous  pouvez  toujours avoir acces a la version anglaise de ce document
       en utilisant la commande << man -L C <section> <page_de_man> >>.

Linux                            31 aout 2010                        SELECT(2)