poll(2) System Calls Manual poll(2) NOM poll, ppoll - Attendre un evenement concernant un descripteur de fichier BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include int poll(struct pollfd *fds, nfds_t nfds, int timeout); #define _GNU_SOURCE /* Consultez feature_test_macros(7) */ #include int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *_Nullable tmo_p, const sigset_t *_Nullable sigmask); DESCRIPTION poll() fait la meme chose que select(2) : il attend que l'un des descripteurs de fichier soit pret pour des entrees et sorties. L'API de epoll(7) specifique a Linux fait la meme chose, mais avec des fonctionnalites allant au-dela de celles de poll(). L'ensemble de descripteurs de fichier a surveiller est indique dans l'argument fds qui est un tableau de structures de la forme suivante : struct pollfd { int fd; /* Descripteur de fichier */ short events; /* Evenements attendus */ short revents; /* Evenements detectes */ }; L'appelant doit specifier le nombre d'elements du tableau fds dans nfds. Le champ fd contient un descripteur de fichier pour un fichier ouvert. Si ce champ est negatif, alors le champ events correspondant est ignore et le champ revents renvoie zero (cela permet d'ignorer facilement un descripteur de fichier pour un seul appel poll() : il suffit de definir le champ fd a son complement bit a bit). Le champ events est un parametre d'entree, un masque de bits indiquant les evenements qui interessent l'application pour le descripteur de fichier fd. Ce champ peut etre nul, auquel cas les seuls evenements qui peuvent etre renvoyes dans revents sont POLLHUP, POLLERR et POLLNVAL (voir ci-dessous). Le champ revents est un parametre de sortie, rempli par le noyau avec les evenements qui se sont effectivement produits, d'un des types demandes 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 positionnes dans la valeur de retour revents si l'une des conditions correspondantes se produit.) Si aucun evenement attendu (ni aucune erreur) ne s'est deja produit, poll() bloque jusqu'a ce que l'un des evenements se produise. L'argument timeout definit le temps en milliseconde pendant lequel poll() devrait bloquer en attendant que le descripteur de fichier soit pret. L'appel bloquera jusqu'au premier evenement suivant : - un descripteur de fichier devient pret ; - l'appel est interrompu par un gestionnaire de signal ; - le delai expire. Etre << pret >> signifie que l'operation requise ne sera pas bloquee ; donc, l'execution de poll() sur des fichiers ordinaires, des peripheriques bloc et d'autres fichiers sans semantique de scrutation correcte rend la main toujours instantanement comme pret a lire et a ecrire. Remarquez que l'intervalle timeout sera arrondi a la granularite de l'horloge systeme et que les delais d'ordonnancement du noyau signifient que l'intervalle de blocage pourrait etre depasse d'une petite quantite. Une valeur negative de timeout signifie un delai infini, alors qu'un timeout nul force epoll() a se terminer immediatement, meme si aucun descripteur de fichier n'est pret. Les bits qui peuvent etre actives ou renvoyes dans events et revents sont definis par : POLLIN Il y a des donnees en attente de lecture. POLLPRI Il existe une condition d'exception sur le descripteur de fichier. Parmi celles possibles : - Des donnees depassent sur un socket TCP (voir tcp(7)). - Un pseudoterminal maitre en mode paquet a vu un changement d'etat sur l'esclave (voir ioctl_tty(2)). - Un fichier cgroup.events a ete modifie (voir cgroups(7)). POLLOUT L'ecriture est maintenant possible, mais une ecriture plus grande que l'espace disponible sur un socket ou un tube bloquera encore (sauf si O_NONBLOCK est positionne). POLLRDHUP (depuis Linux 2.6.17) Le correspondant sur un socket en mode flux a ferme la connexion ou bien a termine la partie ecriture de la connexion. La macro de test de fonctionnalite _GNU_SOURCE doit etre definie (avant d'inclure tout fichier d'en-tete) pour obtenir cette definition. POLLERR Condition d'erreur (renvoyee seulement dans revents ; ignoree dans events). Ce bit est aussi positionne pour un descripteur de fichier qui se rapporte a une fin d'ecriture sur un tube lorsque la fin de lecture a ete fermee. POLLHUP Plantage (renvoye seulement dans revents ; ignore dans events). Remarquez qu'en lecture a partir d'un canal tel qu'un tube ou un socket de flux, cet evenement indique simplement que le pair a ferme la fin de son canal. Les lectures suivantes a partir du canal ne renverront 0 (fin de fichier) qu'apres que toutes les donnees du canal aient ete consommees. POLLNVAL Requete non valable : fd n'est pas ouvert (renvoye seulement dans revents ; ignore dans events). Lorsque _XOPEN_SOURCE est defini a la compilation, les macros suivantes sont egalement definies (mais n'apportent pas d'informations supplementaires par rapport aux bits listes ci-dessus : POLLRDNORM Equivalent a POLLIN. POLLRDBAND Des donnees prioritaires sont en attente de lecture (generalement inutilise sous Linux). POLLWRNORM Equivalent a POLLOUT. POLLWRBAND Des donnees prioritaires peuvent etre ecrites. Linux connait aussi POLLMSG, mais ne l'utilise pas. ppoll() La relation entre poll() et ppoll() est similaire a la relation entre select(2) et pselect(2) : comme pselect(2), ppoll() permet a une application d'attendre de facon sure que soit un descripteur de fichier soit pret, soit un signal soit recu. Mise a part la difference de precision de l'argument timeout, l'appel ppoll() suivant : ready = ppoll(&fds, nfds, tmo_p, &sigmask); est presque equivalent a executer de facon 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 decrit comme presque equivalent parce qu'une valeur negative dans *tmo_p donne une erreur de ppoll(), tandis qu'une valeur negative de timeout pour poll() est interpretee comme un delai infini. Consultez la description de pselect(2) pour une explication de la necessite de ppoll(). Si le parametre sigmask est defini comme NULL, aucune manipulation de masque de signaux n'est effectuee (et ainsi ppoll() ne differe de poll() que dans la precision du parametre timeout). L'argument tmo_p definit une limite superieure 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 indefiniment. VALEUR RENVOYEE En cas de succes, poll() renvoie une valeur non negative qui est un nombre d'elements dans pollfds dont les champs revents ont ete positionnes sur une valeur autre que zero (indiquant un evenement ou une erreur). Un code de retour de zero indique que l'appel systeme a atteint son delai avant qu'un descripteur de fichier ne soit pret. En cas d'erreur, la valeur de retour est -1 et errno est definie pour preciser l'erreur. ERREURS EFAULT fds pointe hors de l'espace d'adressage accessible. Le tableau donne en argument ne se trouvait pas dans l'espace d'adressage du programme appelant. EINTR Un signal a ete recu avant qu'un evenement interessant ne se produise ; voir signal(7). EINVAL La valeur nfds depasse la valeur RLIMIT_NOFILE. EINVAL (ppoll()) La valeur du delai exprimee dans *tmo_p n'est pas valable (negative). ENOMEM Impossible d'allouer de la memoire pour des structures de donnees du noyau. VERSIONS Sur d'autres systemes UNIX, poll() peut echouer avec l'erreur EAGAIN si le systeme n'arrive pas a allouer des ressources internes au noyau, et non avec ENOMEM comme sur Linux. POSIX autorise ce comportement. Les programmes portables peuvent vouloir verifier EAGAIN et tourner en boucle, comme avec EINTR. Certaines implementations definissent la constante symbolique non standard INFTIM de valeur -1, a utiliser comme timeout pour poll(). Cette constante n'est pas fournie par la glibc. Differences entre bibliotheque C et noyau L'appel systeme 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 delai qui est fournie a l'appel systeme. Ainsi, la fonction ppoll() de la glibc ne modifie donc pas son argument tmo_p. L'appel systeme ppoll() brut a un cinquieme parametre, size_t sigsetsize, qui indique la taille en octets du parametre sigmask. La fonction enveloppe ppoll() de la glibc indique ce parametre comme une valeur fixe (egale a sizeof(kernel_sigset_t)). Voir sigprocmask(2) pour un point sur les differences 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 systeme, la fonction enveloppe poll() de la glibc fournit une emulation en utilisant select(2). ppoll() Linux 2.6.16, glibc 2.4. NOTES L'operation de poll() et ppoll() n'est pas concernee par l'attribut O_NONBLOCK. Consultez select(2) pour une discussion sur ce qui pourrait arriver si un descripteur de fichier surveille par poll() est ferme 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 nommes sur ses parametres de la ligne de commande et surveille les descripteurs de fichier qui en resultent quand a leur possibilite d'etre lus (POLLIN). Le programme effectue une boucle de poll() pour surveiller les descripteurs de fichier, affichant en retour le nombre de descripteurs de fichier prets. Pour chaque descripteur disponible, le programme : - affiche le champ revents renvoye sous une forme lisible par un humain ; - si le descripteur de fichier est lisible, y lit des donnees et affiche ces donnees sur la sortie standard ; et - si le descripteur de fichier n'etait pas lisible, mais qu'un autre evenement 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 deuxieme fenetre de terminal, on ouvre alors le FIFO en ecriture, on y ecrit des donnees et on ferme le FIFO : $ echo aaaaabbbbbccccc > monfifo Dans le terminal ou on execute le programme, on verrait alors : "monfifo" ouvert sur le fd 3 Preparation pour poll() Pret : 1 fd=3; evenements: POLLIN POLLHUP 10 octets lus : aaaaabbbbb Va poll() Pret : 1 fd=3 ; evenements : POLLIN POLLHUP lecture de 6 octets : ccccc Preparation pour poll() Pret : 1 fd=3; evenements : POLLHUP fermeture de fd 3 Tous les descripteurs de fichier sont fermes ; au revoir Dans la sortie ci-dessus, on voit que poll() a renvoye trois fois : - Sur le premier retour, les bits renvoyes dans le champ revents etaient POLLIN, indiquant que le descripteur de fichier est lisible, et POLLHUP, indiquant que l'autre extremite du FIFO a ete fermee. Puis le programme a consomme une partie de l'entree disponible. - Le deuxieme retour de poll() indiquait aussi POLLIN et POLLHUP ; le programme a alors consomme la derniere partie de l'entree disponible. - Sur le dernier retour, poll() n'indiquait que POLLHUP sur le FIFO, lemoment ou le descripteur de fichier a ete ferme et ou le programme s'est termine. Source du programme /* poll_input.c Sous licence GNU General Public v2 ou posterieure. */ #include #include #include #include #include #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("Preparation pour poll()\n"); ready = poll(pfds, nfds, -1); if (ready == -1) errExit("poll"); printf("Pret: %d\n", ready); /* Gerer le tableau renvoye par poll(). */ for (nfds_t j = 0; j < nfds; j++) { if (pfds[j].revents != 0) { printf(" fd=%d; evenements : %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 fermes ; 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 francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Philippe MENGUAL Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 poll(2)