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.3109
1 files changed, 71 insertions, 38 deletions
diff --git a/man3/getaddrinfo_a.3 b/man3/getaddrinfo_a.3
index 4b891ab..fe27b6c 100644
--- a/man3/getaddrinfo_a.3
+++ b/man3/getaddrinfo_a.3
@@ -8,7 +8,7 @@
.\" 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-07-20 "Linux man-pages 6.05.01"
+.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
@@ -19,12 +19,12 @@ Asynchronous name lookup library
.nf
.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
.B #include <netdb.h>
-.PP
+.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 );
-.PP
+.P
.BI "int gai_error(struct gaicb *" req );
.BI "int gai_cancel(struct gaicb *" req );
.fi
@@ -35,7 +35,7 @@ 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.
-.PP
+.P
The
.I mode
argument has one of the following values:
@@ -51,7 +51,7 @@ and the requests are resolved in the background.
See the discussion of the
.I sevp
argument below.
-.PP
+.P
The array
.I list
specifies the look-up requests to process.
@@ -66,7 +66,7 @@ are ignored.
Each request is described by a
.I gaicb
structure, defined as follows:
-.PP
+.P
.in +4n
.EX
struct gaicb {
@@ -77,7 +77,7 @@ struct gaicb {
};
.EE
.in
-.PP
+.P
The elements of this structure correspond to the arguments of
.BR getaddrinfo (3).
Thus,
@@ -106,7 +106,7 @@ The
.I addrinfo
structure referenced by the last two elements is described in
.BR getaddrinfo (3).
-.PP
+.P
When
.I mode
is specified as
@@ -118,7 +118,7 @@ structure pointed to by the
.I sevp
argument.
For the definition and general details of this structure, see
-.BR sigevent (7).
+.BR sigevent (3type).
The
.I sevp\->sigev_notify
field can have the following values:
@@ -131,7 +131,7 @@ When a look-up completes, generate the signal
.I sigev_signo
for the process.
See
-.BR sigevent (7)
+.BR sigevent (3type)
for general details.
The
.I si_code
@@ -147,9 +147,9 @@ When a look-up completes, invoke
.I sigev_notify_function
as if it were the start function of a new thread.
See
-.BR sigevent (7)
+.BR sigevent (3type)
for details.
-.PP
+.P
For
.B SIGEV_SIGNAL
and
@@ -158,7 +158,7 @@ it may be useful to point
.I sevp\->sigev_value.sival_ptr
to
.IR list .
-.PP
+.P
The
.BR gai_suspend ()
function suspends execution of the calling thread,
@@ -188,12 +188,12 @@ If
.I timeout
is NULL, then the call blocks indefinitely
(until one of the events above occurs).
-.PP
+.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.
-.PP
+.P
The
.BR gai_error ()
function returns the status of the request
@@ -203,7 +203,7 @@ either
if the request was not completed yet,
0 if it was handled successfully,
or an error code if the request could not be resolved.
-.PP
+.P
The
.BR gai_cancel ()
function cancels the request
@@ -237,7 +237,7 @@ Out of memory.
.B EAI_SYSTEM
.I mode
is invalid.
-.PP
+.P
The
.BR gai_suspend ()
function returns 0 if at least one of the listed requests has been completed.
@@ -253,7 +253,7 @@ There were no actual requests given to the function.
A signal has interrupted the function.
Note that this interruption might have been
caused by signal notification of some completed look-up request.
-.PP
+.P
The
.BR gai_error ()
function can return
@@ -265,7 +265,7 @@ for an unfinished look-up request,
or the error code
.B EAI_CANCELED
if the request has been canceled explicitly before it could be finished.
-.PP
+.P
The
.BR gai_cancel ()
function can return one of these values:
@@ -278,7 +278,7 @@ The request has not been canceled.
.TP
.B EAI_ALLDONE
The request has already completed.
-.PP
+.P
The
.BR gai_strerror (3)
function translates these error codes to a human readable string,
@@ -300,12 +300,11 @@ T{
.BR gai_cancel ()
T} Thread safety MT-Safe
.TE
-.sp 1
.SH STANDARDS
GNU.
.SH HISTORY
glibc 2.2.3.
-.PP
+.P
The interface of
.BR getaddrinfo_a ()
was modeled after the
@@ -320,7 +319,7 @@ 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:
-.PP
+.P
.in +4n
.EX
$ \fB./a.out mirrors.kernel.org enoent.linuxfoundation.org gnu.org\fP
@@ -329,17 +328,20 @@ enoent.linuxfoundation.org: Name or service not known
gnu.org: 209.51.188.116
.EE
.in
-.PP
+.P
Here is the program source code
-.PP
+.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[])
{
@@ -354,11 +356,10 @@ main(int argc, char *argv[])
}
\&
for (size_t i = 0; i < argc \- 1; i++) {
- reqs[i] = malloc(sizeof(*reqs[0]));
- if (reqs[i] == NULL) {
- perror("malloc");
- exit(EXIT_FAILURE);
- }
+ 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];
}
@@ -399,9 +400,9 @@ This example shows a simple interactive
.BR getaddrinfo_a ()
front-end.
The notification facility is not demonstrated.
-.PP
+.P
An example session might look like this:
-.PP
+.P
.in +4n
.EX
$ \fB./a.out\fP
@@ -420,20 +421,42 @@ $ \fB./a.out\fP
[02] gnu.org: 209.51.188.116
.EE
.in
-.PP
+.P
The program source is as follows:
-.PP
+.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)
{
@@ -459,9 +482,14 @@ add_requests(void)
\&
while ((host = strtok(NULL, " "))) {
nreqs++;
- reqs = realloc(reqs, sizeof(reqs[0]) * 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] = calloc(1, sizeof(*reqs[0]));
reqs[nreqs \- 1]\->ar_name = strdup(host);
}
\&
@@ -483,7 +511,12 @@ wait_requests(void)
char *id;
int ret;
size_t n;
- struct gaicb const **wait_reqs = calloc(nreqs, sizeof(*wait_reqs));
+ 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) {
@@ -609,4 +642,4 @@ main(void)
.BR lio_listio (3),
.BR hostname (7),
.BR ip (7),
-.BR sigevent (7)
+.BR sigevent (3type)