]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man3/getaddrinfo_a.3
fuse.4: fuse_entry_out: rework discussion of uniqueness of nodeid + generation
[thirdparty/man-pages.git] / man3 / getaddrinfo_a.3
CommitLineData
e11d63b9 1.\" Copyright (c) 2009 Petr Baudis <pasky@suse.cz>
bfb9c7c0 2.\" and clean-ups and additions (C) Copyright 2010 Michael Kerrisk
67c7e1d5 3.\" <mtk.manpages@gmail.com>
e11d63b9 4.\"
93015253 5.\" %%%LICENSE_START(VERBATIM)
e11d63b9
PB
6.\" Permission is granted to make and distribute verbatim copies of this
7.\" manual provided the copyright notice and this permission notice are
8.\" preserved on all copies.
9.\"
10.\" Permission is granted to copy and distribute modified versions of this
11.\" manual under the conditions for verbatim copying, provided that the
12.\" entire resulting derived work is distributed under the terms of a
13.\" permission notice identical to this one.
14.\"
15.\" Since the Linux kernel and libraries are constantly changing, this
16.\" manual page may be incorrect or out-of-date. The author(s) assume no
17.\" responsibility for errors or omissions, or for damages resulting from
18.\" the use of the information contained herein. The author(s) may not
19.\" have taken the same level of care in the production of this manual,
20.\" which is licensed free of charge, as they might when working
21.\" professionally.
22.\"
23.\" Formatted or processed versions of this manual, if unaccompanied by
24.\" the source, must acknowledge the copyright and authors of this work.
4b72fb64 25.\" %%%LICENSE_END
e11d63b9
PB
26.\"
27.\" References: http://people.redhat.com/drepper/asynchnl.pdf,
28.\" http://www.imperialviolet.org/2005/06/01/asynchronous-dns-lookups-with-glibc.html
29.\"
5722c835 30.TH GETADDRINFO_A 3 2015-07-23 "GNU" "Linux Programmer's Manual"
e11d63b9
PB
31.SH NAME
32getaddrinfo_a, gai_suspend, gai_error, gai_cancel \- asynchronous
33network address and service translation
34.SH SYNOPSIS
35.nf
b80f966b 36.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
e11d63b9
PB
37.B #include <netdb.h>
38.sp
39.BI "int getaddrinfo_a(int " "mode" ", struct gaicb *" "list[]" ,
40.BI " int " "nitems" ", struct sigevent *" "sevp" );
41.sp
8c5ffcfa
RV
42.BI "int gai_suspend(const struct gaicb * const " "list[]" ", int " "nitems" ,
43.BI " const struct timespec *" "timeout" );
e11d63b9
PB
44.sp
45.BI "int gai_error(struct gaicb *" "req" );
46.sp
47.BI "int gai_cancel(struct gaicb *" "req" );
48.sp
49Link with \fI\-lanl\fP.
50.fi
51.SH DESCRIPTION
52The
53.BR getaddrinfo_a ()
54function performs the same task as
55.BR getaddrinfo (3),
56but allows multiple name look-ups to be performed asynchronously,
57with optional notification on completion of look-up operations.
58
59The
60.I mode
61argument has one of the following values:
62.TP
63.B GAI_WAIT
af15dfab
SP
64Perform the look-ups synchronously.
65The call blocks until the look-ups have completed.
e11d63b9
PB
66.TP
67.B GAI_NOWAIT
68Perform the look-ups asynchronously.
69The call returns immediately,
70and the requests are resolved in the background.
71See the discussion of the
72.I sevp
73argument below.
74.PP
75The array
76.I list
77specifies the look-up requests to process.
78The
79.I nitems
80argument specifies the number of elements in
81.IR list .
82The requested look-up operations are started in parallel.
83NULL elements in
84.I list
85are ignored.
86Each request is described by a
87.I gaicb
88structure, defined as follows:
89.sp
90.in +4n
91.nf
92struct gaicb {
93 const char *ar_name;
94 const char *ar_service;
95 const struct addrinfo *ar_request;
96 struct addrinfo *ar_result;
97};
98.fi
99.in
100
101The elements of this structure correspond to the arguments of
102.BR getaddrinfo (3).
103Thus,
104.I ar_name
105corresponds to the
106.I node
107argument and
108.I ar_service
109to the
110.I service
111argument, identifying an Internet host and a service.
112The
113.I ar_request
114element corresponds to the
115.I hints
116argument, specifying the criteria for selecting
117the returned socket address structures.
118Finally,
119.I ar_result
120corresponds to the
121.I res
122argument; you do not need to initialize this element,
123it will be automatically set when the request
124is resolved.
125The
126.I addrinfo
127structure referenced by the last two elements is described in
128.BR getaddrinfo (3).
129
130When
131.I mode
132is specified as
5238ea2c 133.BR GAI_NOWAIT ,
e11d63b9
PB
134notifications about resolved requests
135can be obtained by employing the
136.I sigevent
137structure pointed to by the
138.I sevp
139argument.
140For the definition and general details of this structure, see
141.BR sigevent (7).
142The
143.I sevp\->sigev_notify
144field can have the following values:
145.TP
146.BR SIGEV_NONE
147Don't provide any notification.
148.TP
149.BR SIGEV_SIGNAL
150When a look-up completes, generate the signal
151.I sigev_signo
152for the process.
153See
154.BR sigevent (7)
155for general details.
156The
157.I si_code
158field of the
159.I siginfo_t
160structure will be set to
161.BR SI_ASYNCNL .
162.\" si_pid and si_uid are also set, to the values of the calling process,
163.\" which doesn't provide useful information, so we'll skip mentioning it.
164.TP
165.BR SIGEV_THREAD
166When a look-up completes, invoke
167.I sigev_notify_function
168as if it were the start function of a new thread.
169See
170.BR sigevent (7)
171for details.
172.PP
59e9285d 173For
e11d63b9
PB
174.BR SIGEV_SIGNAL
175and
176.BR SIGEV_THREAD ,
177it may be useful to point
178.IR sevp\->sigev_value.sival_ptr
179to
180.IR list .
181
182The
183.BR gai_suspend ()
184function suspends execution of the calling thread,
185waiting for the completion of one or more requests in the array
1f2a5c64 186.IR list .
e11d63b9
PB
187The
188.I nitems
189argument specifies the size of the array
190.IR list .
191The call blocks until one of the following occurs:
192.IP * 3
193One or more of the operations in
194.I list
195completes.
196.IP *
197The call is interrupted by a signal that is caught.
198.IP *
199The time interval specified in
200.I timeout
201elapses.
202This argument specifies a timeout in seconds plus nanoseconds (see
203.BR nanosleep (2)
204for details of the
205.I timespec
206structure).
207If
208.I timeout
209is NULL, then the call blocks indefinitely
210(until one of the events above occurs).
211.PP
212No explicit indication of which request was completed is given;
213you must determine which request(s) have completed by iterating with
214.BR gai_error ()
215over the list of requests.
216
217The
218.BR gai_error ()
219function returns the status of the request
220.IR req :
221either
222.B EAI_INPROGRESS
223if the request was not completed yet,
2240 if it was handled successfully,
225or an error code if the request could not be resolved.
226
227The
228.BR gai_cancel ()
229function cancels the request
230.IR req .
231If the request has been canceled successfully,
232the error status of the request will be set to
819eeff4 233.B EAI_CANCELED
e11d63b9
PB
234and normal asynchronous notification will be performed.
235The request cannot be canceled if it is currently being processed;
236in that case, it will be handled as if
237.BR gai_cancel ()
238has never been called.
239If
240.I req
241is NULL, an attempt is made to cancel all outstanding requests
242that the process has made.
47297adb 243.SH RETURN VALUE
e11d63b9
PB
244The
245.BR getaddrinfo_a ()
246function returns 0 if all of the requests have been enqueued successfully,
247or one of the following nonzero error codes:
248.TP
249.B EAI_AGAIN
250The resources necessary to enqueue the look-up requests were not available.
251The application may check the error status of each
252request to determine which ones failed.
253.TP
254.B EAI_MEMORY
255Out of memory.
256.TP
257.B EAI_SYSTEM
258.I mode
259is invalid.
260.PP
261The
262.BR gai_suspend ()
263function returns 0 if at least one of the listed requests has been completed.
264Otherwise, it returns one of the following nonzero error codes:
265.TP
266.B EAI_AGAIN
267The given timeout expired before any of the requests could be completed.
268.TP
269.B EAI_ALLDONE
270There were no actual requests given to the function.
271.TP
272.B EAI_INTR
273A signal has interrupted the function.
274Note that this interruption might have been
275caused by signal notification of some completed look-up request.
276.PP
277The
278.BR gai_error ()
279function can return
280.B EAI_INPROGRESS
281for an unfinished look-up request,
2820 for a successfully completed look-up
283(as described above), one of the error codes that could be returned by
284.BR getaddrinfo (3),
285or the error code
819eeff4 286.B EAI_CANCELED
e11d63b9
PB
287if the request has been canceled explicitly before it could be finished.
288
289The
290.BR gai_cancel ()
291function can return one of these values:
292.TP
819eeff4 293.B EAI_CANCELED
e11d63b9
PB
294The request has been canceled successfully.
295.TP
819eeff4 296.B EAI_NOTCANCELED
e11d63b9
PB
297The request has not been canceled.
298.TP
299.B EAI_ALLDONE
300The request has already completed.
301.PP
302The
303.BR gai_strerror (3)
304function translates these error codes to a human readable string,
305suitable for error reporting.
9038b7f6
ZL
306.SH ATTRIBUTES
307For an explanation of the terms used in this section, see
308.BR attributes (7).
309.TS
310allbox;
311lbw31 lb lb
312l l l.
313Interface Attribute Value
314T{
315.BR getaddrinfo_a (),
316.BR gai_suspend (),
317.BR gai_error (),
318.BR gai_cancel ()
319T} Thread safety MT-Safe
320.TE
321
47297adb 322.SH CONFORMING TO
e11d63b9
PB
323These functions are GNU extensions;
324they first appeared in glibc in version 2.2.3.
325.SH NOTES
326The interface of
327.BR getaddrinfo_a ()
328was modeled after the
329.BR lio_listio (3)
330interface.
331.SH EXAMPLE
332Two examples are provided: a simple example that resolves
333several requests in parallel synchronously, and a complex example
334showing some of the asynchronous capabilities.
c634028a 335.SS Synchronous example
e11d63b9
PB
336The program below simply resolves several hostnames in parallel,
337giving a speed-up compared to resolving the hostnames sequentially using
338.BR getaddrinfo (3).
339The program might be used like this:
340.in +4n
341.nf
342
343$ \fB./a.out ftp.us.kernel.org enoent.linuxfoundation.org gnu.cz\fP
344ftp.us.kernel.org: 128.30.2.36
345enoent.linuxfoundation.org: Name or service not known
346gnu.cz: 87.236.197.13
347.fi
348.in
349.PP
350Here is the program source code
351.nf
352
353#define _GNU_SOURCE
354#include <netdb.h>
355#include <stdio.h>
356#include <stdlib.h>
357#include <string.h>
358
359int
360main(int argc, char *argv[])
361{
362 int i, ret;
363 struct gaicb *reqs[argc \- 1];
364 char host[NI_MAXHOST];
365 struct addrinfo *res;
366
367 if (argc < 2) {
368 fprintf(stderr, "Usage: %s HOST...\\n", argv[0]);
369 exit(EXIT_FAILURE);
370 }
371
372 for (i = 0; i < argc \- 1; i++) {
373 reqs[i] = malloc(sizeof(*reqs[0]));
374 if (reqs[i] == NULL) {
375 perror("malloc");
376 exit(EXIT_FAILURE);
377 }
378 memset(reqs[i], 0, sizeof(*reqs[0]));
379 reqs[i]\->ar_name = argv[i + 1];
380 }
381
382 ret = getaddrinfo_a(GAI_WAIT, reqs, argc \- 1, NULL);
383 if (ret != 0) {
384 fprintf(stderr, "getaddrinfo_a() failed: %s\\n",
385 gai_strerror(ret));
386 exit(EXIT_FAILURE);
387 }
388
389 for (i = 0; i < argc \- 1; i++) {
390 printf("%s: ", reqs[i]\->ar_name);
391 ret = gai_error(reqs[i]);
392 if (ret == 0) {
393 res = reqs[i]\->ar_result;
394
395 ret = getnameinfo(res\->ai_addr, res\->ai_addrlen,
396 host, sizeof(host),
397 NULL, 0, NI_NUMERICHOST);
398 if (ret != 0) {
399 fprintf(stderr, "getnameinfo() failed: %s\\n",
400 gai_strerror(ret));
401 exit(EXIT_FAILURE);
402 }
403 puts(host);
404
405 } else {
406 puts(gai_strerror(ret));
407 }
408 }
409 exit(EXIT_SUCCESS);
410}
411.fi
c634028a 412.SS Asynchronous example
e11d63b9
PB
413This example shows a simple interactive
414.BR getaddrinfo_a ()
415front-end.
416The notification facility is not demonstrated.
417.PP
b084fc29 418An example session might look like this:
e11d63b9
PB
419.in +4n
420.nf
421
422$ \fB./a.out\fP
423> a ftp.us.kernel.org enoent.linuxfoundation.org gnu.cz
424> c 2
425[2] gnu.cz: Request not canceled
426> w 0 1
427[00] ftp.us.kernel.org: Finished
428> l
429[00] ftp.us.kernel.org: 216.165.129.139
430[01] enoent.linuxfoundation.org: Processing request in progress
431[02] gnu.cz: 87.236.197.13
432> l
433[00] ftp.us.kernel.org: 216.165.129.139
434[01] enoent.linuxfoundation.org: Name or service not known
435[02] gnu.cz: 87.236.197.13
436.fi
437.in
438.PP
71af708f 439The program source is as follows:
e11d63b9 440
e11d63b9
PB
441.nf
442#define _GNU_SOURCE
443#include <netdb.h>
444#include <stdio.h>
445#include <stdlib.h>
446#include <string.h>
447
448static struct gaicb **reqs = NULL;
449static int nreqs = 0;
450
451static char *
452getcmd(void)
453{
454 static char buf[256];
455
456 fputs("> ", stdout); fflush(stdout);
457 if (fgets(buf, sizeof(buf), stdin) == NULL)
458 return NULL;
459
460 if (buf[strlen(buf) \- 1] == \(aq\\n\(aq)
461 buf[strlen(buf) \- 1] = 0;
462
463 return buf;
464}
465
466/* Add requests for specified hostnames */
467static void
468add_requests(void)
469{
470 int nreqs_base = nreqs;
471 char *host;
472 int ret;
473
474 while ((host = strtok(NULL, " "))) {
475 nreqs++;
476 reqs = realloc(reqs, nreqs * sizeof(reqs[0]));
477
478 reqs[nreqs \- 1] = calloc(1, sizeof(*reqs[0]));
479 reqs[nreqs \- 1]\->ar_name = strdup(host);
480 }
481
482 /* Queue nreqs_base..nreqs requests. */
483
484 ret = getaddrinfo_a(GAI_NOWAIT, &reqs[nreqs_base],
485 nreqs \- nreqs_base, NULL);
486 if (ret) {
487 fprintf(stderr, "getaddrinfo_a() failed: %s\\n",
488 gai_strerror(ret));
489 exit(EXIT_FAILURE);
490 }
491}
492
493/* Wait until at least one of specified requests completes */
494static void
495wait_requests(void)
496{
497 char *id;
498 int i, ret, n;
499 struct gaicb const **wait_reqs = calloc(nreqs, sizeof(*wait_reqs));
500 /* NULL elements are ignored by gai_suspend(). */
501
502 while ((id = strtok(NULL, " ")) != NULL) {
503 n = atoi(id);
504
505 if (n >= nreqs) {
506 printf("Bad request number: %s\\n", id);
507 return;
508 }
509
510 wait_reqs[n] = reqs[n];
511 }
512
513 ret = gai_suspend(wait_reqs, nreqs, NULL);
514 if (ret) {
515 printf("gai_suspend(): %s\\n", gai_strerror(ret));
516 return;
517 }
518
519 for (i = 0; i < nreqs; i++) {
520 if (wait_reqs[i] == NULL)
521 continue;
522
523 ret = gai_error(reqs[i]);
524 if (ret == EAI_INPROGRESS)
525 continue;
526
527 printf("[%02d] %s: %s\\n", i, reqs[i]\->ar_name,
528 ret == 0 ? "Finished" : gai_strerror(ret));
529 }
530}
531
532/* Cancel specified requests */
533static void
534cancel_requests(void)
535{
536 char *id;
537 int ret, n;
538
539 while ((id = strtok(NULL, " ")) != NULL) {
540 n = atoi(id);
541
542 if (n >= nreqs) {
543 printf("Bad request number: %s\\n", id);
544 return;
545 }
59e9285d 546
e11d63b9
PB
547 ret = gai_cancel(reqs[n]);
548 printf("[%s] %s: %s\\n", id, reqs[atoi(id)]\->ar_name,
549 gai_strerror(ret));
550 }
551}
552
553/* List all requests */
554static void
555list_requests(void)
556{
557 int i, ret;
558 char host[NI_MAXHOST];
559 struct addrinfo *res;
560
561 for (i = 0; i < nreqs; i++) {
562 printf("[%02d] %s: ", i, reqs[i]\->ar_name);
563 ret = gai_error(reqs[i]);
564
565 if (!ret) {
566 res = reqs[i]\->ar_result;
567
568 ret = getnameinfo(res\->ai_addr, res\->ai_addrlen,
569 host, sizeof(host),
570 NULL, 0, NI_NUMERICHOST);
571 if (ret) {
572 fprintf(stderr, "getnameinfo() failed: %s\\n",
573 gai_strerror(ret));
574 exit(EXIT_FAILURE);
575 }
576 puts(host);
577 } else {
578 puts(gai_strerror(ret));
579 }
580 }
581}
582
583int
584main(int argc, char *argv[])
585{
586 char *cmdline;
587 char *cmd;
588
589 while ((cmdline = getcmd()) != NULL) {
590 cmd = strtok(cmdline, " ");
591
592 if (cmd == NULL) {
593 list_requests();
594 } else {
595 switch (cmd[0]) {
596 case \(aqa\(aq:
597 add_requests();
598 break;
599 case \(aqw\(aq:
600 wait_requests();
601 break;
602 case \(aqc\(aq:
603 cancel_requests();
604 break;
605 case \(aql\(aq:
606 list_requests();
607 break;
608 default:
609 fprintf(stderr, "Bad command: %c\\n", cmd[0]);
610 break;
611 }
612 }
613 }
614 exit(EXIT_SUCCESS);
615}
616.fi
47297adb 617.SH SEE ALSO
e11d63b9
PB
618.BR getaddrinfo (3),
619.BR inet (3),
620.BR lio_listio (3),
621.BR hostname (7),
622.BR ip (7),
623.BR sigevent (7)