Provided by:
manpages-fr-dev_3.32d0.2p4-1_all 
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() ajoute et FD_CLR() supprime 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.32 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)