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