plucky (2) poll.2.gz

Provided by: manpages-fr-dev_4.25.1-1_all bug

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

          Licensed under GNU General Public License v2 or later.
       */
       #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, "Usage: %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");

           /* Open each file on command line, and add it to 'pfds' array. */

           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("Opened \"%s\" on fd %d\n", argv[j + 1], pfds[j].fd);

               pfds[j].events = POLLIN;
           }

           /* Keep calling poll() as long as at least one file descriptor is
              open. */

           while (num_open_fds > 0) {
               printf("About to poll()\n");
               ready = poll(pfds, nfds, -1);
               if (ready == -1)
                   errExit("poll");

               printf("Ready: %d\n", ready);

               /* Deal with array returned by poll(). */

               for (nfds_t j = 0; j < nfds; j++) {
                   if (pfds[j].revents != 0) {
                       printf("  fd=%d; events: %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("    read %zd bytes: %.*s\n",
                                  s, (int) s, buf);
                       } else {                /* POLLERR | POLLHUP */
                           printf("    closing fd %d\n", pfds[j].fd);
                           if (close(pfds[j].fd) == -1)
                               errExit("close");
                           num_open_fds--;
                       }
                   }
               }
           }

           printf("All file descriptors closed; bye\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   ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   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⟩.