aboutsummaryrefslogtreecommitdiff
path: root/src/lib/mhd_sockets.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/mhd_sockets.h')
-rw-r--r--src/lib/mhd_sockets.h760
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 */
711int
712MHD_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 */
724int
725MHD_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 */
735int
736MHD_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 */
757MHD_socket
758MHD_socket_create_listen_ (bool use_ipv6);
759
760#endif /* ! MHD_SOCKETS_H */