diff options
Diffstat (limited to 'man3/getaddrinfo_a.3')
-rw-r--r-- | man3/getaddrinfo_a.3 | 645 |
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) |