summaryrefslogtreecommitdiffstats
path: root/man3/getaddrinfo_a.3
diff options
context:
space:
mode:
Diffstat (limited to 'man3/getaddrinfo_a.3')
-rw-r--r--man3/getaddrinfo_a.3645
1 files changed, 0 insertions, 645 deletions
diff --git a/man3/getaddrinfo_a.3 b/man3/getaddrinfo_a.3
deleted file mode 100644
index fe27b6c..0000000
--- a/man3/getaddrinfo_a.3
+++ /dev/null
@@ -1,645 +0,0 @@
-'\" t
-.\" Copyright (c) 2009 Petr Baudis <pasky@suse.cz>
-.\" and clean-ups and additions (C) Copyright 2010 Michael Kerrisk
-.\" <mtk.manpages@gmail.com>
-.\"
-.\" SPDX-License-Identifier: Linux-man-pages-copyleft
-.\"
-.\" References: http://people.redhat.com/drepper/asynchnl.pdf,
-.\" http://www.imperialviolet.org/2005/06/01/asynchronous-dns-lookups-with-glibc.html
-.\"
-.TH getaddrinfo_a 3 2023-10-31 "Linux man-pages 6.7"
-.SH NAME
-getaddrinfo_a, gai_suspend, gai_error, gai_cancel \- asynchronous
-network address and service translation
-.SH LIBRARY
-Asynchronous name lookup library
-.RI ( libanl ", " \-lanl )
-.SH SYNOPSIS
-.nf
-.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
-.B #include <netdb.h>
-.P
-.BI "int getaddrinfo_a(int " mode ", struct gaicb *" list [restrict],
-.BI " int " nitems ", struct sigevent *restrict " sevp );
-.BI "int gai_suspend(const struct gaicb *const " list "[], int " nitems ,
-.BI " const struct timespec *" timeout );
-.P
-.BI "int gai_error(struct gaicb *" req );
-.BI "int gai_cancel(struct gaicb *" req );
-.fi
-.SH DESCRIPTION
-The
-.BR getaddrinfo_a ()
-function performs the same task as
-.BR getaddrinfo (3),
-but allows multiple name look-ups to be performed asynchronously,
-with optional notification on completion of look-up operations.
-.P
-The
-.I mode
-argument has one of the following values:
-.TP
-.B GAI_WAIT
-Perform the look-ups synchronously.
-The call blocks until the look-ups have completed.
-.TP
-.B GAI_NOWAIT
-Perform the look-ups asynchronously.
-The call returns immediately,
-and the requests are resolved in the background.
-See the discussion of the
-.I sevp
-argument below.
-.P
-The array
-.I list
-specifies the look-up requests to process.
-The
-.I nitems
-argument specifies the number of elements in
-.IR list .
-The requested look-up operations are started in parallel.
-NULL elements in
-.I list
-are ignored.
-Each request is described by a
-.I gaicb
-structure, defined as follows:
-.P
-.in +4n
-.EX
-struct gaicb {
- const char *ar_name;
- const char *ar_service;
- const struct addrinfo *ar_request;
- struct addrinfo *ar_result;
-};
-.EE
-.in
-.P
-The elements of this structure correspond to the arguments of
-.BR getaddrinfo (3).
-Thus,
-.I ar_name
-corresponds to the
-.I node
-argument and
-.I ar_service
-to the
-.I service
-argument, identifying an Internet host and a service.
-The
-.I ar_request
-element corresponds to the
-.I hints
-argument, specifying the criteria for selecting
-the returned socket address structures.
-Finally,
-.I ar_result
-corresponds to the
-.I res
-argument; you do not need to initialize this element,
-it will be automatically set when the request
-is resolved.
-The
-.I addrinfo
-structure referenced by the last two elements is described in
-.BR getaddrinfo (3).
-.P
-When
-.I mode
-is specified as
-.BR GAI_NOWAIT ,
-notifications about resolved requests
-can be obtained by employing the
-.I sigevent
-structure pointed to by the
-.I sevp
-argument.
-For the definition and general details of this structure, see
-.BR sigevent (3type).
-The
-.I sevp\->sigev_notify
-field can have the following values:
-.TP
-.B SIGEV_NONE
-Don't provide any notification.
-.TP
-.B SIGEV_SIGNAL
-When a look-up completes, generate the signal
-.I sigev_signo
-for the process.
-See
-.BR sigevent (3type)
-for general details.
-The
-.I si_code
-field of the
-.I siginfo_t
-structure will be set to
-.BR SI_ASYNCNL .
-.\" si_pid and si_uid are also set, to the values of the calling process,
-.\" which doesn't provide useful information, so we'll skip mentioning it.
-.TP
-.B SIGEV_THREAD
-When a look-up completes, invoke
-.I sigev_notify_function
-as if it were the start function of a new thread.
-See
-.BR sigevent (3type)
-for details.
-.P
-For
-.B SIGEV_SIGNAL
-and
-.BR SIGEV_THREAD ,
-it may be useful to point
-.I sevp\->sigev_value.sival_ptr
-to
-.IR list .
-.P
-The
-.BR gai_suspend ()
-function suspends execution of the calling thread,
-waiting for the completion of one or more requests in the array
-.IR list .
-The
-.I nitems
-argument specifies the size of the array
-.IR list .
-The call blocks until one of the following occurs:
-.IP \[bu] 3
-One or more of the operations in
-.I list
-completes.
-.IP \[bu]
-The call is interrupted by a signal that is caught.
-.IP \[bu]
-The time interval specified in
-.I timeout
-elapses.
-This argument specifies a timeout in seconds plus nanoseconds (see
-.BR nanosleep (2)
-for details of the
-.I timespec
-structure).
-If
-.I timeout
-is NULL, then the call blocks indefinitely
-(until one of the events above occurs).
-.P
-No explicit indication of which request was completed is given;
-you must determine which request(s) have completed by iterating with
-.BR gai_error ()
-over the list of requests.
-.P
-The
-.BR gai_error ()
-function returns the status of the request
-.IR req :
-either
-.B EAI_INPROGRESS
-if the request was not completed yet,
-0 if it was handled successfully,
-or an error code if the request could not be resolved.
-.P
-The
-.BR gai_cancel ()
-function cancels the request
-.IR req .
-If the request has been canceled successfully,
-the error status of the request will be set to
-.B EAI_CANCELED
-and normal asynchronous notification will be performed.
-The request cannot be canceled if it is currently being processed;
-in that case, it will be handled as if
-.BR gai_cancel ()
-has never been called.
-If
-.I req
-is NULL, an attempt is made to cancel all outstanding requests
-that the process has made.
-.SH RETURN VALUE
-The
-.BR getaddrinfo_a ()
-function returns 0 if all of the requests have been enqueued successfully,
-or one of the following nonzero error codes:
-.TP
-.B EAI_AGAIN
-The resources necessary to enqueue the look-up requests were not available.
-The application may check the error status of each
-request to determine which ones failed.
-.TP
-.B EAI_MEMORY
-Out of memory.
-.TP
-.B EAI_SYSTEM
-.I mode
-is invalid.
-.P
-The
-.BR gai_suspend ()
-function returns 0 if at least one of the listed requests has been completed.
-Otherwise, it returns one of the following nonzero error codes:
-.TP
-.B EAI_AGAIN
-The given timeout expired before any of the requests could be completed.
-.TP
-.B EAI_ALLDONE
-There were no actual requests given to the function.
-.TP
-.B EAI_INTR
-A signal has interrupted the function.
-Note that this interruption might have been
-caused by signal notification of some completed look-up request.
-.P
-The
-.BR gai_error ()
-function can return
-.B EAI_INPROGRESS
-for an unfinished look-up request,
-0 for a successfully completed look-up
-(as described above), one of the error codes that could be returned by
-.BR getaddrinfo (3),
-or the error code
-.B EAI_CANCELED
-if the request has been canceled explicitly before it could be finished.
-.P
-The
-.BR gai_cancel ()
-function can return one of these values:
-.TP
-.B EAI_CANCELED
-The request has been canceled successfully.
-.TP
-.B EAI_NOTCANCELED
-The request has not been canceled.
-.TP
-.B EAI_ALLDONE
-The request has already completed.
-.P
-The
-.BR gai_strerror (3)
-function translates these error codes to a human readable string,
-suitable for error reporting.
-.SH ATTRIBUTES
-For an explanation of the terms used in this section, see
-.BR attributes (7).
-.TS
-allbox;
-lbx lb lb
-l l l.
-Interface Attribute Value
-T{
-.na
-.nh
-.BR getaddrinfo_a (),
-.BR gai_suspend (),
-.BR gai_error (),
-.BR gai_cancel ()
-T} Thread safety MT-Safe
-.TE
-.SH STANDARDS
-GNU.
-.SH HISTORY
-glibc 2.2.3.
-.P
-The interface of
-.BR getaddrinfo_a ()
-was modeled after the
-.BR lio_listio (3)
-interface.
-.SH EXAMPLES
-Two examples are provided: a simple example that resolves
-several requests in parallel synchronously, and a complex example
-showing some of the asynchronous capabilities.
-.SS Synchronous example
-The program below simply resolves several hostnames in parallel,
-giving a speed-up compared to resolving the hostnames sequentially using
-.BR getaddrinfo (3).
-The program might be used like this:
-.P
-.in +4n
-.EX
-$ \fB./a.out mirrors.kernel.org enoent.linuxfoundation.org gnu.org\fP
-mirrors.kernel.org: 139.178.88.99
-enoent.linuxfoundation.org: Name or service not known
-gnu.org: 209.51.188.116
-.EE
-.in
-.P
-Here is the program source code
-.P
-.\" SRC BEGIN (sync.c)
-.EX
-#define _GNU_SOURCE
-#include <err.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-\&
-#define MALLOC(n, type) ((type *) reallocarray(NULL, n, sizeof(type)))
-\&
-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...\en", argv[0]);
- exit(EXIT_FAILURE);
- }
-\&
- for (size_t i = 0; i < argc \- 1; i++) {
- reqs[i] = MALLOC(1, struct gaicb);
- if (reqs[i] == NULL)
- err(EXIT_FAILURE, "malloc");
-\&
- 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\en",
- 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\en",
- gai_strerror(ret));
- exit(EXIT_FAILURE);
- }
- puts(host);
-\&
- } else {
- puts(gai_strerror(ret));
- }
- }
- exit(EXIT_SUCCESS);
-}
-.EE
-.\" SRC END
-.SS Asynchronous example
-This example shows a simple interactive
-.BR getaddrinfo_a ()
-front-end.
-The notification facility is not demonstrated.
-.P
-An example session might look like this:
-.P
-.in +4n
-.EX
-$ \fB./a.out\fP
-> 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
-.EE
-.in
-.P
-The program source is as follows:
-.P
-.\" SRC BEGIN (async.c)
-.EX
-#define _GNU_SOURCE
-#include <assert.h>
-#include <err.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-\&
-#define CALLOC(n, type) ((type *) calloc(n, sizeof(type)))
-\&
-#define REALLOCF(ptr, n, type) \e
-({ \e
- static_assert(__builtin_types_compatible_p(typeof(ptr), type *)); \e
- \e
- (type *) reallocarrayf(ptr, n, sizeof(type)); \e
-})
-\&
-static struct gaicb **reqs = NULL;
-static size_t nreqs = 0;
-\&
-static inline void *
-reallocarrayf(void *p, size_t nmemb, size_t size)
-{
- void *q;
-\&
- q = reallocarray(p, nmemb, size);
- if (q == NULL && nmemb != 0 && size != 0)
- free(p);
- return q;
-}
-\&
-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] == \[aq]\en\[aq])
- 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 = REALLOCF(reqs, nreqs, struct gaicb *);
- if (reqs == NULL)
- err(EXIT_FAILURE, "reallocf");
-\&
- reqs[nreqs \- 1] = CALLOC(1, struct gaicb);
- if (reqs[nreqs \- 1] == NULL)
- err(EXIT_FAILURE, "calloc");
-\&
- 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\en",
- 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;
-\&
- wait_reqs = CALLOC(nreqs, const struct gaicb *);
- if (wait_reqs == NULL)
- err(EXIT_FAILURE, "calloc");
-\&
- /* NULL elements are ignored by gai_suspend(). */
-\&
- while ((id = strtok(NULL, " ")) != NULL) {
- n = atoi(id);
-\&
- if (n >= nreqs) {
- printf("Bad request number: %s\en", id);
- return;
- }
-\&
- wait_reqs[n] = reqs[n];
- }
-\&
- ret = gai_suspend(wait_reqs, nreqs, NULL);
- if (ret) {
- printf("gai_suspend(): %s\en", 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\en", 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\en", id);
- return;
- }
-\&
- ret = gai_cancel(reqs[n]);
- printf("[%s] %s: %s\en", 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\en",
- 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 \[aq]a\[aq]:
- add_requests();
- break;
- case \[aq]w\[aq]:
- wait_requests();
- break;
- case \[aq]c\[aq]:
- cancel_requests();
- break;
- case \[aq]l\[aq]:
- list_requests();
- break;
- default:
- fprintf(stderr, "Bad command: %c\en", cmd[0]);
- break;
- }
- }
- }
- exit(EXIT_SUCCESS);
-}
-.EE
-.\" SRC END
-.SH SEE ALSO
-.BR getaddrinfo (3),
-.BR inet (3),
-.BR lio_listio (3),
-.BR hostname (7),
-.BR ip (7),
-.BR sigevent (3type)