3 /* async_netdb.h, Copyright (c) Dave Odell <dmo2118@gmail.com>
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation. No representations are made about the suitability of this
10 * software for any purpose. It is provided "as is" without express or
17 #include "thread_util.h"
20 #include <netinet/in.h>
21 #include <sys/socket.h>
25 Both async_name_from_addr_* and async_addr_from_name_* follow basic pattern
26 for io_thread clients as described in thread_util.h:
27 1. async_*_from_*_start
28 2. async_*_from_*_is_done (repeat as necessary)
29 3a. async_*_from_*_finish to retrieve the results, or:
30 3b. async_*_from_*_cancel to abort the lookup.
32 On systems that can't do asynchronous host lookups, the *_finish functions
38 From the glibc man page for getnameinfo(3):
39 Since glibc 2.8, these definitions are exposed only if one of the
40 feature test macros _BSD_SOURCE, _SVID_SOURCE, or _GNU_SOURCE is
43 # define NI_MAXHOST 1025
46 #if HAVE_PTHREAD && HAVE_GETADDRINFO
48 If threads or getaddrinfo() are unavailable, then the older gethostbyname()
49 and gethostbyaddr() functions are used, and IPv6 is disabled.
51 # define ASYNC_NETDB_USE_GAI 1
54 #if ASYNC_NETDB_USE_GAI
56 typedef struct sockaddr_storage async_netdb_sockaddr_storage_t;
58 int _async_netdb_is_done (struct io_thread *io);
62 typedef struct sockaddr_in async_netdb_sockaddr_storage_t;
65 /* The EAI_* codes are specified specifically as preprocessor macros, so
66 the #ifdef here should always work...
67 http://pubs.opengroup.org/onlinepubs/009604499/basedefs/netdb.h.html */
69 # define ASYNC_NETDB_FAKE_EAI 1
71 /* Even without addrinfo, the EAI_* error codes are used. The numbers are from
73 # define EAI_NONAME -2
76 # define EAI_MEMORY -10
77 # define EAI_SYSTEM -11
79 const char *_async_netdb_strerror (int errcode);
81 # define gai_strerror(errcode) _async_netdb_strerror (errcode)
84 # define _async_netdb_is_done(io) 1
88 /* In non-threaded mode, _async_name_from_addr_param is used in place of
89 async_name_from_addr. */
90 struct _async_name_from_addr_param
93 async_netdb_sockaddr_storage_t addr;
96 typedef struct async_name_from_addr
99 Stupid memory trick, thwarted: The host string could be at the beginning
100 of this structure, and the memory block that contains this struct could
101 be resized and returned directly in async_name_from_addr_finish. But...
103 There is no aligned_realloc. In fact, aligned_realloc is a bit of a
104 problem, mostly because:
105 1. realloc() is the only way to resize a heap-allocated memory block.
106 2. realloc() moves memory.
107 3. The location that realloc() moves memory to won't be aligned.
110 struct _async_name_from_addr_param param;
113 char host[NI_MAXHOST];
117 } *async_name_from_addr_t;
119 async_name_from_addr_t async_name_from_addr_start (Display *dpy,
120 const struct sockaddr *addr,
123 Starts an asynchronous name-from-address lookup.
124 dpy: An X11 Display with a .useThreads resource.
125 addr: An address. Like various socket functions (e.g. bind(2),
126 connect(2), sendto(2)), this isn't really a struct sockaddr so
127 much as a "subtype" of sockaddr, like sockaddr_in, or
128 sockaddr_in6, or whatever.
129 addrlen: The (actual) length of *addr.
130 Returns NULL if the request couldn't be created (due to low memory).
133 #define async_name_from_addr_is_done(self) _async_netdb_is_done (&(self)->io)
135 #if ASYNC_NETDB_USE_GAI
136 void async_name_from_addr_cancel (async_name_from_addr_t self);
138 # define async_name_from_addr_cancel(self) (free (self))
141 int async_name_from_addr_finish (async_name_from_addr_t self,
142 char **host, int *errno_error);
144 Gets the result of an asynchronous name-from-address lookup. If the lookup
145 operation is still in progress, or if the system can't do async lookups,
146 this will block. This cleans up the lookup operation; do not use 'self'
147 after calling this function.
148 self: The lookup operation.
149 host: If no error, the name of the host. Free this with free(3).
150 errno_error: The value of errno if EAI_SYSTEM is returned. Can be NULL.
151 Returns 0 on success, otherwise an error from getnameinfo(3).
154 /* In non-threaded mode, async_addr_from_name contains different stuff. */
155 typedef struct async_addr_from_name
157 #if ASYNC_NETDB_USE_GAI
163 struct addrinfo *res;
165 char dont_complain_about_empty_structs;
167 } *async_addr_from_name_t;
169 async_addr_from_name_t async_addr_from_name_start (Display *dpy,
172 Starts an asynchronous address-from-name lookup.
174 host: The hostname to look up.
175 Returns NULL if the request couldn't be created (due to low memory).
178 #define async_addr_from_name_is_done(self) _async_netdb_is_done (&(self)->io)
180 #if ASYNC_NETDB_USE_GAI
181 void async_addr_from_name_cancel (async_addr_from_name_t self);
183 # define async_addr_from_name_cancel(self) (thread_free (self));
186 /* sockaddr must be sizeof(async_netdb_sockaddr_storage_t) in size. */
187 int async_addr_from_name_finish (async_addr_from_name_t self, void *addr,
188 socklen_t *addrlen, int *errno_error);
190 Returns the address from an asynchronous address-from-name operation. If
191 the lookup is still in progress, or the system can't do an asynchronous
192 lookup, this blocks. This cleans up the lookup operation; do not use 'self'
193 after calling this function.
194 self: The lookup operation.
195 addr: A sockaddr. This must be as large as or larger than
196 sizeof(async_netdb_sockaddr_storage_t). (Hint: just use an
197 instance of async_netdb_sockaddr_storage_t itself here.)
198 addrlen: The length of the obtained sockaddr.
199 errno_error: The value of errno if EAI_SYSTEM is returned. Can be NULL.
200 Returns 0 on success, or an error from getaddrinfo(3).
205 /* Local Variables: */
207 /* fill-column: 78 */
208 /* c-file-style: "gnu" */
209 /* c-basic-offset: 2 */
210 /* indent-tabs-mode: nil */