diff options
Diffstat (limited to 'src/lib/mhd_sockets.h')
-rw-r--r-- | src/lib/mhd_sockets.h | 760 |
1 files changed, 760 insertions, 0 deletions
diff --git a/src/lib/mhd_sockets.h b/src/lib/mhd_sockets.h new file mode 100644 index 00000000..c999ea35 --- /dev/null +++ b/src/lib/mhd_sockets.h | |||
@@ -0,0 +1,760 @@ | |||
1 | /* | ||
2 | This file is part of libmicrohttpd | ||
3 | Copyright (C) 2014-2016 Karlson2k (Evgeny Grin) | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file microhttpd/mhd_sockets.c | ||
23 | * @brief Header for platform-independent sockets abstraction | ||
24 | * @author Karlson2k (Evgeny Grin) | ||
25 | * | ||
26 | * Provides basic abstraction for sockets. | ||
27 | * Any functions can be implemented as macro on some platforms | ||
28 | * unless explicitly marked otherwise. | ||
29 | * Any function argument can be skipped in macro, so avoid | ||
30 | * variable modification in function parameters. | ||
31 | */ | ||
32 | |||
33 | #ifndef MHD_SOCKETS_H | ||
34 | #define MHD_SOCKETS_H 1 | ||
35 | #include "mhd_options.h" | ||
36 | |||
37 | #include <errno.h> | ||
38 | |||
39 | #if !defined(MHD_POSIX_SOCKETS) && !defined(MHD_WINSOCK_SOCKETS) | ||
40 | # if !defined(_WIN32) || defined(__CYGWIN__) | ||
41 | # define MHD_POSIX_SOCKETS 1 | ||
42 | # else /* defined(_WIN32) && !defined(__CYGWIN__) */ | ||
43 | # define MHD_WINSOCK_SOCKETS 1 | ||
44 | # endif /* defined(_WIN32) && !defined(__CYGWIN__) */ | ||
45 | #endif /* !MHD_POSIX_SOCKETS && !MHD_WINSOCK_SOCKETS */ | ||
46 | |||
47 | /* | ||
48 | * MHD require headers that define socket type, socket basic functions | ||
49 | * (socket(), accept(), listen(), bind(), send(), recv(), select()), socket | ||
50 | * parameters like SOCK_CLOEXEC, SOCK_NONBLOCK, additional socket functions | ||
51 | * (poll(), epoll(), accept4()), struct timeval and other types, required | ||
52 | * for socket function. | ||
53 | */ | ||
54 | #if defined(MHD_POSIX_SOCKETS) | ||
55 | # ifdef HAVE_SYS_TYPES_H | ||
56 | # include <sys/types.h> /* required on old platforms */ | ||
57 | # endif | ||
58 | # ifdef HAVE_SYS_SOCKET_H | ||
59 | # include <sys/socket.h> | ||
60 | # endif | ||
61 | # if defined(__VXWORKS__) || defined(__vxworks) || defined(OS_VXWORKS) | ||
62 | # ifdef HAVE_SOCKLIB_H | ||
63 | # include <sockLib.h> | ||
64 | # endif /* HAVE_SOCKLIB_H */ | ||
65 | # ifdef HAVE_INETLIB_H | ||
66 | # include <inetLib.h> | ||
67 | # endif /* HAVE_INETLIB_H */ | ||
68 | # include <strings.h> /* required for FD_SET (bzero() function) */ | ||
69 | # endif /* __VXWORKS__ || __vxworks || OS_VXWORKS */ | ||
70 | # ifdef HAVE_NETINET_IN_H | ||
71 | # include <netinet/in.h> | ||
72 | # endif /* HAVE_NETINET_IN_H */ | ||
73 | # ifdef HAVE_ARPA_INET_H | ||
74 | # include <arpa/inet.h> | ||
75 | # endif | ||
76 | # ifdef HAVE_NET_IF_H | ||
77 | # include <net/if.h> | ||
78 | # endif | ||
79 | # ifdef HAVE_SYS_TIME_H | ||
80 | # include <sys/time.h> | ||
81 | # endif | ||
82 | # ifdef HAVE_TIME_H | ||
83 | # include <time.h> | ||
84 | # endif | ||
85 | # ifdef HAVE_NETDB_H | ||
86 | # include <netdb.h> | ||
87 | # endif | ||
88 | # ifdef HAVE_SYS_SELECT_H | ||
89 | # include <sys/select.h> | ||
90 | # endif | ||
91 | # ifdef EPOLL_SUPPORT | ||
92 | # include <sys/epoll.h> | ||
93 | # endif | ||
94 | # ifdef HAVE_NETINET_TCP_H | ||
95 | /* for TCP_FASTOPEN and TCP_CORK */ | ||
96 | # include <netinet/tcp.h> | ||
97 | # endif | ||
98 | # ifdef HAVE_STRING_H | ||
99 | # include <string.h> /* for strerror() */ | ||
100 | # endif | ||
101 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
102 | # ifndef WIN32_LEAN_AND_MEAN | ||
103 | # define WIN32_LEAN_AND_MEAN 1 | ||
104 | # endif /* !WIN32_LEAN_AND_MEAN */ | ||
105 | # include <winsock2.h> | ||
106 | # include <ws2tcpip.h> | ||
107 | #endif /* MHD_WINSOCK_SOCKETS */ | ||
108 | |||
109 | #if defined(HAVE_POLL_H) && defined(HAVE_POLL) | ||
110 | # include <poll.h> | ||
111 | #endif | ||
112 | |||
113 | #include <stddef.h> | ||
114 | #if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED) | ||
115 | # include <stdint.h> | ||
116 | # define _SSIZE_T_DEFINED | ||
117 | typedef intptr_t ssize_t; | ||
118 | #endif /* !_SSIZE_T_DEFINED */ | ||
119 | |||
120 | #include "mhd_limits.h" | ||
121 | |||
122 | #ifdef _MHD_FD_SETSIZE_IS_DEFAULT | ||
123 | # define _MHD_SYS_DEFAULT_FD_SETSIZE FD_SETSIZE | ||
124 | #else /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ | ||
125 | # include "sysfdsetsize.h" | ||
126 | # define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value() | ||
127 | #endif /* ! _MHD_FD_SETSIZE_IS_DEFAULT */ | ||
128 | |||
129 | #ifndef MHD_PANIC | ||
130 | # include <stdio.h> | ||
131 | # include <stdlib.h> | ||
132 | /* Simple implementation of MHD_PANIC, to be used outside lib */ | ||
133 | # define MHD_PANIC(msg) do { fprintf (stderr, \ | ||
134 | "Abnormal termination at %d line in file %s: %s\n", \ | ||
135 | (int)__LINE__, __FILE__, msg); abort();} while(0) | ||
136 | #endif /* ! MHD_PANIC */ | ||
137 | |||
138 | #ifndef MHD_SOCKET_DEFINED | ||
139 | /** | ||
140 | * MHD_socket is type for socket FDs | ||
141 | */ | ||
142 | # if defined(MHD_POSIX_SOCKETS) | ||
143 | typedef int MHD_socket; | ||
144 | # define MHD_INVALID_SOCKET (-1) | ||
145 | # elif defined(MHD_WINSOCK_SOCKETS) | ||
146 | typedef SOCKET MHD_socket; | ||
147 | # define MHD_INVALID_SOCKET (INVALID_SOCKET) | ||
148 | # endif /* MHD_WINSOCK_SOCKETS */ | ||
149 | |||
150 | # define MHD_SOCKET_DEFINED 1 | ||
151 | #endif /* ! MHD_SOCKET_DEFINED */ | ||
152 | |||
153 | #ifdef SOCK_CLOEXEC | ||
154 | # define MAYBE_SOCK_CLOEXEC SOCK_CLOEXEC | ||
155 | #else /* ! SOCK_CLOEXEC */ | ||
156 | # define MAYBE_SOCK_CLOEXEC 0 | ||
157 | #endif /* ! SOCK_CLOEXEC */ | ||
158 | |||
159 | #ifdef HAVE_SOCK_NONBLOCK | ||
160 | # define MAYBE_SOCK_NONBLOCK SOCK_NONBLOCK | ||
161 | #else /* ! HAVE_SOCK_NONBLOCK */ | ||
162 | # define MAYBE_SOCK_NONBLOCK 0 | ||
163 | #endif /* ! HAVE_SOCK_NONBLOCK */ | ||
164 | |||
165 | #ifdef MSG_NOSIGNAL | ||
166 | # define MAYBE_MSG_NOSIGNAL MSG_NOSIGNAL | ||
167 | #else /* ! MSG_NOSIGNAL */ | ||
168 | # define MAYBE_MSG_NOSIGNAL 0 | ||
169 | #endif /* ! MSG_NOSIGNAL */ | ||
170 | |||
171 | #if !defined(SHUT_WR) && defined(SD_SEND) | ||
172 | # define SHUT_WR SD_SEND | ||
173 | #endif | ||
174 | #if !defined(SHUT_RD) && defined(SD_RECEIVE) | ||
175 | # define SHUT_RD SD_RECEIVE | ||
176 | #endif | ||
177 | #if !defined(SHUT_RDWR) && defined(SD_BOTH) | ||
178 | # define SHUT_RDWR SD_BOTH | ||
179 | #endif | ||
180 | |||
181 | #if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || defined(SOCK_CLOEXEC)) | ||
182 | # define USE_ACCEPT4 1 | ||
183 | #endif | ||
184 | |||
185 | #if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC) | ||
186 | # define USE_EPOLL_CREATE1 1 | ||
187 | #endif /* HAVE_EPOLL_CREATE1 && EPOLL_CLOEXEC */ | ||
188 | |||
189 | #ifdef TCP_FASTOPEN | ||
190 | /** | ||
191 | * Default TCP fastopen queue size. | ||
192 | */ | ||
193 | #define MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT 10 | ||
194 | #endif | ||
195 | |||
196 | |||
197 | /** | ||
198 | * MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt() | ||
199 | */ | ||
200 | #ifdef MHD_POSIX_SOCKETS | ||
201 | typedef int MHD_SCKT_OPT_BOOL_; | ||
202 | #else /* MHD_WINSOCK_SOCKETS */ | ||
203 | typedef BOOL MHD_SCKT_OPT_BOOL_; | ||
204 | #endif /* MHD_WINSOCK_SOCKETS */ | ||
205 | |||
206 | /** | ||
207 | * MHD_SCKT_SEND_SIZE_ is type used to specify size for send and recv | ||
208 | * functions | ||
209 | */ | ||
210 | #if !defined(MHD_WINSOCK_SOCKETS) | ||
211 | typedef size_t MHD_SCKT_SEND_SIZE_; | ||
212 | #else | ||
213 | typedef int MHD_SCKT_SEND_SIZE_; | ||
214 | #endif | ||
215 | |||
216 | /** | ||
217 | * MHD_SCKT_SEND_MAX_SIZE_ is maximum send()/recv() size value. | ||
218 | */ | ||
219 | #if !defined(MHD_WINSOCK_SOCKETS) | ||
220 | # define MHD_SCKT_SEND_MAX_SIZE_ SSIZE_MAX | ||
221 | #else | ||
222 | # define MHD_SCKT_SEND_MAX_SIZE_ INT_MAX | ||
223 | #endif | ||
224 | |||
225 | /** | ||
226 | * MHD_socket_close_(fd) close any FDs (non-W32) / close only socket | ||
227 | * FDs (W32). Note that on HP-UNIX, this function may leak the FD if | ||
228 | * errno is set to EINTR. Do not use HP-UNIX. | ||
229 | * | ||
230 | * @param fd descriptor to close | ||
231 | * @return boolean true on success (error codes like EINTR and EIO are | ||
232 | * counted as success, only EBADF counts as an error!), | ||
233 | * boolean false otherwise. | ||
234 | */ | ||
235 | #if !defined(MHD_WINSOCK_SOCKETS) | ||
236 | # define MHD_socket_close_(fd) ((0 == close((fd))) || (EBADF != errno)) | ||
237 | #else | ||
238 | # define MHD_socket_close_(fd) (0 == closesocket((fd))) | ||
239 | #endif | ||
240 | |||
241 | /** | ||
242 | * MHD_socket_close_chk_(fd) close socket and abort execution | ||
243 | * if error is detected. | ||
244 | * @param fd socket to close | ||
245 | */ | ||
246 | #define MHD_socket_close_chk_(fd) do { \ | ||
247 | if (!MHD_socket_close_(fd)) \ | ||
248 | MHD_PANIC(_("Close socket failed.\n")); \ | ||
249 | } while(0) | ||
250 | |||
251 | |||
252 | /** | ||
253 | * MHD_send_ is wrapper for system's send() | ||
254 | * @param s the socket to use | ||
255 | * @param b the buffer with data to send | ||
256 | * @param l the length of data in @a b | ||
257 | * @return ssize_t type value | ||
258 | */ | ||
259 | #define MHD_send_(s,b,l) \ | ||
260 | ((ssize_t)send((s),(const void*)(b),((MHD_SCKT_SEND_SIZE_)l), MAYBE_MSG_NOSIGNAL)) | ||
261 | |||
262 | |||
263 | /** | ||
264 | * MHD_recv_ is wrapper for system's recv() | ||
265 | * @param s the socket to use | ||
266 | * @param b the buffer for data to receive | ||
267 | * @param l the length of @a b | ||
268 | * @return ssize_t type value | ||
269 | */ | ||
270 | #define MHD_recv_(s,b,l) \ | ||
271 | ((ssize_t)recv((s),(void*)(b),((MHD_SCKT_SEND_SIZE_)l), 0)) | ||
272 | |||
273 | |||
274 | /** | ||
275 | * Check whether FD can be added to fd_set with specified FD_SETSIZE. | ||
276 | * @param fd the fd to check | ||
277 | * @param pset the pointer to fd_set to check or NULL to check | ||
278 | * whether FD can be used with fd_sets. | ||
279 | * @param setsize the value of FD_SETSIZE. | ||
280 | * @return boolean true if FD can be added to fd_set, | ||
281 | * boolean false otherwise. | ||
282 | */ | ||
283 | #if defined(MHD_POSIX_SOCKETS) | ||
284 | # define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ((fd) < ((MHD_socket)setsize)) | ||
285 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
286 | # define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ( ((void*)(pset)==(void*)0) || \ | ||
287 | (((fd_set*)(pset))->fd_count < ((unsigned)setsize)) || \ | ||
288 | (FD_ISSET((fd),(pset))) ) | ||
289 | #endif | ||
290 | |||
291 | /** | ||
292 | * Check whether FD can be added to fd_set with current FD_SETSIZE. | ||
293 | * @param fd the fd to check | ||
294 | * @param pset the pointer to fd_set to check or NULL to check | ||
295 | * whether FD can be used with fd_sets. | ||
296 | * @return boolean true if FD can be added to fd_set, | ||
297 | * boolean false otherwise. | ||
298 | */ | ||
299 | #define MHD_SCKT_FD_FITS_FDSET_(fd,pset) MHD_SCKT_FD_FITS_FDSET_SETSIZE_((fd),(pset),FD_SETSIZE) | ||
300 | |||
301 | /** | ||
302 | * Add FD to fd_set with specified FD_SETSIZE. | ||
303 | * @param fd the fd to add | ||
304 | * @param pset the valid pointer to fd_set. | ||
305 | * @param setsize the value of FD_SETSIZE. | ||
306 | * @note To work on W32 with value of FD_SETSIZE different from currently defined value, | ||
307 | * system definition of FD_SET() is not used. | ||
308 | */ | ||
309 | #if defined(MHD_POSIX_SOCKETS) | ||
310 | # define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) FD_SET((fd),(pset)) | ||
311 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
312 | # define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) \ | ||
313 | do { \ | ||
314 | u_int _i_ = 0; \ | ||
315 | fd_set* const _s_ = (fd_set*)(pset); \ | ||
316 | while((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array[_i_])) {++_i_;} \ | ||
317 | if ((_i_ == _s_->fd_count)) {_s_->fd_array[_s_->fd_count++] = (fd);} \ | ||
318 | } while(0) | ||
319 | #endif | ||
320 | |||
321 | /* MHD_SYS_select_ is wrapper macro for system select() function */ | ||
322 | #if !defined(MHD_WINSOCK_SOCKETS) | ||
323 | # define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t)) | ||
324 | #else | ||
325 | # define MHD_SYS_select_(n,r,w,e,t) \ | ||
326 | ( ( (((void*)(r) == (void*)0) || ((fd_set*)(r))->fd_count == 0) && \ | ||
327 | (((void*)(w) == (void*)0) || ((fd_set*)(w))->fd_count == 0) && \ | ||
328 | (((void*)(e) == (void*)0) || ((fd_set*)(e))->fd_count == 0) ) ? \ | ||
329 | ( ((void*)(t) == (void*)0) ? 0 : \ | ||
330 | (Sleep(((struct timeval*)(t))->tv_sec * 1000 + \ | ||
331 | ((struct timeval*)(t))->tv_usec / 1000), 0) ) : \ | ||
332 | (select((int)0,(r),(w),(e),(t))) ) | ||
333 | #endif | ||
334 | |||
335 | #if defined(HAVE_POLL) | ||
336 | /* MHD_sys_poll_ is wrapper macro for system poll() function */ | ||
337 | # if !defined(MHD_WINSOCK_SOCKETS) | ||
338 | # define MHD_sys_poll_ poll | ||
339 | # else /* MHD_WINSOCK_SOCKETS */ | ||
340 | # define MHD_sys_poll_ WSAPoll | ||
341 | # endif /* MHD_WINSOCK_SOCKETS */ | ||
342 | |||
343 | # ifdef POLLPRI | ||
344 | # define MHD_POLLPRI_OR_ZERO POLLPRI | ||
345 | # else /* ! POLLPRI */ | ||
346 | # define MHD_POLLPRI_OR_ZERO 0 | ||
347 | # endif /* ! POLLPRI */ | ||
348 | # ifdef POLLRDBAND | ||
349 | # define MHD_POLLRDBAND_OR_ZERO POLLRDBAND | ||
350 | # else /* ! POLLRDBAND */ | ||
351 | # define MHD_POLLRDBAND_OR_ZERO 0 | ||
352 | # endif /* ! POLLRDBAND */ | ||
353 | # ifdef POLLNVAL | ||
354 | # define MHD_POLLNVAL_OR_ZERO POLLNVAL | ||
355 | # else /* ! POLLNVAL */ | ||
356 | # define MHD_POLLNVAL_OR_ZERO 0 | ||
357 | # endif /* ! POLLNVAL */ | ||
358 | |||
359 | /* MHD_POLL_EVENTS_ERR_DISC is 'events' mask for errors and disconnect. | ||
360 | * Note: Out-of-band data is treated as error. */ | ||
361 | # if defined(_WIN32) && ! defined(__CYGWIN__) | ||
362 | # define MHD_POLL_EVENTS_ERR_DISC POLLRDBAND | ||
363 | # elif defined(__linux__) | ||
364 | # define MHD_POLL_EVENTS_ERR_DISC POLLPRI | ||
365 | # else /* ! __linux__ */ | ||
366 | # define MHD_POLL_EVENTS_ERR_DISC (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO) | ||
367 | # endif /* ! __linux__ */ | ||
368 | /* MHD_POLL_REVENTS_ERR_DISC is 'revents' mask for errors and disconnect. | ||
369 | * Note: Out-of-band data is treated as error. */ | ||
370 | # define MHD_POLL_REVENTS_ERR_DISC \ | ||
371 | (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR | POLLHUP) | ||
372 | /* MHD_POLL_REVENTS_ERRROR is 'revents' mask for errors. | ||
373 | * Note: Out-of-band data is treated as error. */ | ||
374 | # define MHD_POLL_REVENTS_ERRROR \ | ||
375 | (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR) | ||
376 | #endif /* HAVE_POLL */ | ||
377 | |||
378 | #define MHD_SCKT_MISSING_ERR_CODE_ 31450 | ||
379 | |||
380 | #if defined(MHD_POSIX_SOCKETS) | ||
381 | # if defined(EAGAIN) | ||
382 | # define MHD_SCKT_EAGAIN_ EAGAIN | ||
383 | # elif defined(EWOULDBLOCK) | ||
384 | # define MHD_SCKT_EAGAIN_ EWOULDBLOCK | ||
385 | # else /* !EAGAIN && !EWOULDBLOCK */ | ||
386 | # define MHD_SCKT_EAGAIN_ MHD_SCKT_MISSING_ERR_CODE_ | ||
387 | # endif /* !EAGAIN && !EWOULDBLOCK */ | ||
388 | # if defined(EWOULDBLOCK) | ||
389 | # define MHD_SCKT_EWOULDBLOCK_ EWOULDBLOCK | ||
390 | # elif defined(EAGAIN) | ||
391 | # define MHD_SCKT_EWOULDBLOCK_ EAGAIN | ||
392 | # else /* !EWOULDBLOCK && !EAGAIN */ | ||
393 | # define MHD_SCKT_EWOULDBLOCK_ MHD_SCKT_MISSING_ERR_CODE_ | ||
394 | # endif /* !EWOULDBLOCK && !EAGAIN */ | ||
395 | # ifdef EINTR | ||
396 | # define MHD_SCKT_EINTR_ EINTR | ||
397 | # else /* ! EINTR */ | ||
398 | # define MHD_SCKT_EINTR_ MHD_SCKT_MISSING_ERR_CODE_ | ||
399 | # endif /* ! EINTR */ | ||
400 | # ifdef ECONNRESET | ||
401 | # define MHD_SCKT_ECONNRESET_ ECONNRESET | ||
402 | # else /* ! ECONNRESET */ | ||
403 | # define MHD_SCKT_ECONNRESET_ MHD_SCKT_MISSING_ERR_CODE_ | ||
404 | # endif /* ! ECONNRESET */ | ||
405 | # ifdef ECONNABORTED | ||
406 | # define MHD_SCKT_ECONNABORTED_ ECONNABORTED | ||
407 | # else /* ! ECONNABORTED */ | ||
408 | # define MHD_SCKT_ECONNABORTED_ MHD_SCKT_MISSING_ERR_CODE_ | ||
409 | # endif /* ! ECONNABORTED */ | ||
410 | # ifdef ENOTCONN | ||
411 | # define MHD_SCKT_ENOTCONN_ ENOTCONN | ||
412 | # else /* ! ENOTCONN */ | ||
413 | # define MHD_SCKT_ENOTCONN_ MHD_SCKT_MISSING_ERR_CODE_ | ||
414 | # endif /* ! ENOTCONN */ | ||
415 | # ifdef EMFILE | ||
416 | # define MHD_SCKT_EMFILE_ EMFILE | ||
417 | # else /* ! EMFILE */ | ||
418 | # define MHD_SCKT_EMFILE_ MHD_SCKT_MISSING_ERR_CODE_ | ||
419 | # endif /* ! EMFILE */ | ||
420 | # ifdef ENFILE | ||
421 | # define MHD_SCKT_ENFILE_ ENFILE | ||
422 | # else /* ! ENFILE */ | ||
423 | # define MHD_SCKT_ENFILE_ MHD_SCKT_MISSING_ERR_CODE_ | ||
424 | # endif /* ! ENFILE */ | ||
425 | # ifdef ENOMEM | ||
426 | # define MHD_SCKT_ENOMEM_ ENOMEM | ||
427 | # else /* ! ENOMEM */ | ||
428 | # define MHD_SCKT_ENOMEM_ MHD_SCKT_MISSING_ERR_CODE_ | ||
429 | # endif /* ! ENOMEM */ | ||
430 | # ifdef ENOBUFS | ||
431 | # define MHD_SCKT_ENOBUFS_ ENOBUFS | ||
432 | # else /* ! ENOBUFS */ | ||
433 | # define MHD_SCKT_ENOBUFS_ MHD_SCKT_MISSING_ERR_CODE_ | ||
434 | # endif /* ! ENOBUFS */ | ||
435 | # ifdef EBADF | ||
436 | # define MHD_SCKT_EBADF_ EBADF | ||
437 | # else /* ! EBADF */ | ||
438 | # define MHD_SCKT_EBADF_ MHD_SCKT_MISSING_ERR_CODE_ | ||
439 | # endif /* ! EBADF */ | ||
440 | # ifdef ENOTSOCK | ||
441 | # define MHD_SCKT_ENOTSOCK_ ENOTSOCK | ||
442 | # else /* ! ENOTSOCK */ | ||
443 | # define MHD_SCKT_ENOTSOCK_ MHD_SCKT_MISSING_ERR_CODE_ | ||
444 | # endif /* ! ENOTSOCK */ | ||
445 | # ifdef EINVAL | ||
446 | # define MHD_SCKT_EINVAL_ EINVAL | ||
447 | # else /* ! EINVAL */ | ||
448 | # define MHD_SCKT_EINVAL_ MHD_SCKT_MISSING_ERR_CODE_ | ||
449 | # endif /* ! EINVAL */ | ||
450 | # ifdef EFAULT | ||
451 | # define MHD_SCKT_EFAUL_ EFAULT | ||
452 | # else /* ! EFAULT */ | ||
453 | # define MHD_SCKT_EFAUL_ MHD_SCKT_MISSING_ERR_CODE_ | ||
454 | # endif /* ! EFAULT */ | ||
455 | # ifdef ENOSYS | ||
456 | # define MHD_SCKT_ENOSYS_ ENOSYS | ||
457 | # else /* ! ENOSYS */ | ||
458 | # define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_ | ||
459 | # endif /* ! ENOSYS */ | ||
460 | # ifdef ENOTSUP | ||
461 | # define MHD_SCKT_ENOTSUP_ ENOTSUP | ||
462 | # else /* ! ENOTSUP */ | ||
463 | # define MHD_SCKT_ENOTSUP_ MHD_SCKT_MISSING_ERR_CODE_ | ||
464 | # endif /* ! ENOTSUP */ | ||
465 | # ifdef EOPNOTSUPP | ||
466 | # define MHD_SCKT_EOPNOTSUPP_ EOPNOTSUPP | ||
467 | # else /* ! EOPNOTSUPP */ | ||
468 | # define MHD_SCKT_EOPNOTSUPP_ MHD_SCKT_MISSING_ERR_CODE_ | ||
469 | # endif /* ! EOPNOTSUPP */ | ||
470 | # ifdef EACCES | ||
471 | # define MHD_SCKT_EACCESS_ EACCES | ||
472 | # else /* ! EACCES */ | ||
473 | # define MHD_SCKT_EACCESS_ MHD_SCKT_MISSING_ERR_CODE_ | ||
474 | # endif /* ! EACCES */ | ||
475 | # ifdef ENETDOWN | ||
476 | # define MHD_SCKT_ENETDOWN_ ENETDOWN | ||
477 | # else /* ! ENETDOWN */ | ||
478 | # define MHD_SCKT_ENETDOWN_ MHD_SCKT_MISSING_ERR_CODE_ | ||
479 | # endif /* ! ENETDOWN */ | ||
480 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
481 | # define MHD_SCKT_EAGAIN_ WSAEWOULDBLOCK | ||
482 | # define MHD_SCKT_EWOULDBLOCK_ WSAEWOULDBLOCK | ||
483 | # define MHD_SCKT_EINTR_ WSAEINTR | ||
484 | # define MHD_SCKT_ECONNRESET_ WSAECONNRESET | ||
485 | # define MHD_SCKT_ECONNABORTED_ WSAECONNABORTED | ||
486 | # define MHD_SCKT_ENOTCONN_ WSAENOTCONN | ||
487 | # define MHD_SCKT_EMFILE_ WSAEMFILE | ||
488 | # define MHD_SCKT_ENFILE_ MHD_SCKT_MISSING_ERR_CODE_ | ||
489 | # define MHD_SCKT_ENOMEM_ MHD_SCKT_MISSING_ERR_CODE_ | ||
490 | # define MHD_SCKT_ENOBUFS_ WSAENOBUFS | ||
491 | # define MHD_SCKT_EBADF_ WSAEBADF | ||
492 | # define MHD_SCKT_ENOTSOCK_ WSAENOTSOCK | ||
493 | # define MHD_SCKT_EINVAL_ WSAEINVAL | ||
494 | # define MHD_SCKT_EFAUL_ WSAEFAULT | ||
495 | # define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_ | ||
496 | # define MHD_SCKT_ENOTSUP_ MHD_SCKT_MISSING_ERR_CODE_ | ||
497 | # define MHD_SCKT_EOPNOTSUPP_ WSAEOPNOTSUPP | ||
498 | # define MHD_SCKT_EACCESS_ WSAEACCES | ||
499 | # define MHD_SCKT_ENETDOWN_ WSAENETDOWN | ||
500 | #endif | ||
501 | |||
502 | /** | ||
503 | * MHD_socket_error_ return system native error code for last socket error. | ||
504 | * @return system error code for last socket error. | ||
505 | */ | ||
506 | #if defined(MHD_POSIX_SOCKETS) | ||
507 | # define MHD_socket_get_error_() (errno) | ||
508 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
509 | # define MHD_socket_get_error_() WSAGetLastError() | ||
510 | #endif | ||
511 | |||
512 | #ifdef MHD_WINSOCK_SOCKETS | ||
513 | /* POSIX-W32 sockets compatibility functions */ | ||
514 | |||
515 | /** | ||
516 | * Return pointer to string description of specified WinSock error | ||
517 | * @param err the WinSock error code. | ||
518 | * @return pointer to string description of specified WinSock error. | ||
519 | */ | ||
520 | const char* MHD_W32_strerror_winsock_(int err); | ||
521 | #endif /* MHD_WINSOCK_SOCKETS */ | ||
522 | |||
523 | /* MHD_socket_last_strerr_ is description string of specified socket error code */ | ||
524 | #if defined(MHD_POSIX_SOCKETS) | ||
525 | # define MHD_socket_strerr_(err) strerror((err)) | ||
526 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
527 | # define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_((err)) | ||
528 | #endif | ||
529 | |||
530 | /* MHD_socket_last_strerr_ is description string of last errno (non-W32) / | ||
531 | * description string of last socket error (W32) */ | ||
532 | #define MHD_socket_last_strerr_() MHD_socket_strerr_(MHD_socket_get_error_()) | ||
533 | |||
534 | /** | ||
535 | * MHD_socket_fset_error_() set socket system native error code. | ||
536 | */ | ||
537 | #if defined(MHD_POSIX_SOCKETS) | ||
538 | # define MHD_socket_fset_error_(err) (errno = (err)) | ||
539 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
540 | # define MHD_socket_fset_error_(err) (WSASetLastError((err))) | ||
541 | #endif | ||
542 | |||
543 | /** | ||
544 | * MHD_socket_try_set_error_() set socket system native error code if | ||
545 | * specified code is defined on system. | ||
546 | * @return non-zero if specified @a err code is defined on system | ||
547 | * and error was set; | ||
548 | * zero if specified @a err code is not defined on system | ||
549 | * and error was not set. | ||
550 | */ | ||
551 | #define MHD_socket_try_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \ | ||
552 | (MHD_socket_fset_error_((err)), !0) : 0 ) | ||
553 | |||
554 | /** | ||
555 | * MHD_socket_set_error_() set socket system native error code to | ||
556 | * specified code or replacement code if specified code is not | ||
557 | * defined on system. | ||
558 | */ | ||
559 | #if defined(MHD_POSIX_SOCKETS) | ||
560 | # if defined(ENOSYS) | ||
561 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ | ||
562 | (errno = ENOSYS) : (errno = (err)) ) | ||
563 | # elif defined(EOPNOTSUPP) | ||
564 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ | ||
565 | (errno = EOPNOTSUPP) : (errno = (err)) ) | ||
566 | # elif defined (EFAULT) | ||
567 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ | ||
568 | (errno = EFAULT) : (errno = (err)) ) | ||
569 | # elif defined (EINVAL) | ||
570 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ | ||
571 | (errno = EINVAL) : (errno = (err)) ) | ||
572 | # else /* !EOPNOTSUPP && !EFAULT && !EINVAL */ | ||
573 | # warning No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system. | ||
574 | # define MHD_socket_set_error_(err) (errno = (err)) | ||
575 | # endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/ | ||
576 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
577 | # define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \ | ||
578 | (WSASetLastError((WSAEOPNOTSUPP))) : \ | ||
579 | (WSASetLastError((err))) ) | ||
580 | #endif | ||
581 | |||
582 | /** | ||
583 | * Check whether given socket error is equal to specified system | ||
584 | * native MHD_SCKT_E*_ code. | ||
585 | * If platform don't have specific error code, result is | ||
586 | * always boolean false. | ||
587 | * @return boolean true if @a code is real error code and | ||
588 | * @a err equals to MHD_SCKT_E*_ @a code; | ||
589 | * boolean false otherwise | ||
590 | */ | ||
591 | #define MHD_SCKT_ERR_IS_(err,code) ( (MHD_SCKT_MISSING_ERR_CODE_ != (code)) && \ | ||
592 | ((code) == (err)) ) | ||
593 | |||
594 | /** | ||
595 | * Check whether last socket error is equal to specified system | ||
596 | * native MHD_SCKT_E*_ code. | ||
597 | * If platform don't have specific error code, result is | ||
598 | * always boolean false. | ||
599 | * @return boolean true if @a code is real error code and | ||
600 | * last socket error equals to MHD_SCKT_E*_ @a code; | ||
601 | * boolean false otherwise | ||
602 | */ | ||
603 | #define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_(MHD_socket_get_error_() ,(code)) | ||
604 | |||
605 | /* Specific error code checks */ | ||
606 | |||
607 | /** | ||
608 | * Check whether given socket error is equal to system's | ||
609 | * socket error codes for EINTR. | ||
610 | * @return boolean true if @a err is equal to sockets' EINTR code; | ||
611 | * boolean false otherwise. | ||
612 | */ | ||
613 | #define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EINTR_) | ||
614 | |||
615 | /** | ||
616 | * Check whether given socket error is equal to system's | ||
617 | * socket error codes for EAGAIN or EWOULDBLOCK. | ||
618 | * @return boolean true if @a err is equal to sockets' EAGAIN or EWOULDBLOCK codes; | ||
619 | * boolean false otherwise. | ||
620 | */ | ||
621 | #if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_ | ||
622 | # define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_) | ||
623 | #else /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ | ||
624 | # define MHD_SCKT_ERR_IS_EAGAIN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_) || \ | ||
625 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_EWOULDBLOCK_) ) | ||
626 | #endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */ | ||
627 | |||
628 | /** | ||
629 | * Check whether given socket error is any kind of "low resource" error. | ||
630 | * @return boolean true if @a err is any kind of "low resource" error, | ||
631 | * boolean false otherwise. | ||
632 | */ | ||
633 | #define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EMFILE_) || \ | ||
634 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENFILE_) || \ | ||
635 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOMEM_) || \ | ||
636 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOBUFS_) ) | ||
637 | |||
638 | /** | ||
639 | * Check whether is given socket error is type of "incoming connection | ||
640 | * was disconnected before 'accept()' is called". | ||
641 | * @return boolean true is @a err match described socket error code, | ||
642 | * boolean false otherwise. | ||
643 | */ | ||
644 | #if defined(MHD_POSIX_SOCKETS) | ||
645 | # define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_) | ||
646 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
647 | # define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_) | ||
648 | #endif | ||
649 | |||
650 | /** | ||
651 | * Check whether is given socket error is type of "connection was terminated | ||
652 | * by remote side". | ||
653 | * @return boolean true is @a err match described socket error code, | ||
654 | * boolean false otherwise. | ||
655 | */ | ||
656 | #define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_) || \ | ||
657 | MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_)) | ||
658 | |||
659 | /* Specific error code set */ | ||
660 | |||
661 | /** | ||
662 | * Set socket's error code to ENOMEM or equivalent if ENOMEM is not | ||
663 | * available on platform. | ||
664 | */ | ||
665 | #if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_ | ||
666 | # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_) | ||
667 | #elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_ | ||
668 | # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOBUFS_) | ||
669 | #else | ||
670 | # warning No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system. | ||
671 | # define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_) | ||
672 | #endif | ||
673 | |||
674 | /* Socket functions */ | ||
675 | |||
676 | #if defined(AF_LOCAL) | ||
677 | # define MHD_SCKT_LOCAL AF_LOCAL | ||
678 | #elif defined(AF_UNIX) | ||
679 | # define MHD_SCKT_LOCAL AF_UNIX | ||
680 | #endif /* AF_UNIX */ | ||
681 | |||
682 | #if defined(MHD_POSIX_SOCKETS) && defined(MHD_SCKT_LOCAL) | ||
683 | # define MHD_socket_pair_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM, 0, (fdarr))) | ||
684 | # if defined(HAVE_SOCK_NONBLOCK) | ||
685 | # define MHD_socket_pair_nblk_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0, (fdarr))) | ||
686 | # endif /* HAVE_SOCK_NONBLOCK*/ | ||
687 | #elif defined(MHD_WINSOCK_SOCKETS) | ||
688 | /** | ||
689 | * Create pair of mutually connected TCP/IP sockets on loopback address | ||
690 | * @param sockets_pair array to receive resulted sockets | ||
691 | * @param non_blk if set to non-zero value, sockets created in non-blocking mode | ||
692 | * otherwise sockets will be in blocking mode | ||
693 | * @return non-zero if succeeded, zero otherwise | ||
694 | */ | ||
695 | int MHD_W32_socket_pair_(SOCKET sockets_pair[2], int non_blk); | ||
696 | |||
697 | # define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_((fdarr), 0) | ||
698 | # define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_((fdarr), 1) | ||
699 | #endif | ||
700 | |||
701 | /** | ||
702 | * Add @a fd to the @a set. If @a fd is | ||
703 | * greater than @a max_fd, set @a max_fd to @a fd. | ||
704 | * | ||
705 | * @param fd file descriptor to add to the @a set | ||
706 | * @param set set to modify | ||
707 | * @param max_fd maximum value to potentially update | ||
708 | * @param fd_setsize value of FD_SETSIZE | ||
709 | * @return non-zero if succeeded, zero otherwise | ||
710 | */ | ||
711 | int | ||
712 | MHD_add_to_fd_set_ (MHD_socket fd, | ||
713 | fd_set *set, | ||
714 | MHD_socket *max_fd, | ||
715 | unsigned int fd_setsize); | ||
716 | |||
717 | |||
718 | /** | ||
719 | * Change socket options to be non-blocking. | ||
720 | * | ||
721 | * @param sock socket to manipulate | ||
722 | * @return non-zero if succeeded, zero otherwise | ||
723 | */ | ||
724 | int | ||
725 | MHD_socket_nonblocking_ (MHD_socket sock); | ||
726 | |||
727 | |||
728 | /** | ||
729 | * Change socket options to be non-inheritable. | ||
730 | * | ||
731 | * @param sock socket to manipulate | ||
732 | * @return non-zero if succeeded, zero otherwise | ||
733 | * @warning Does not set socket error on W32. | ||
734 | */ | ||
735 | int | ||
736 | MHD_socket_noninheritable_ (MHD_socket sock); | ||
737 | |||
738 | |||
739 | #if defined(SOL_SOCKET) && defined(SO_NOSIGPIPE) | ||
740 | static const int _MHD_socket_int_one = 1; | ||
741 | /** | ||
742 | * Change socket options to no signal on remote disconnect. | ||
743 | * | ||
744 | * @param sock socket to manipulate | ||
745 | * @return non-zero if succeeded, zero otherwise | ||
746 | */ | ||
747 | # define MHD_socket_nosignal_(sock) \ | ||
748 | (!setsockopt((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one,sizeof(_MHD_socket_int_one))) | ||
749 | #endif /* SOL_SOCKET && SO_NOSIGPIPE */ | ||
750 | |||
751 | /** | ||
752 | * Create a listen socket, with noninheritable flag if possible. | ||
753 | * | ||
754 | * @param use_ipv6 if set to non-zero IPv6 is used | ||
755 | * @return created socket or MHD_INVALID_SOCKET in case of errors | ||
756 | */ | ||
757 | MHD_socket | ||
758 | MHD_socket_create_listen_ (bool use_ipv6); | ||
759 | |||
760 | #endif /* ! MHD_SOCKETS_H */ | ||