]> git.ipfire.org Git - thirdparty/man-pages.git/blobdiff - man3/gai_cancel.3
signal.7: Note async-signal-safe functions added by POSIX.1-2008 TC1
[thirdparty/man-pages.git] / man3 / gai_cancel.3
index b39fd07ebe2d8a7df272898681efa3d5090e63ff..1b0f392ae93bdc7bea6834f956a4c0537076f5f0 100644 (file)
@@ -1,606 +1 @@
-.\" Copyright (c) 2009 Petr Baudis <pasky@suse.cz>
-.\" and clean-ups and additions (C) 2010 Michael Kerrisk <mtk.manpages@gmail.com>
-.\"
-.\" Permission is granted to make and distribute verbatim copies of this
-.\" manual provided the copyright notice and this permission notice are
-.\" preserved on all copies.
-.\"
-.\" Permission is granted to copy and distribute modified versions of this
-.\" manual under the conditions for verbatim copying, provided that the
-.\" entire resulting derived work is distributed under the terms of a
-.\" permission notice identical to this one.
-.\"
-.\" Since the Linux kernel and libraries are constantly changing, this
-.\" manual page may be incorrect or out-of-date.  The author(s) assume no
-.\" responsibility for errors or omissions, or for damages resulting from
-.\" the use of the information contained herein.  The author(s) may not
-.\" have taken the same level of care in the production of this manual,
-.\" which is licensed free of charge, as they might when working
-.\" professionally.
-.\"
-.\" Formatted or processed versions of this manual, if unaccompanied by
-.\" the source, must acknowledge the copyright and authors of this work.
-.\"
-.\" 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 2010-09-27 "GNU" "Linux Programmer's Manual"
-.SH NAME
-getaddrinfo_a, gai_suspend, gai_error, gai_cancel \- asynchronous
-network address and service translation
-.SH SYNOPSIS
-.nf
-.B #define _GNU_SOURCE
-.B #include <netdb.h>
-.sp
-.BI "int getaddrinfo_a(int " "mode" ", struct gaicb *" "list[]" ,
-.BI "                int " "nitems" ", struct sigevent *" "sevp" );
-.sp
-.BI "int gai_suspend(struct gaicb *" "list[]" ", int " "nitems" ,
-.BI "                struct timespec *" "timeout" );
-.sp
-.BI "int gai_error(struct gaicb *" "req" );
-.sp
-.BI "int gai_cancel(struct gaicb *" "req" );
-.sp
-Link with \fI\-lanl\fP.
-.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.
-
-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.
-.PP
-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:
-.sp
-.in +4n
-.nf
-struct gaicb {
-    const char            *ar_name;
-    const char            *ar_service;
-    const struct addrinfo *ar_request;
-    struct addrinfo       *ar_result;
-};
-.fi
-.in
-
-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).
-
-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 (7).
-The
-.I sevp\->sigev_notify
-field can have the following values:
-.TP
-.BR SIGEV_NONE
-Don't provide any notification.
-.TP
-.BR SIGEV_SIGNAL
-When a look-up completes, generate the signal
-.I sigev_signo
-for the process.
-See
-.BR sigevent (7)
-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
-.BR 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 (7)
-for details.
-.PP
-For 
-.BR SIGEV_SIGNAL
-and
-.BR SIGEV_THREAD ,
-it may be useful to point
-.IR sevp\->sigev_value.sival_ptr
-to
-.IR list .
-
-The
-.BR gai_suspend ()
-function suspends execution of the calling thread,
-waiting for the completion of one or more requests in the array
-.ID list .
-The
-.I nitems
-argument specifies the size of the array
-.IR list .
-The call blocks until one of the following occurs:
-.IP * 3
-One or more of the operations in
-.I list
-completes.
-.IP *
-The call is interrupted by a signal that is caught.
-.IP *
-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).
-.PP
-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.
-
-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.
-
-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_CANCELLED
-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.
-.PP
-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.
-.PP
-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_CANCELLED
-if the request has been canceled explicitly before it could be finished.
-
-The
-.BR gai_cancel ()
-function can return one of these values:
-.TP
-.B EAI_CANCELLED
-The request has been canceled successfully.
-.TP
-.B EAI_NOTCANCELLED
-The request has not been canceled.
-.TP
-.B EAI_ALLDONE
-The request has already completed.
-.PP
-The
-.BR gai_strerror (3)
-function translates these error codes to a human readable string,
-suitable for error reporting.
-.SH "CONFORMING TO"
-These functions are GNU extensions;
-they first appeared in glibc in version 2.2.3.
-.SH NOTES
-The interface of
-.BR getaddrinfo_a ()
-was modeled after the
-.BR lio_listio (3)
-interface.
-.SH EXAMPLE
-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:
-.in +4n
-.nf
-
-$ \fB./a.out ftp.us.kernel.org enoent.linuxfoundation.org gnu.cz\fP
-ftp.us.kernel.org: 128.30.2.36
-enoent.linuxfoundation.org: Name or service not known
-gnu.cz: 87.236.197.13
-.fi
-.in
-.PP
-Here is the program source code
-.nf
-
-#define _GNU_SOURCE
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int
-main(int argc, char *argv[])
-{
-    int i, ret;
-    struct gaicb *reqs[argc \- 1];
-    char host[NI_MAXHOST];
-    struct addrinfo *res;
-
-    if (argc < 2) {
-        fprintf(stderr, "Usage: %s HOST...\\n", argv[0]);
-        exit(EXIT_FAILURE);
-    }
-
-    for (i = 0; i < argc \- 1; i++) {
-        reqs[i] = malloc(sizeof(*reqs[0]));
-        if (reqs[i] == NULL) {
-            perror("malloc");
-            exit(EXIT_FAILURE);
-        }
-        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\\n",
-                gai_strerror(ret));
-        exit(EXIT_FAILURE);
-    }
-
-    for (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\\n",
-                        gai_strerror(ret));
-                exit(EXIT_FAILURE);
-            }
-            puts(host);
-
-        } else {
-            puts(gai_strerror(ret));
-        }
-    }
-    exit(EXIT_SUCCESS);
-}
-.fi
-
-.SS Asynchronous Example
-This example shows a simple interactive
-.BR getaddrinfo_a ()
-front-end.
-The notification facility is not demonstrated.
-.PP
-An example session might look like like this:
-.in +4n
-.nf
-
-$ \fB./a.out\fP
-> a ftp.us.kernel.org enoent.linuxfoundation.org gnu.cz
-> c 2
-[2] gnu.cz: Request not canceled
-> w 0 1
-[00] ftp.us.kernel.org: Finished
-> l
-[00] ftp.us.kernel.org: 216.165.129.139
-[01] enoent.linuxfoundation.org: Processing request in progress
-[02] gnu.cz: 87.236.197.13
-> l
-[00] ftp.us.kernel.org: 216.165.129.139
-[01] enoent.linuxfoundation.org: Name or service not known
-[02] gnu.cz: 87.236.197.13
-.fi
-.in
-.PP
-The program source goes as follows:
-
-\&
-.nf
-#define _GNU_SOURCE
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static struct gaicb **reqs = NULL;
-static int nreqs = 0;
-
-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\\n\(aq)
-        buf[strlen(buf) \- 1] = 0;
-
-    return buf;
-}
-
-/* Add requests for specified hostnames */
-static void
-add_requests(void)
-{
-    int nreqs_base = nreqs;
-    char *host;
-    int ret;
-
-    while ((host = strtok(NULL, " "))) {
-        nreqs++;
-        reqs = realloc(reqs, nreqs * sizeof(reqs[0]));
-
-        reqs[nreqs \- 1] = calloc(1, sizeof(*reqs[0]));
-        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\\n",
-                gai_strerror(ret));
-        exit(EXIT_FAILURE);
-    }
-}
-
-/* Wait until at least one of specified requests completes */
-static void
-wait_requests(void)
-{
-    char *id;
-    int i, ret, n;
-    struct gaicb const **wait_reqs = calloc(nreqs, sizeof(*wait_reqs));
-                /* NULL elements are ignored by gai_suspend(). */
-
-    while ((id = strtok(NULL, " ")) != NULL) {
-        n = atoi(id);
-
-        if (n >= nreqs) {
-            printf("Bad request number: %s\\n", id);
-            return;
-        }
-
-        wait_reqs[n] = reqs[n];
-    }
-
-    ret = gai_suspend(wait_reqs, nreqs, NULL);
-    if (ret) {
-        printf("gai_suspend(): %s\\n", gai_strerror(ret));
-        return;
-    }
-
-    for (i = 0; i < nreqs; i++) {
-        if (wait_reqs[i] == NULL)
-            continue;
-
-        ret = gai_error(reqs[i]);
-        if (ret == EAI_INPROGRESS)
-            continue;
-
-        printf("[%02d] %s: %s\\n", i, reqs[i]\->ar_name,
-               ret == 0 ? "Finished" : gai_strerror(ret));
-    }
-}
-
-/* Cancel specified requests */
-static void
-cancel_requests(void)
-{
-    char *id;
-    int ret, n;
-
-    while ((id = strtok(NULL, " ")) != NULL) {
-        n = atoi(id);
-
-        if (n >= nreqs) {
-            printf("Bad request number: %s\\n", id);
-            return;
-        }
-        
-        ret = gai_cancel(reqs[n]);
-        printf("[%s] %s: %s\\n", id, reqs[atoi(id)]\->ar_name,
-               gai_strerror(ret));
-    }
-}
-
-/* List all requests */
-static void
-list_requests(void)
-{
-    int i, ret;
-    char host[NI_MAXHOST];
-    struct addrinfo *res;
-
-    for (i = 0; i < nreqs; i++) {
-        printf("[%02d] %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\\n",
-                        gai_strerror(ret));
-                exit(EXIT_FAILURE);
-            }
-            puts(host);
-        } else {
-            puts(gai_strerror(ret));
-        }
-    }
-}
-
-int
-main(int argc, char *argv[])
-{
-    char *cmdline;
-    char *cmd;
-
-    while ((cmdline = getcmd()) != NULL) {
-        cmd = strtok(cmdline, " ");
-
-        if (cmd == NULL) {
-            list_requests();
-        } else {
-            switch (cmd[0]) {
-            case \(aqa\(aq:
-                add_requests();
-                break;
-            case \(aqw\(aq:
-                wait_requests();
-                break;
-            case \(aqc\(aq:
-                cancel_requests();
-                break;
-            case \(aql\(aq:
-                list_requests();
-                break;
-            default:
-                fprintf(stderr, "Bad command: %c\\n", cmd[0]);
-                break;
-            }
-        }
-    }
-    exit(EXIT_SUCCESS);
-}
-.fi
-.SH "SEE ALSO"
-.BR getaddrinfo (3),
-.BR inet (3),
-.BR lio_listio (3),
-.BR hostname (7),
-.BR ip (7),
-.BR sigevent (7)
+.so man3/getaddrinfo_a.3