dwww Home | Manual pages | Find package

getaddrinfo_a(3)           Library Functions Manual           getaddrinfo_a(3)

NOM
       getaddrinfo_a,  gai_suspend,  gai_error,  gai_cancel - Traduction asyn-
       chrone d'adresses et de services réseau

BIBLIOTHÈQUE
       Bibliothèque de résolution de noms asynchrone (libanl, -lanl)

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

       int getaddrinfo_a(int mode, struct gaicb *list[restrict],
                         int nitems, struct sigevent *restrict sevp);
       int gai_suspend(const struct gaicb *const list[], int nitems,
                         const struct timespec *timeout);

       int gai_error(struct gaicb *req);
       int gai_cancel(struct gaicb *req);

DESCRIPTION
       La fonction getaddrinfo_a()  effectue  la  même  opération  que  getad-
       drinfo(3),  mais  permet  d'effectuer  plusieurs résolutions de manière
       asynchrone et de recevoir une notification à chaque  résolution  effec-
       tuée.

       Le champ mode peut prendre une des valeurs suivantes :

       GAI_WAIT
              Effectue  les  résolutions  de manière synchrone. L'appel bloque
              tant que les résolutions ne sont pas terminées.

       GAI_NOWAIT
              Effectue les résolutions de manière asynchrone. L'appel s'achève
              immédiatement  et  les  requêtes  sont résolues en arrière-plan.
              Consultez la description du paramètre sevp ci-dessous.

       Le tableau list indique les requêtes de recherche  à  traiter.  Le  pa-
       ramètre  nitems  indique le nombre d'éléments dans list. Les opérations
       de recherche demandées sont lancées en parallèle. Les éléments  égal  à
       NULL de list sont ignorés. Chaque requête est décrite par une structure
       gaicb définie ci-dessous :

           struct gaicb {
               const char            *ar_name;
               const char            *ar_service;
               const struct addrinfo *ar_request;
               struct addrinfo       *ar_result;
           };

       Les éléments de cette structure correspondent aux paramètres de  getad-
       drinfo(3). Ainsi, ar_name correspond au paramètre node et ar_service au
       paramètre service, identifiant respectivement un hôte et un service In-
       ternet.  L'élément  ar_request correspond au paramètre hints, indiquant
       le critère de sélection des structures d'adresse de  socket  renvoyées.
       Enfin,  ar_result  correspond au paramètre res ; vous n'avez pas besoin
       d'initialiser ce paramètre, il sera automatiquement défini  lorsque  la
       requête  sera  résolue.  La  structure addrinfo référencée par les deux
       derniers éléments est décrite dans getaddrinfo(3).

       Lorsque mode est défini à GAI_NOWAIT, les  notifications  des  requêtes
       résolues  peuvent  être obtenues avec la structure sigevent pointée par
       le paramètre sevp. Pour la définition et les détails généraux de  cette
       structure,  consultez  sigevent(7).  Le  champ  sevp->sigev_notify peut
       prendre l'une des valeurs suivantes :

       SIGEV_NONE
              Ne fournit pas de notification.

       SIGEV_SIGNAL
              Lorsqu'une recherche se termine, générer le signal sigev_signo à
              destination du processus. Consultez sigevent(7) pour plus de dé-
              tails. Le champ si_code de la structure siginfo_t sera défini  à
              SI_ASYNCNL.

       SIGEV_THREAD
              Lors  d'une  résolution, invoquer sigev_notify_function comme si
              c'était la fonction de création d'un  nouveau  processus  léger.
              Consultez sigevent(7) pour plus détails.

       Pour  SIGEV_SIGNAL et SIGEV_THREAD, il peut être utile de faire pointer
       sevp->sigev_value.sival_ptr vers list.

       La fonction gai_suspend() suspend l'exécution du processus léger  appe-
       lant,  attendant  la  fin  d'une ou plusieurs requêtes du tableau list.
       L'argument nitems indique la taille du tableau list. L'appel  est  blo-
       quant tant que l'un des événements suivants ne se produisent :

       •  Une ou plusieurs des opérations de list se sont terminées.

       •  L'appel a été interrompu par un signal qui a été interrompu.

       •  L'intervalle  de  temps  indiqué  dans  timeout s'est écoulé. Ce pa-
          ramètre indique un délai en seconds plus nanosecondes (consultez na-
          nosleep(2)  pour  plus de détails sur la structure timespec). Si ti-
          meout est NULL, alors l'appel est bloqué indéfiniment (à  moins  que
          l'un des événement ci-dessus se produisent).

       Aucune indication explicite sur la requête qui s'est terminée est four-
       nie ; vous devez déterminer quelle requête s'est terminée en parcourant
       avec  gai_error()  la  liste des requête (il peut y avoir plusieurs re-
       quêtes).

       La fonction gai_error() renvoie l'état de la requête req : soit EAI_IN-
       PROGRESS  si  la  requête  ne s'est pas encore terminée, soit 0 si elle
       s'est terminé correctement ou soit un code d'erreur si elle ne peut pas
       être résolue.

       La fonction gai_cancel() annule la requête req. Si la requête a été an-
       nulée avec succès, le statut d'erreur  de  la  requête  sera  défini  à
       EAI_CANCELED  et  un  notification asynchrone normale sera exécutée. La
       requête ne peut pas être annulée si elle est en  cours  d'utilisation ;
       dans  ce  cas, elle continuera comme si gai_cancel() n'avait jamais été
       appelée. Si req est NULL, une tentative d'annulation de toutes les  re-
       quêtes en cours que le processus a fait sera exécutée.

VALEUR RENVOYÉE
       La  fonction  getaddrinfo_a()  renvoie 0 si toutes les requêtes ont été
       mises en file d'attente avec succès, ou un des codes d'erreur non  nuls
       suivants :

       EAI_AGAIN
              Les ressources nécessaires pour mettre en file d'attente les re-
              quêtes de recherche ne sont pas disponibles.  L'application  de-
              vrait  vérifier le statut d'erreur de chaque requête pour déter-
              miner laquelle a échoué.

       EAI_MEMORY
              Plus assez de mémoire.

       EAI_SYSTEM
              mode est non valable.

       La fonction gai_suspend() renvoie 0 si au moins une des  requêtes  lis-
       tées s'est terminée. Sinon, elle renvoie un des codes d'erreur non nuls
       suivants :

       EAI_AGAIN
              Le délai d'attente a expiré avant que toute requête ne soit ter-
              minée.

       EAI_ALLDONE
              Il n'y a actuellement aucune requête fournie à la fonction.

       EAI_INTR
              Un signal a interrompu la fonction. Notez que cette interruption
              pourrait avoir été causé par une notification de signal  de  fin
              de certaines requêtes de recherche.

       La  fonction  gai_error() peut renvoyer EAI_INPROGRESS pour une requête
       de recherche non terminée, 0 pour une recherche  terminée  avec  succès
       (cas décrit ci-dessus), un des codes d'erreur qui peut être renvoyé par
       getaddrinfo(3), ou le code d'erreur EAI_CANCELED si la  requête  a  été
       annulée explicitement avant quelle ne soit terminée.

       La fonction gai_cancel() peut renvoyer une des valeurs suivantes :

       EAI_CANCELED
              La requête a été annulée avec succès.

       EAI_NOTCANCELED
              La requête n'a pas été annulée.

       EAI_ALLDONE
              La requête est déjà terminée.

       La fonction gai_strerror(3) traduit ces codes d'erreur en une chaîne de
       caractères compréhensible, utilisable pour rendre compte du problème.

ATTRIBUTS
       Pour une explication des termes utilisés dans cette section,  consulter
       attributes(7).

       ┌─────────────────────────────────────┬──────────────────────┬─────────┐
       │InterfaceAttributValeur  │
       ├─────────────────────────────────────┼──────────────────────┼─────────┤
       │getaddrinfo_a(), gai_suspend(),      │ Sécurité des threads │ MT-Safe │
       │gai_error(), gai_cancel()            │                      │         │
       └─────────────────────────────────────┴──────────────────────┴─────────┘

STANDARDS
       Ces fonctions sont des extensions GNU. Elles ont été  introduites  dans
       la glibc 2.2.3.

NOTES
       L'interface   de  getaddrinfo_a()  a  été  modifiée  après  l'interface
       lio_listio(3).

EXEMPLES
       Deux exemples sont fournis : un simple exemple qui résout plusieurs re-
       quête  en  parallèle de façon synchrone et un exemple complexe montrant
       certaines des capacités asynchrones.

   Exemple synchrone
       Le programme ci-dessous résout simplement plusieurs noms d'hôte en  pa-
       rallèle,  améliorant  le temps de résolution des noms d'hôtes comparé à
       des appels séquentiels à getaddrinfo(3). Le programme peut être utilisé
       comme suit :

           $ ./a.out mirrors.kernel.org enoent.linuxfoundation.org gnu.org
           mirrors.kernel.org: 139.178.88.99
           enoent.linuxfoundation.org: Name or service not known
           gnu.org: 209.51.188.116

       Voilà le code source du programme

       #define _GNU_SOURCE
       #include <netdb.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>

       int
       main(int argc, char *argv[])
       {
           int ret;
           struct gaicb *reqs[argc - 1];
           char host[NI_MAXHOST];
           struct addrinfo *res;

           if (argc < 2) {
               fprintf(stderr, "Usage: %s HOST...\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           for (size_t i = 0; i < argc - 1; i++) {
               reqs[i] = malloc(sizeof(*reqs[0]));
               if (reqs[i] == NULL) {
                   perror("malloc");
                   exit(EXIT_FAILURE);
               }
               memset(reqs[i], 0, sizeof(*reqs[0]));
               reqs[i]->ar_name = argv[i + 1];
           }

           ret = getaddrinfo_a(GAI_WAIT, reqs, argc - 1, NULL);
           if (ret != 0) {
               fprintf(stderr, "getaddrinfo_a() failed: %s\n",
                       gai_strerror(ret));
               exit(EXIT_FAILURE);
           }

           for (size_t i = 0; i < argc - 1; i++) {
               printf("%s: ", reqs[i]->ar_name);
               ret = gai_error(reqs[i]);
               if (ret == 0) {
                   res = reqs[i]->ar_result;

                   ret = getnameinfo(res->ai_addr, res->ai_addrlen,
                                     host, sizeof(host),
                                     NULL, 0, NI_NUMERICHOST);
                   if (ret != 0) {
                       fprintf(stderr, "getnameinfo() failed: %s\n",
                               gai_strerror(ret));
                       exit(EXIT_FAILURE);
                   }
                   puts(host);

               } else {
                   puts(gai_strerror(ret));
               }
           }
           exit(EXIT_SUCCESS);
       }

   Exemple asynchrone
       Cet  exemple  est  une  simple application interactive utilisant getad-
       drinfo_a(). Les fonctionnalités de notification ne sont pas exploitées.

       Un exemple de session pourrait ressembler à ceci :

           $ ./a.out
           > a mirrors.kernel.org enoent.linuxfoundation.org gnu.org
           > c 2
           [2] gnu.org: Request not canceled
           > w 0 1
           [00] mirrors.kernel.org: Finished
           > l
           [00] mirrors.kernel.org: 139.178.88.99
           [01] enoent.linuxfoundation.org: Processing request in progress
           [02] gnu.org: 209.51.188.116
           > l
           [00] mirrors.kernel.org: 139.178.88.99
           [01] enoent.linuxfoundation.org: Name or service not known
           [02] gnu.org: 209.51.188.116

       Le code source du programme est :

       #define _GNU_SOURCE
       #include <netdb.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>

       static struct gaicb **reqs = NULL;
       static size_t nreqs = 0;

       static char *
       getcmd(void)
       {
           static char buf[256];

           fputs("> ", stdout); fflush(stdout);
           if (fgets(buf, sizeof(buf), stdin) == NULL)
               return NULL;

           if (buf[strlen(buf) - 1] == '\n')
               buf[strlen(buf) - 1] = 0;

           return buf;
       }

       /* Add requests for specified hostnames. */
       static void
       add_requests(void)
       {
           size_t nreqs_base = nreqs;
           char *host;
           int ret;

           while ((host = strtok(NULL, " "))) {
               nreqs++;
               reqs = realloc(reqs, sizeof(reqs[0]) * nreqs);

               reqs[nreqs - 1] = calloc(1, sizeof(*reqs[0]));
               reqs[nreqs - 1]->ar_name = strdup(host);
           }

           /* Queue nreqs_base..nreqs requests. */

           ret = getaddrinfo_a(GAI_NOWAIT, &reqs[nreqs_base],
                               nreqs - nreqs_base, NULL);
           if (ret) {
               fprintf(stderr, "getaddrinfo_a() failed: %s\n",
                       gai_strerror(ret));
               exit(EXIT_FAILURE);
           }
       }

       /* Wait until at least one of specified requests completes. */
       static void
       wait_requests(void)
       {
           char *id;
           int ret;
           size_t n;
           struct gaicb const **wait_reqs = calloc(nreqs, sizeof(*wait_reqs));
                       /* NULL elements are ignored by gai_suspend(). */

           while ((id = strtok(NULL, " ")) != NULL) {
               n = atoi(id);

               if (n >= nreqs) {
                   printf("Bad request number: %s\n", id);
                   return;
               }

               wait_reqs[n] = reqs[n];
           }

           ret = gai_suspend(wait_reqs, nreqs, NULL);
           if (ret) {
               printf("gai_suspend(): %s\n", gai_strerror(ret));
               return;
           }

           for (size_t i = 0; i < nreqs; i++) {
               if (wait_reqs[i] == NULL)
                   continue;

               ret = gai_error(reqs[i]);
               if (ret == EAI_INPROGRESS)
                   continue;

               printf("[%02zu] %s: %s\n", i, reqs[i]->ar_name,
                      ret == 0 ? "Finished" : gai_strerror(ret));
           }
       }

       /* Cancel specified requests. */
       static void
       cancel_requests(void)
       {
           char *id;
           int ret;
           size_t n;

           while ((id = strtok(NULL, " ")) != NULL) {
               n = atoi(id);

               if (n >= nreqs) {
                   printf("Bad request number: %s\n", id);
                   return;
               }

               ret = gai_cancel(reqs[n]);
               printf("[%s] %s: %s\n", id, reqs[atoi(id)]->ar_name,
                      gai_strerror(ret));
           }
       }

       /* List all requests. */
       static void
       list_requests(void)
       {
           int ret;
           char host[NI_MAXHOST];
           struct addrinfo *res;

           for (size_t i = 0; i < nreqs; i++) {
               printf("[%02zu] %s: ", i, reqs[i]->ar_name);
               ret = gai_error(reqs[i]);

               if (!ret) {
                   res = reqs[i]->ar_result;

                   ret = getnameinfo(res->ai_addr, res->ai_addrlen,
                                     host, sizeof(host),
                                     NULL, 0, NI_NUMERICHOST);
                   if (ret) {
                       fprintf(stderr, "getnameinfo() failed: %s\n",
                               gai_strerror(ret));
                       exit(EXIT_FAILURE);
                   }
                   puts(host);
               } else {
                   puts(gai_strerror(ret));
               }
           }
       }

       int
       main(void)
       {
           char *cmdline;
           char *cmd;

           while ((cmdline = getcmd()) != NULL) {
               cmd = strtok(cmdline, " ");

               if (cmd == NULL) {
                   list_requests();
               } else {
                   switch (cmd[0]) {
                   case 'a':
                       add_requests();
                       break;
                   case 'w':
                       wait_requests();
                       break;
                   case 'c':
                       cancel_requests();
                       break;
                   case 'l':
                       list_requests();
                       break;
                   default:
                       fprintf(stderr, "Bad command: %c\n", cmd[0]);
                       break;
                   }
               }
           }
           exit(EXIT_SUCCESS);
       }

VOIR AUSSI
       getaddrinfo(3), inet(3), lio_listio(3), hostname(7), ip(7), sigevent(7)

TRADUCTION
       La traduction française de cette page de manuel a été créée par  Chris-
       tophe  Blaess  <https://www.blaess.fr/christophe/>, Stéphan Rafin <ste-
       phan.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.cou-
       lon@wanadoo.fr>,  Julien  Cristau <jcristau@debian.org>, Thomas Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François  <nicolas.francois@centra-
       liens.net>,  Florentin  Duneau <fduneau@gmail.com>, Simon Paillard <si-
       mon.paillard@resel.enst-bretagne.fr>,   Denis   Barbier    <barbier@de-
       bian.org> et David Prévot <david@tilapin.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⟩.

Pages du manuel de Linux 6.03   5 février 2023                getaddrinfo_a(3)

Generated by dwww version 1.15 on Sat Jun 29 00:26:50 CEST 2024.