Man page - poll(2)

Packages contains this manual

Available languages:

en fr ja

Manual

poll

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
ppoll()
VALEUR RENVOYÉE
ERREURS
VERSIONS
Différences entre bibliothÚque C et noyau
STANDARDS
HISTORIQUE
NOTES
BOGUES
EXEMPLES
Source du programme
VOIR AUSSI
TRADUCTION

NOM

poll, ppoll - Attendre un événement concernant un descripteur de fichier

BIBLIOTHÈQUE

BibliothĂšque C standard ( libc , -lc )

SYNOPSIS

#include <poll.h>

int poll(struct pollfd * fds , nfds_t nfds , int timeout );

#define _GNU_SOURCE /* Consultez feature_test_macros(7) */
#include <poll.h>

int ppoll(struct pollfd * fds , nfds_t nfds ,
const struct timespec *_Nullable
tmo_p ,
const sigset_t *_Nullable
sigmask );

DESCRIPTION

poll () fait la mĂȘme chose que select (2) : il attend que l’un des descripteurs de fichier soit prĂȘt pour des entrĂ©es et sorties. L’API de epoll (7) spĂ©cifique Ă  Linux fait la mĂȘme chose, mais avec des fonctionnalitĂ©s allant au-delĂ  de celles de poll ().

L’ensemble de descripteurs de fichier Ă  surveiller est indiquĂ© dans l’argument fds qui est un tableau de structures de la forme suivante :

struct pollfd {
int fd; /* Descripteur de fichier */
short events; /* ÉvĂ©nements attendus */
short revents; /* ÉvĂ©nements dĂ©tectĂ©s */
};

L’appelant doit spĂ©cifier le nombre d’élĂ©ments du tableau fds dans nfds .

Le champ fd contient un descripteur de fichier pour un fichier ouvert. Si ce champ est nĂ©gatif, alors le champ events correspondant est ignorĂ© et le champ revents renvoie zĂ©ro (cela permet d’ignorer facilement un descripteur de fichier pour un seul appel poll () : il suffit de dĂ©finir le champ fd Ă  son complĂ©ment bit Ă  bit).

Le champ events est un paramĂštre d’entrĂ©e, un masque de bits indiquant les Ă©vĂ©nements qui intĂ©ressent l’application pour le descripteur de fichier fd . Ce champ peut ĂȘtre nul, auquel cas les seuls Ă©vĂ©nements qui peuvent ĂȘtre renvoyĂ©s dans revents sont POLLHUP , POLLERR et POLLNVAL (voir ci-dessous).

Le champ revents est un paramĂštre de sortie, rempli par le noyau avec les Ă©vĂ©nements qui se sont effectivement produits, d’un des types demandĂ©s par events ou de l’une des valeurs POLLERR , POLLHUP ou POLLNVAL . (Ces trois bits n’ont pas de signification dans la demande events et se trouvent positionnĂ©s dans la valeur de retour revents si l’une des conditions correspondantes se produit.)

Si aucun Ă©vĂ©nement attendu (ni aucune erreur) ne s’est dĂ©jĂ  produit, poll () bloque jusqu’à ce que l’un des Ă©vĂ©nements se produise.

L’argument timeout dĂ©finit le temps en milliseconde pendant lequel poll () devrait bloquer en attendant que le descripteur de fichier soit prĂȘt. L’appel bloquera jusqu’au premier Ă©vĂ©nement suivant :

-

un descripteur de fichier devient prĂȘt ;

-

l’appel est interrompu par un gestionnaire de signal ;

-

le délai expire.

Être « prĂȘt » signifie que l’opĂ©ration requise ne sera pas bloquĂ©e ; donc, l’exĂ©cution de poll () sur des fichiers ordinaires, des pĂ©riphĂ©riques bloc et d’autres fichiers sans sĂ©mantique de scrutation correcte rend la main toujours instantanĂ©ment comme prĂȘt Ă  lire et Ă  Ă©crire.

Remarquez que l’intervalle timeout sera arrondi Ă  la granularitĂ© de l’horloge systĂšme et que les dĂ©lais d’ordonnancement du noyau signifient que l’intervalle de blocage pourrait ĂȘtre dĂ©passĂ© d’une petite quantitĂ©. Une valeur nĂ©gative de timeout signifie un dĂ©lai infini, alors qu’un timeout nul force epoll () Ă  se terminer immĂ©diatement, mĂȘme si aucun descripteur de fichier n’est prĂȘt.

Les bits qui peuvent ĂȘtre activĂ©s ou renvoyĂ©s dans events et revents sont dĂ©finis par <poll.h> :

POLLIN

Il y a des données en attente de lecture.

POLLPRI

Il existe une condition d’exception sur le descripteur de fichier. Parmi celles possibles :

-

Des données dépassent sur un socket TCP (voir tcp (7)).

-

Un pseudoterminal maĂźtre en mode paquet a vu un changement d’état sur l’esclave (voir ioctl_tty (2)).

-

Un fichier cgroup.events a été modifié (voir cgroups (7)).

POLLOUT

L’écriture est maintenant possible, mais une Ă©criture plus grande que l’espace disponible sur un socket ou un tube bloquera encore (sauf si O_NONBLOCK est positionnĂ©).

POLLRDHUP (depuis Linux 2.6.17)

Le correspondant sur un socket en mode flux a fermĂ© la connexion ou bien a terminĂ© la partie Ă©criture de la connexion. La macro de test de fonctionnalitĂ© _GNU_SOURCE doit ĂȘtre dĂ©finie (avant d’inclure tout fichier d’en-tĂȘte) pour obtenir cette dĂ©finition.

POLLERR

Condition d’erreur (renvoyĂ©e seulement dans revents ; ignorĂ©e dans events ). Ce bit est aussi positionnĂ© pour un descripteur de fichier qui se rapporte Ă  une fin d’écriture sur un tube lorsque la fin de lecture a Ă©tĂ© fermĂ©e.

POLLHUP

Plantage (renvoyĂ© seulement dans revents ; ignorĂ© dans events ). Remarquez qu’en lecture Ă  partir d’un canal tel qu’un tube ou un socket de flux, cet Ă©vĂ©nement indique simplement que le pair a fermĂ© la fin de son canal. Les lectures suivantes Ă  partir du canal ne renverront 0 (fin de fichier) qu’aprĂšs que toutes les donnĂ©es du canal aient Ă©tĂ© consommĂ©es.

POLLNVAL

RequĂȘte non valable : fd n’est pas ouvert (renvoyĂ© seulement dans revents ; ignorĂ© dans events ).

Lorsque _XOPEN_SOURCE est dĂ©fini Ă  la compilation, les macros suivantes sont Ă©galement dĂ©finies (mais n’apportent pas d’informations supplĂ©mentaires par rapport aux bits listĂ©s ci-dessus :
POLLRDNORM

Équivalent à POLLIN .

POLLRDBAND

Des données prioritaires sont en attente de lecture (généralement inutilisé sous Linux).

POLLWRNORM

Équivalent à POLLOUT .

POLLWRBAND

Des donnĂ©es prioritaires peuvent ĂȘtre Ă©crites.

Linux connaüt aussi POLLMSG , mais ne l’utilise pas.

ppoll()

La relation entre poll () et ppoll () est similaire Ă  la relation entre select (2) et pselect (2) : comme pselect (2), ppoll () permet Ă  une application d’attendre de façon sĂ»re que soit un descripteur de fichier soit prĂȘt, soit un signal soit reçu.

Mise Ă  part la diffĂ©rence de prĂ©cision de l’argument timeout , l’appel ppoll () suivant :

ready = ppoll(&fds, nfds, tmo_p, &sigmask);

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

sigset_t origmask;
int timeout;
timeout = (tmo_p == NULL) ? -1 :
(tmo_p->tv_sec * 1000 + tmo_p->tv_nsec / 1000000);
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ready = poll(&fds, nfds, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);

Le bout de code ci-dessus est dĂ©crit comme presque Ă©quivalent parce qu’une valeur nĂ©gative dans *tmo_p donne une erreur de ppoll (), tandis qu’une valeur nĂ©gative de timeout pour poll () est interprĂ©tĂ©e comme un dĂ©lai infini.

Consultez la description de pselect (2) pour une explication de la nécessité de ppoll ().

Si le paramĂštre sigmask est dĂ©fini comme NULL, aucune manipulation de masque de signaux n’est effectuĂ©e (et ainsi ppoll () ne diffĂšre de poll () que dans la prĂ©cision du paramĂštre timeout ).

L’argument tmo_p dĂ©finit une limite supĂ©rieure sur le temps pendant lequel ppoll () bloquera. Cet argument est un pointeur vers une structure timespec (3) :

Si tmo_p est NULL, ppoll () pourra bloquer indéfiniment.

VALEUR RENVOYÉE

En cas de succĂšs, poll () renvoie une valeur non nĂ©gative qui est un nombre d’élĂ©ments dans pollfds dont les champs revents ont Ă©tĂ© positionnĂ©s sur une valeur autre que zĂ©ro (indiquant un Ă©vĂ©nement ou une erreur). Un code de retour de zĂ©ro indique que l’appel systĂšme a atteint son dĂ©lai avant qu’un descripteur de fichier ne soit prĂȘt.

En cas d’erreur, la valeur de retour est -1 et errno est dĂ©finie pour prĂ©ciser l’erreur.

ERREURS

EFAULT

fds pointe hors de l’espace d’adressage accessible. Le tableau donnĂ© en argument ne se trouvait pas dans l’espace d’adressage du programme appelant.

EINTR

Un signal a Ă©tĂ© reçu avant qu’un Ă©vĂ©nement intĂ©ressant ne se produise ; voir signal (7).

EINVAL

La valeur nfds dépasse la valeur RLIMIT_NOFILE .

EINVAL

( ppoll ()) La valeur du dĂ©lai exprimĂ©e dans *tmo_p n’est pas valable (nĂ©gative).

ENOMEM

Impossible d’allouer de la mĂ©moire pour des structures de donnĂ©es du noyau.

VERSIONS

Sur d’autres systĂšmes UNIX, poll () peut Ă©chouer avec l’erreur EAGAIN si le systĂšme n’arrive pas Ă  allouer des ressources internes au noyau, et non avec ENOMEM comme sur Linux. POSIX autorise ce comportement. Les programmes portables peuvent vouloir vĂ©rifier EAGAIN et tourner en boucle, comme avec EINTR .

Certaines implĂ©mentations dĂ©finissent la constante symbolique non standard INFTIM de valeur -1 , Ă  utiliser comme timeout pour poll (). Cette constante n’est pas fournie par la glibc.

Différences entre bibliothÚque C et noyau

L’appel systĂšme ppoll () sous Linux modifie son argument tmo_p . Cependant, l’enveloppe fournie par la glibc cache ce comportement en utilisant une variable locale pour le dĂ©lai qui est fournie Ă  l’appel systĂšme. Ainsi, la fonction ppoll () de la glibc ne modifie donc pas son argument tmo_p .

L’appel systĂšme ppoll () brut a un cinquiĂšme paramĂštre, size_t sigsetsize , qui indique la taille en octets du paramĂštre sigmask . La fonction enveloppe ppoll () de la glibc indique ce paramĂštre comme une valeur fixe (Ă©gale Ă  sizeof(kernel_sigset_t) ). Voir sigprocmask (2) pour un point sur les diffĂ©rences entre l’approche du noyau et de la libc de sigset.

STANDARDS

poll ()

POSIX.1-2008.

ppoll ()

Linux.

HISTORIQUE

poll ()

POSIX.1-2001, Linux 2.1.23.

Sur les anciens noyaux sans cet appel systÚme, la fonction enveloppe poll () de la glibc fournit une émulation en utilisant select (2).

ppoll ()

Linux 2.6.16, glibc 2.4.

NOTES

L’opĂ©ration de poll () et ppoll () n’est pas concernĂ©e par l’attribut O_NONBLOCK .

Consultez select (2) pour une discussion sur ce qui pourrait arriver si un descripteur de fichier surveillé par poll () est fermé dans un autre thread.

BOGUES

Consultez la discussion sur les notifications non voulues dans la section BOGUES de select (2).

EXEMPLES

Le programme ci-dessous ouvre chacun des fichiers nommĂ©s sur ses paramĂštres de la ligne de commande et surveille les descripteurs de fichier qui en rĂ©sultent quand Ă  leur possibilitĂ© d’ĂȘtre lus ( POLLIN ). Le programme effectue une boucle de poll () pour surveiller les descripteurs de fichier, affichant en retour le nombre de descripteurs de fichier prĂȘts. Pour chaque descripteur disponible, le programme :

-

affiche le champ revents renvoyé sous une forme lisible par un humain ;

-

si le descripteur de fichier est lisible, y lit des données et affiche ces données sur la sortie standard ; et

-

si le descripteur de fichier n’était pas lisible, mais qu’un autre Ă©vĂ©nement s’est produit (probablement POLLHUP ), ferme le descripteur de fichier.

Supposons qu’on lance le programme dans un terminal, en lui demandant d’ouvrir un FIFO :

$ mkfifo monfifo
$ ./poll_input monfifo

Dans une deuxiĂšme fenĂȘtre de terminal, on ouvre alors le FIFO en Ă©criture, on y Ă©crit des donnĂ©es et on ferme le FIFO :

$ echo aaaaabbbbbccccc > monfifo

Dans le terminal oĂč on exĂ©cute le programme, on verrait alors :

"monfifo" ouvert sur le fd 3
Préparation pour poll()
PrĂȘt : 1
fd=3; événements: POLLIN POLLHUP
10 octets lus : aaaaabbbbb
Va poll()
PrĂȘt : 1
fd=3 ; événements : POLLIN POLLHUP
lecture de 6 octets : ccccc
Préparation pour poll()

PrĂȘt : 1
fd=3; événements : POLLHUP
fermeture de fd 3
Tous les descripteurs de fichier sont fermés ; au revoir

Dans la sortie ci-dessus, on voit que poll () a renvoyé trois fois :

-

Sur le premier retour, les bits renvoyĂ©s dans le champ revents Ă©taient POLLIN , indiquant que le descripteur de fichier est lisible, et POLLHUP , indiquant que l’autre extrĂ©mitĂ© du FIFO a Ă©tĂ© fermĂ©e. Puis le programme a consommĂ© une partie de l’entrĂ©e disponible.

-

Le deuxiĂšme retour de poll () indiquait aussi POLLIN et POLLHUP ; le programme a alors consommĂ© la derniĂšre partie de l’entrĂ©e disponible.

-

Sur le dernier retour, poll () n’indiquait que POLLHUP sur le FIFO, lemoment oĂč le descripteur de fichier a Ă©tĂ© fermĂ© et oĂč le programme s’est terminĂ©.

Source du programme

/* poll_input.c
Sous licence GNU General Public v2 ou postérieure.
*/
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
int
main(int argc, char *argv[])
{
int ready;
char buf[10];
nfds_t num_open_fds, nfds;
ssize_t s;
struct pollfd *pfds;
if (argc < 2) {
fprintf(stderr, "Utilisation : %s file...\n", argv[0]);
exit(EXIT_FAILURE);
}
num_open_fds = nfds = argc - 1;
pfds = calloc(nfds, sizeof(struct pollfd));
if (pfds == NULL)
errExit("malloc");
/* Ouvrir chaque fichier de la ligne de commande et l’ajouter au tableau
'pfds'. */
for (nfds_t j = 0; j < nfds; j++) {
pfds[j].fd = open(argv[j + 1], O_RDONLY);
if (pfds[j].fd == -1)
errExit("open");
printf(""\"%s\" ouvert sur le fd %d\n", argv[j + 1], pfds[j].fd);
pfds[j].events = POLLIN;
}
/* Conserver poll() au moins aussi longtemps qu’un descripteur de fichier
est ouvert. */
while (num_open_fds > 0) {
printf("Préparation pour poll()\n");
ready = poll(pfds, nfds, -1);
if (ready == -1)
errExit("poll");
printf("PrĂȘt: %d\n", ready);
/* Gérer le tableau renvoyé par poll(). */
for (nfds_t j = 0; j < nfds; j++) {
if (pfds[j].revents != 0) {
printf(" fd=%d; événements : %s%s%s\n", pfds[j].fd,
(pfds[j].revents & POLLIN) ? "POLLIN " : "",
(pfds[j].revents & POLLHUP) ? "POLLHUP " : "",
(pfds[j].revents & POLLERR) ? "POLLERR " : "");
if (pfds[j].revents & POLLIN) {
s = read(pfds[j].fd, buf, sizeof(buf));
if (s == -1)
errExit("read");
printf(" lecture de %zd octets : %.*s\n",
s, (int) s, buf);
} else { /* POLLERR | POLLHUP */
printf(" fermeture du fd %d\n", pfds[j].fd);
if (close(pfds[j].fd) == -1)
errExit("close");
num_open_fds--;
}
}
}
}
printf("Tous les descripteurs de fichier sont fermés ; au revoir\n");
exit(EXIT_SUCCESS);
}

VOIR AUSSI

restart_syscall (2), select (2), select_tut (2), timespec (3), epoll (7), time (7)

TRADUCTION

La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n’y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org .