788 lines
27 KiB
HTML
788 lines
27 KiB
HTML
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<HTML><HEAD><TITLE>Man page of GETADDRINFO_A</TITLE>
|
|
</HEAD><BODY>
|
|
<H1>GETADDRINFO_A</H1>
|
|
Section: Linux Programmer's Manual (3)<BR>Updated: 2019-03-06<BR><A HREF="#index">Index</A>
|
|
<A HREF="/cgi-bin/man/man2html">Return to Main Contents</A><HR>
|
|
|
|
<A NAME="lbAB"> </A>
|
|
<H2>NAME</H2>
|
|
|
|
getaddrinfo_a, gai_suspend, gai_error, gai_cancel - asynchronous
|
|
network address and service translation
|
|
<A NAME="lbAC"> </A>
|
|
<H2>SYNOPSIS</H2>
|
|
|
|
<PRE>
|
|
<B>#define _GNU_SOURCE</B> /* See <A HREF="/cgi-bin/man/man2html?7+feature_test_macros">feature_test_macros</A>(7) */
|
|
<B>#include <<A HREF="file:///usr/include/netdb.h">netdb.h</A>></B>
|
|
|
|
<B>int getaddrinfo_a(int </B><I>mode</I><B>, struct gaicb *</B><I>list[]</I><B>,</B>
|
|
<B> int </B><I>nitems</I><B>, struct sigevent *</B><I>sevp</I><B>);</B>
|
|
|
|
<B>int gai_suspend(const struct gaicb * const </B><I>list[]</I><B>, int </B><I>nitems</I><B>,</B>
|
|
<B> const struct timespec *</B><I>timeout</I><B>);</B>
|
|
|
|
<B>int gai_error(struct gaicb *</B><I>req</I><B>);</B>
|
|
|
|
<B>int gai_cancel(struct gaicb *</B><I>req</I><B>);</B>
|
|
|
|
Link with <I>-lanl</I>.
|
|
</PRE>
|
|
|
|
<A NAME="lbAD"> </A>
|
|
<H2>DESCRIPTION</H2>
|
|
|
|
The
|
|
<B>getaddrinfo_a</B>()
|
|
|
|
function performs the same task as
|
|
<B><A HREF="/cgi-bin/man/man2html?3+getaddrinfo">getaddrinfo</A></B>(3),
|
|
|
|
but allows multiple name look-ups to be performed asynchronously,
|
|
with optional notification on completion of look-up operations.
|
|
<P>
|
|
|
|
The
|
|
<I>mode</I>
|
|
|
|
argument has one of the following values:
|
|
<DL COMPACT>
|
|
<DT id="1"><B>GAI_WAIT</B>
|
|
|
|
<DD>
|
|
Perform the look-ups synchronously.
|
|
The call blocks until the look-ups have completed.
|
|
<DT id="2"><B>GAI_NOWAIT</B>
|
|
|
|
<DD>
|
|
Perform the look-ups asynchronously.
|
|
The call returns immediately,
|
|
and the requests are resolved in the background.
|
|
See the discussion of the
|
|
<I>sevp</I>
|
|
|
|
argument below.
|
|
</DL>
|
|
<P>
|
|
|
|
The array
|
|
<I>list</I>
|
|
|
|
specifies the look-up requests to process.
|
|
The
|
|
<I>nitems</I>
|
|
|
|
argument specifies the number of elements in
|
|
<I>list</I>.
|
|
|
|
The requested look-up operations are started in parallel.
|
|
NULL elements in
|
|
<I>list</I>
|
|
|
|
are ignored.
|
|
Each request is described by a
|
|
<I>gaicb</I>
|
|
|
|
structure, defined as follows:
|
|
<P>
|
|
|
|
|
|
|
|
struct gaicb {
|
|
<BR> const char *ar_name;
|
|
<BR> const char *ar_service;
|
|
<BR> const struct addrinfo *ar_request;
|
|
<BR> struct addrinfo *ar_result;
|
|
};
|
|
|
|
|
|
<P>
|
|
|
|
The elements of this structure correspond to the arguments of
|
|
<B><A HREF="/cgi-bin/man/man2html?3+getaddrinfo">getaddrinfo</A></B>(3).
|
|
|
|
Thus,
|
|
<I>ar_name</I>
|
|
|
|
corresponds to the
|
|
<I>node</I>
|
|
|
|
argument and
|
|
<I>ar_service</I>
|
|
|
|
to the
|
|
<I>service</I>
|
|
|
|
argument, identifying an Internet host and a service.
|
|
The
|
|
<I>ar_request</I>
|
|
|
|
element corresponds to the
|
|
<I>hints</I>
|
|
|
|
argument, specifying the criteria for selecting
|
|
the returned socket address structures.
|
|
Finally,
|
|
<I>ar_result</I>
|
|
|
|
corresponds to the
|
|
<I>res</I>
|
|
|
|
argument; you do not need to initialize this element,
|
|
it will be automatically set when the request
|
|
is resolved.
|
|
The
|
|
<I>addrinfo</I>
|
|
|
|
structure referenced by the last two elements is described in
|
|
<B><A HREF="/cgi-bin/man/man2html?3+getaddrinfo">getaddrinfo</A></B>(3).
|
|
|
|
<P>
|
|
|
|
When
|
|
<I>mode</I>
|
|
|
|
is specified as
|
|
<B>GAI_NOWAIT</B>,
|
|
|
|
notifications about resolved requests
|
|
can be obtained by employing the
|
|
<I>sigevent</I>
|
|
|
|
structure pointed to by the
|
|
<I>sevp</I>
|
|
|
|
argument.
|
|
For the definition and general details of this structure, see
|
|
<B><A HREF="/cgi-bin/man/man2html?7+sigevent">sigevent</A></B>(7).
|
|
|
|
The
|
|
<I>sevp->sigev_notify</I>
|
|
|
|
field can have the following values:
|
|
<DL COMPACT>
|
|
<DT id="3"><B>SIGEV_NONE</B>
|
|
|
|
<DD>
|
|
Don't provide any notification.
|
|
<DT id="4"><B>SIGEV_SIGNAL</B>
|
|
|
|
<DD>
|
|
When a look-up completes, generate the signal
|
|
<I>sigev_signo</I>
|
|
|
|
for the process.
|
|
See
|
|
<B><A HREF="/cgi-bin/man/man2html?7+sigevent">sigevent</A></B>(7)
|
|
|
|
for general details.
|
|
The
|
|
<I>si_code</I>
|
|
|
|
field of the
|
|
<I>siginfo_t</I>
|
|
|
|
structure will be set to
|
|
<B>SI_ASYNCNL</B>.
|
|
|
|
|
|
|
|
<DT id="5"><B>SIGEV_THREAD</B>
|
|
|
|
<DD>
|
|
When a look-up completes, invoke
|
|
<I>sigev_notify_function</I>
|
|
|
|
as if it were the start function of a new thread.
|
|
See
|
|
<B><A HREF="/cgi-bin/man/man2html?7+sigevent">sigevent</A></B>(7)
|
|
|
|
for details.
|
|
</DL>
|
|
<P>
|
|
|
|
For
|
|
<B>SIGEV_SIGNAL</B>
|
|
|
|
and
|
|
<B>SIGEV_THREAD</B>,
|
|
|
|
it may be useful to point
|
|
<I>sevp->sigev_value.sival_ptr</I>
|
|
|
|
to
|
|
<I>list</I>.
|
|
|
|
<P>
|
|
|
|
The
|
|
<B>gai_suspend</B>()
|
|
|
|
function suspends execution of the calling thread,
|
|
waiting for the completion of one or more requests in the array
|
|
<I>list</I>.
|
|
|
|
The
|
|
<I>nitems</I>
|
|
|
|
argument specifies the size of the array
|
|
<I>list</I>.
|
|
|
|
The call blocks until one of the following occurs:
|
|
<DL COMPACT>
|
|
<DT id="6">*<DD>
|
|
One or more of the operations in
|
|
<I>list</I>
|
|
|
|
completes.
|
|
<DT id="7">*<DD>
|
|
The call is interrupted by a signal that is caught.
|
|
<DT id="8">*<DD>
|
|
The time interval specified in
|
|
<I>timeout</I>
|
|
|
|
elapses.
|
|
This argument specifies a timeout in seconds plus nanoseconds (see
|
|
<B><A HREF="/cgi-bin/man/man2html?2+nanosleep">nanosleep</A></B>(2)
|
|
|
|
for details of the
|
|
<I>timespec</I>
|
|
|
|
structure).
|
|
If
|
|
<I>timeout</I>
|
|
|
|
is NULL, then the call blocks indefinitely
|
|
(until one of the events above occurs).
|
|
</DL>
|
|
<P>
|
|
|
|
No explicit indication of which request was completed is given;
|
|
you must determine which request(s) have completed by iterating with
|
|
<B>gai_error</B>()
|
|
|
|
over the list of requests.
|
|
<P>
|
|
|
|
The
|
|
<B>gai_error</B>()
|
|
|
|
function returns the status of the request
|
|
<I>req</I>:
|
|
|
|
either
|
|
<B>EAI_INPROGRESS</B>
|
|
|
|
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
|
|
<B>gai_cancel</B>()
|
|
|
|
function cancels the request
|
|
<I>req</I>.
|
|
|
|
If the request has been canceled successfully,
|
|
the error status of the request will be set to
|
|
<B>EAI_CANCELED</B>
|
|
|
|
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
|
|
<B>gai_cancel</B>()
|
|
|
|
has never been called.
|
|
If
|
|
<I>req</I>
|
|
|
|
is NULL, an attempt is made to cancel all outstanding requests
|
|
that the process has made.
|
|
<A NAME="lbAE"> </A>
|
|
<H2>RETURN VALUE</H2>
|
|
|
|
The
|
|
<B>getaddrinfo_a</B>()
|
|
|
|
function returns 0 if all of the requests have been enqueued successfully,
|
|
or one of the following nonzero error codes:
|
|
<DL COMPACT>
|
|
<DT id="9"><B>EAI_AGAIN</B>
|
|
|
|
<DD>
|
|
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.
|
|
<DT id="10"><B>EAI_MEMORY</B>
|
|
|
|
<DD>
|
|
Out of memory.
|
|
<DT id="11"><B>EAI_SYSTEM</B>
|
|
|
|
<DD>
|
|
<I>mode</I>
|
|
|
|
is invalid.
|
|
</DL>
|
|
<P>
|
|
|
|
The
|
|
<B>gai_suspend</B>()
|
|
|
|
function returns 0 if at least one of the listed requests has been completed.
|
|
Otherwise, it returns one of the following nonzero error codes:
|
|
<DL COMPACT>
|
|
<DT id="12"><B>EAI_AGAIN</B>
|
|
|
|
<DD>
|
|
The given timeout expired before any of the requests could be completed.
|
|
<DT id="13"><B>EAI_ALLDONE</B>
|
|
|
|
<DD>
|
|
There were no actual requests given to the function.
|
|
<DT id="14"><B>EAI_INTR</B>
|
|
|
|
<DD>
|
|
A signal has interrupted the function.
|
|
Note that this interruption might have been
|
|
caused by signal notification of some completed look-up request.
|
|
</DL>
|
|
<P>
|
|
|
|
The
|
|
<B>gai_error</B>()
|
|
|
|
function can return
|
|
<B>EAI_INPROGRESS</B>
|
|
|
|
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
|
|
<B><A HREF="/cgi-bin/man/man2html?3+getaddrinfo">getaddrinfo</A></B>(3),
|
|
|
|
or the error code
|
|
<B>EAI_CANCELED</B>
|
|
|
|
if the request has been canceled explicitly before it could be finished.
|
|
<P>
|
|
|
|
The
|
|
<B>gai_cancel</B>()
|
|
|
|
function can return one of these values:
|
|
<DL COMPACT>
|
|
<DT id="15"><B>EAI_CANCELED</B>
|
|
|
|
<DD>
|
|
The request has been canceled successfully.
|
|
<DT id="16"><B>EAI_NOTCANCELED</B>
|
|
|
|
<DD>
|
|
The request has not been canceled.
|
|
<DT id="17"><B>EAI_ALLDONE</B>
|
|
|
|
<DD>
|
|
The request has already completed.
|
|
</DL>
|
|
<P>
|
|
|
|
The
|
|
<B><A HREF="/cgi-bin/man/man2html?3+gai_strerror">gai_strerror</A></B>(3)
|
|
|
|
function translates these error codes to a human readable string,
|
|
suitable for error reporting.
|
|
<A NAME="lbAF"> </A>
|
|
<H2>ATTRIBUTES</H2>
|
|
|
|
For an explanation of the terms used in this section, see
|
|
<B><A HREF="/cgi-bin/man/man2html?7+attributes">attributes</A></B>(7).
|
|
|
|
<TABLE BORDER>
|
|
<TR VALIGN=top><TD><B>Interface</B></TD><TD><B>Attribute</B></TD><TD><B>Value</B><BR></TD></TR>
|
|
<TR VALIGN=top><TD>
|
|
<B>getaddrinfo_a</B>(),
|
|
|
|
<B>gai_suspend</B>(),
|
|
|
|
<B>gai_error</B>(),
|
|
|
|
<B>gai_cancel</B>()
|
|
|
|
</TD><TD>Thread safety</TD><TD>MT-Safe<BR></TD></TR>
|
|
</TABLE>
|
|
|
|
<P>
|
|
<A NAME="lbAG"> </A>
|
|
<H2>CONFORMING TO</H2>
|
|
|
|
These functions are GNU extensions;
|
|
they first appeared in glibc in version 2.2.3.
|
|
<A NAME="lbAH"> </A>
|
|
<H2>NOTES</H2>
|
|
|
|
The interface of
|
|
<B>getaddrinfo_a</B>()
|
|
|
|
was modeled after the
|
|
<B><A HREF="/cgi-bin/man/man2html?3+lio_listio">lio_listio</A></B>(3)
|
|
|
|
interface.
|
|
<A NAME="lbAI"> </A>
|
|
<H2>EXAMPLE</H2>
|
|
|
|
Two examples are provided: a simple example that resolves
|
|
several requests in parallel synchronously, and a complex example
|
|
showing some of the asynchronous capabilities.
|
|
<A NAME="lbAJ"> </A>
|
|
<H3>Synchronous example</H3>
|
|
|
|
The program below simply resolves several hostnames in parallel,
|
|
giving a speed-up compared to resolving the hostnames sequentially using
|
|
<B><A HREF="/cgi-bin/man/man2html?3+getaddrinfo">getaddrinfo</A></B>(3).
|
|
|
|
The program might be used like this:
|
|
<P>
|
|
|
|
|
|
|
|
$ <B>./a.out <A HREF="ftp://ftp.us.kernel.org">ftp.us.kernel.org</A> enoent.linuxfoundation.org gnu.cz</B>
|
|
<A HREF="ftp://ftp.us.kernel.org">ftp.us.kernel.org</A>: 128.30.2.36
|
|
enoent.linuxfoundation.org: Name or service not known
|
|
gnu.cz: 87.236.197.13
|
|
|
|
|
|
<P>
|
|
|
|
Here is the program source code
|
|
<P>
|
|
|
|
|
|
#define _GNU_SOURCE
|
|
#include <<A HREF="file:///usr/include/netdb.h">netdb.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdio.h">stdio.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdlib.h">stdlib.h</A>>
|
|
#include <<A HREF="file:///usr/include/string.h">string.h</A>>
|
|
<P>
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
<BR> int i, ret;
|
|
<BR> struct gaicb *reqs[argc - 1];
|
|
<BR> char host[NI_MAXHOST];
|
|
<BR> struct addrinfo *res;
|
|
<P>
|
|
<BR> if (argc < 2) {
|
|
<BR> fprintf(stderr, "Usage: %s HOST...\n", argv[0]);
|
|
<BR> exit(EXIT_FAILURE);
|
|
<BR> }
|
|
<P>
|
|
<BR> for (i = 0; i < argc - 1; i++) {
|
|
<BR> reqs[i] = malloc(sizeof(*reqs[0]));
|
|
<BR> if (reqs[i] == NULL) {
|
|
<BR> perror("malloc");
|
|
<BR> exit(EXIT_FAILURE);
|
|
<BR> }
|
|
<BR> memset(reqs[i], 0, sizeof(*reqs[0]));
|
|
<BR> reqs[i]->ar_name = argv[i + 1];
|
|
<BR> }
|
|
<P>
|
|
<BR> ret = getaddrinfo_a(GAI_WAIT, reqs, argc - 1, NULL);
|
|
<BR> if (ret != 0) {
|
|
<BR> fprintf(stderr, "getaddrinfo_a() failed: %s\n",
|
|
<BR> gai_strerror(ret));
|
|
<BR> exit(EXIT_FAILURE);
|
|
<BR> }
|
|
<P>
|
|
<BR> for (i = 0; i < argc - 1; i++) {
|
|
<BR> printf("%s: ", reqs[i]->ar_name);
|
|
<BR> ret = gai_error(reqs[i]);
|
|
<BR> if (ret == 0) {
|
|
<BR> res = reqs[i]->ar_result;
|
|
<P>
|
|
<BR> ret = getnameinfo(res->ai_addr, res->ai_addrlen,
|
|
<BR> host, sizeof(host),
|
|
<BR> NULL, 0, NI_NUMERICHOST);
|
|
<BR> if (ret != 0) {
|
|
<BR> fprintf(stderr, "getnameinfo() failed: %s\n",
|
|
<BR> gai_strerror(ret));
|
|
<BR> exit(EXIT_FAILURE);
|
|
<BR> }
|
|
<BR> puts(host);
|
|
<P>
|
|
<BR> } else {
|
|
<BR> puts(gai_strerror(ret));
|
|
<BR> }
|
|
<BR> }
|
|
<BR> exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
<A NAME="lbAK"> </A>
|
|
<H3>Asynchronous example</H3>
|
|
|
|
This example shows a simple interactive
|
|
<B>getaddrinfo_a</B>()
|
|
|
|
front-end.
|
|
The notification facility is not demonstrated.
|
|
<P>
|
|
|
|
An example session might look like this:
|
|
<P>
|
|
|
|
|
|
|
|
$ <B>./a.out</B>
|
|
> a <A HREF="ftp://ftp.us.kernel.org">ftp.us.kernel.org</A> enoent.linuxfoundation.org gnu.cz
|
|
> c 2
|
|
[2] gnu.cz: Request not canceled
|
|
> w 0 1
|
|
[00] <A HREF="ftp://ftp.us.kernel.org">ftp.us.kernel.org</A>: Finished
|
|
> l
|
|
[00] <A HREF="ftp://ftp.us.kernel.org">ftp.us.kernel.org</A>: 216.165.129.139
|
|
[01] enoent.linuxfoundation.org: Processing request in progress
|
|
[02] gnu.cz: 87.236.197.13
|
|
> l
|
|
[00] <A HREF="ftp://ftp.us.kernel.org">ftp.us.kernel.org</A>: 216.165.129.139
|
|
[01] enoent.linuxfoundation.org: Name or service not known
|
|
[02] gnu.cz: 87.236.197.13
|
|
|
|
|
|
<P>
|
|
|
|
The program source is as follows:
|
|
<P>
|
|
|
|
|
|
#define _GNU_SOURCE
|
|
#include <<A HREF="file:///usr/include/netdb.h">netdb.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdio.h">stdio.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdlib.h">stdlib.h</A>>
|
|
#include <<A HREF="file:///usr/include/string.h">string.h</A>>
|
|
<P>
|
|
static struct gaicb **reqs = NULL;
|
|
static int nreqs = 0;
|
|
<P>
|
|
static char *
|
|
getcmd(void)
|
|
{
|
|
<BR> static char buf[256];
|
|
<P>
|
|
<BR> fputs("> ", stdout); fflush(stdout);
|
|
<BR> if (fgets(buf, sizeof(buf), stdin) == NULL)
|
|
<BR> return NULL;
|
|
<P>
|
|
<BR> if (buf[strlen(buf) - 1] == '\n')
|
|
<BR> buf[strlen(buf) - 1] = 0;
|
|
<P>
|
|
<BR> return buf;
|
|
}
|
|
<P>
|
|
/* Add requests for specified hostnames */
|
|
static void
|
|
add_requests(void)
|
|
{
|
|
<BR> int nreqs_base = nreqs;
|
|
<BR> char *host;
|
|
<BR> int ret;
|
|
<P>
|
|
<BR> while ((host = strtok(NULL, " "))) {
|
|
<BR> nreqs++;
|
|
<BR> reqs = realloc(reqs, nreqs * sizeof(reqs[0]));
|
|
<P>
|
|
<BR> reqs[nreqs - 1] = calloc(1, sizeof(*reqs[0]));
|
|
<BR> reqs[nreqs - 1]->ar_name = strdup(host);
|
|
<BR> }
|
|
<P>
|
|
<BR> /* Queue nreqs_base..nreqs requests. */
|
|
<P>
|
|
<BR> ret = getaddrinfo_a(GAI_NOWAIT, &reqs[nreqs_base],
|
|
<BR> nreqs - nreqs_base, NULL);
|
|
<BR> if (ret) {
|
|
<BR> fprintf(stderr, "getaddrinfo_a() failed: %s\n",
|
|
<BR> gai_strerror(ret));
|
|
<BR> exit(EXIT_FAILURE);
|
|
<BR> }
|
|
}
|
|
<P>
|
|
/* Wait until at least one of specified requests completes */
|
|
static void
|
|
wait_requests(void)
|
|
{
|
|
<BR> char *id;
|
|
<BR> int i, ret, n;
|
|
<BR> struct gaicb const **wait_reqs = calloc(nreqs, sizeof(*wait_reqs));
|
|
<BR> /* NULL elements are ignored by gai_suspend(). */
|
|
<P>
|
|
<BR> while ((id = strtok(NULL, " ")) != NULL) {
|
|
<BR> n = atoi(id);
|
|
<P>
|
|
<BR> if (n >= nreqs) {
|
|
<BR> printf("Bad request number: %s\n", id);
|
|
<BR> return;
|
|
<BR> }
|
|
<P>
|
|
<BR> wait_reqs[n] = reqs[n];
|
|
<BR> }
|
|
<P>
|
|
<BR> ret = gai_suspend(wait_reqs, nreqs, NULL);
|
|
<BR> if (ret) {
|
|
<BR> printf("gai_suspend(): %s\n", gai_strerror(ret));
|
|
<BR> return;
|
|
<BR> }
|
|
<P>
|
|
<BR> for (i = 0; i < nreqs; i++) {
|
|
<BR> if (wait_reqs[i] == NULL)
|
|
<BR> continue;
|
|
<P>
|
|
<BR> ret = gai_error(reqs[i]);
|
|
<BR> if (ret == EAI_INPROGRESS)
|
|
<BR> continue;
|
|
<P>
|
|
<BR> printf("[%02d] %s: %s\n", i, reqs[i]->ar_name,
|
|
<BR> ret == 0 ? "Finished" : gai_strerror(ret));
|
|
<BR> }
|
|
}
|
|
<P>
|
|
/* Cancel specified requests */
|
|
static void
|
|
cancel_requests(void)
|
|
{
|
|
<BR> char *id;
|
|
<BR> int ret, n;
|
|
<P>
|
|
<BR> while ((id = strtok(NULL, " ")) != NULL) {
|
|
<BR> n = atoi(id);
|
|
<P>
|
|
<BR> if (n >= nreqs) {
|
|
<BR> printf("Bad request number: %s\n", id);
|
|
<BR> return;
|
|
<BR> }
|
|
<P>
|
|
<BR> ret = gai_cancel(reqs[n]);
|
|
<BR> printf("[%s] %s: %s\n", id, reqs[atoi(id)]->ar_name,
|
|
<BR> gai_strerror(ret));
|
|
<BR> }
|
|
}
|
|
<P>
|
|
/* List all requests */
|
|
static void
|
|
list_requests(void)
|
|
{
|
|
<BR> int i, ret;
|
|
<BR> char host[NI_MAXHOST];
|
|
<BR> struct addrinfo *res;
|
|
<P>
|
|
<BR> for (i = 0; i < nreqs; i++) {
|
|
<BR> printf("[%02d] %s: ", i, reqs[i]->ar_name);
|
|
<BR> ret = gai_error(reqs[i]);
|
|
<P>
|
|
<BR> if (!ret) {
|
|
<BR> res = reqs[i]->ar_result;
|
|
<P>
|
|
<BR> ret = getnameinfo(res->ai_addr, res->ai_addrlen,
|
|
<BR> host, sizeof(host),
|
|
<BR> NULL, 0, NI_NUMERICHOST);
|
|
<BR> if (ret) {
|
|
<BR> fprintf(stderr, "getnameinfo() failed: %s\n",
|
|
<BR> gai_strerror(ret));
|
|
<BR> exit(EXIT_FAILURE);
|
|
<BR> }
|
|
<BR> puts(host);
|
|
<BR> } else {
|
|
<BR> puts(gai_strerror(ret));
|
|
<BR> }
|
|
<BR> }
|
|
}
|
|
<P>
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
<BR> char *cmdline;
|
|
<BR> char *cmd;
|
|
<P>
|
|
<BR> while ((cmdline = getcmd()) != NULL) {
|
|
<BR> cmd = strtok(cmdline, " ");
|
|
<P>
|
|
<BR> if (cmd == NULL) {
|
|
<BR> list_requests();
|
|
<BR> } else {
|
|
<BR> switch (cmd[0]) {
|
|
<BR> case 'a':
|
|
<BR> add_requests();
|
|
<BR> break;
|
|
<BR> case 'w':
|
|
<BR> wait_requests();
|
|
<BR> break;
|
|
<BR> case 'c':
|
|
<BR> cancel_requests();
|
|
<BR> break;
|
|
<BR> case 'l':
|
|
<BR> list_requests();
|
|
<BR> break;
|
|
<BR> default:
|
|
<BR> fprintf(stderr, "Bad command: %c\n", cmd[0]);
|
|
<BR> break;
|
|
<BR> }
|
|
<BR> }
|
|
<BR> }
|
|
<BR> exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
<A NAME="lbAL"> </A>
|
|
<H2>SEE ALSO</H2>
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?3+getaddrinfo">getaddrinfo</A></B>(3),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?3+inet">inet</A></B>(3),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?3+lio_listio">lio_listio</A></B>(3),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?7+hostname">hostname</A></B>(7),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?7+ip">ip</A></B>(7),
|
|
|
|
<B><A HREF="/cgi-bin/man/man2html?7+sigevent">sigevent</A></B>(7)
|
|
|
|
<A NAME="lbAM"> </A>
|
|
<H2>COLOPHON</H2>
|
|
|
|
This page is part of release 5.05 of the Linux
|
|
<I>man-pages</I>
|
|
|
|
project.
|
|
A description of the project,
|
|
information about reporting bugs,
|
|
and the latest version of this page,
|
|
can be found at
|
|
<A HREF="https://www.kernel.org/doc/man-pages/.">https://www.kernel.org/doc/man-pages/.</A>
|
|
<P>
|
|
|
|
<HR>
|
|
<A NAME="index"> </A><H2>Index</H2>
|
|
<DL>
|
|
<DT id="18"><A HREF="#lbAB">NAME</A><DD>
|
|
<DT id="19"><A HREF="#lbAC">SYNOPSIS</A><DD>
|
|
<DT id="20"><A HREF="#lbAD">DESCRIPTION</A><DD>
|
|
<DT id="21"><A HREF="#lbAE">RETURN VALUE</A><DD>
|
|
<DT id="22"><A HREF="#lbAF">ATTRIBUTES</A><DD>
|
|
<DT id="23"><A HREF="#lbAG">CONFORMING TO</A><DD>
|
|
<DT id="24"><A HREF="#lbAH">NOTES</A><DD>
|
|
<DT id="25"><A HREF="#lbAI">EXAMPLE</A><DD>
|
|
<DL>
|
|
<DT id="26"><A HREF="#lbAJ">Synchronous example</A><DD>
|
|
<DT id="27"><A HREF="#lbAK">Asynchronous example</A><DD>
|
|
</DL>
|
|
<DT id="28"><A HREF="#lbAL">SEE ALSO</A><DD>
|
|
<DT id="29"><A HREF="#lbAM">COLOPHON</A><DD>
|
|
</DL>
|
|
<HR>
|
|
This document was created by
|
|
<A HREF="/cgi-bin/man/man2html">man2html</A>,
|
|
using the manual pages.<BR>
|
|
Time: 00:05:44 GMT, March 31, 2021
|
|
</BODY>
|
|
</HTML>
|