mhd_sockets_macros.h (12062B)
1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */ 2 /* 3 This file is part of GNU libmicrohttpd. 4 Copyright (C) 2014-2024 Karlson2k (Evgeny Grin) 5 6 GNU libmicrohttpd is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 GNU libmicrohttpd is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 Alternatively, you can redistribute GNU libmicrohttpd and/or 17 modify it under the terms of the GNU General Public License as 18 published by the Free Software Foundation; either version 2 of 19 the License, or (at your option) any later version, together 20 with the eCos exception, as follows: 21 22 As a special exception, if other files instantiate templates or 23 use macros or inline functions from this file, or you compile this 24 file and link it with other works to produce a work based on this 25 file, this file does not by itself cause the resulting work to be 26 covered by the GNU General Public License. However the source code 27 for this file must still be made available in accordance with 28 section (3) of the GNU General Public License v2. 29 30 This exception does not invalidate any other reasons why a work 31 based on this file might be covered by the GNU General Public 32 License. 33 34 You should have received copies of the GNU Lesser General Public 35 License and the GNU General Public License along with this library; 36 if not, see <https://www.gnu.org/licenses/>. 37 */ 38 39 /** 40 * @file src/mhd2/mhd_sockets_macros.h 41 * @brief Various helper macros functions related to sockets 42 * @author Karlson2k (Evgeny Grin) 43 */ 44 45 #ifndef MHD_SOCKETS_MACROS_H 46 #define MHD_SOCKETS_MACROS_H 1 47 48 #include "mhd_sys_options.h" 49 50 #include "mhd_socket_type.h" 51 #include "sys_base_types.h" 52 #include "sys_sockets_headers.h" 53 54 #if defined(MHD_SOCKETS_KIND_POSIX) 55 # include "sys_errno.h" 56 # ifdef HAVE_UNISTD_H 57 # include <unistd.h> 58 # else 59 # include <stdlib.h> 60 # endif 61 # include "sys_errno.h" 62 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 63 # include <winsock2.h> 64 #endif 65 66 /** 67 * Close the socket FD 68 * @param sckt the socket to close 69 */ 70 #if defined(MHD_SOCKETS_KIND_POSIX) 71 # define mhd_socket_close(sckt) close (sckt) 72 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 73 # define mhd_socket_close(sckt) closesocket (sckt) 74 #endif 75 76 /** 77 * mhd_sys_send4 is a wrapper for system's send() 78 * @param s the socket to use 79 * @param b the buffer with data to send 80 * @param l the length of data in @a b 81 * @param f the additional flags 82 * @return ssize_t type value 83 */ 84 #ifdef MHD_SOCKETS_KIND_POSIX 85 # define mhd_sys_send4(s,b,l,f) \ 86 ((ssize_t) send ((s),(const void*) (b),(mhd_SCKT_SEND_SIZE) (l), \ 87 ((mhd_MSG_NOSIGNAL) | (f)))) 88 #else 89 # define mhd_sys_send4(s,b,l,f) \ 90 ((ssize_t) send ((s),(const char*) (b),(mhd_SCKT_SEND_SIZE) (l), \ 91 ((mhd_MSG_NOSIGNAL) | (f)))) 92 #endif 93 94 /** 95 * mhd_sys_send is a simple wrapper for system's send() 96 * @param s the socket to use 97 * @param b the buffer with data to send 98 * @param l the length of data in @a b 99 * @return ssize_t type value 100 */ 101 #define mhd_sys_send(s,b,l) mhd_sys_send4 ((s),(b),(l), 0) 102 103 104 /** 105 * mhd_recv is wrapper for system's recv() 106 * @param s the socket to use 107 * @param b the buffer for data to receive 108 * @param l the length of @a b 109 * @return ssize_t type value 110 */ 111 #ifdef MHD_SOCKETS_KIND_POSIX 112 # define mhd_sys_recv(s,b,l) \ 113 ((ssize_t) recv ((s),(void*) (b),(mhd_SCKT_SEND_SIZE) (l), 0)) 114 #else 115 # define mhd_sys_recv(s,b,l) \ 116 ((ssize_t) recv ((s),(char*) (b),(mhd_SCKT_SEND_SIZE) (l), 0)) 117 #endif 118 119 /** 120 * Last socket error 121 */ 122 #if defined(MHD_SOCKETS_KIND_POSIX) 123 # define mhd_SCKT_GET_LERR() errno 124 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 125 # define mhd_SCKT_GET_LERR() (WSAGetLastError ()) 126 #endif 127 128 /** 129 * Set last socket error 130 */ 131 #if defined(MHD_SOCKETS_KIND_POSIX) 132 # define mhd_SCKT_SET_LERR(err) do { errno = (err); } while (0) 133 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 134 # define mhd_SCKT_SET_LERR(err) WSASetLastError ((err)) 135 #endif 136 137 #if defined(MHD_SOCKETS_KIND_POSIX) 138 # if defined(EAGAIN) && defined(EWOULDBLOCK) && \ 139 ((EWOULDBLOCK + 0) != (EAGAIN + 0)) 140 # define mhd_SCKT_ERR_IS_EAGAIN(err) \ 141 ((EAGAIN == (err)) || (EWOULDBLOCK == (err))) 142 # elif defined(EAGAIN) 143 # define mhd_SCKT_ERR_IS_EAGAIN(err) (EAGAIN == (err)) 144 # elif defined(EWOULDBLOCK) 145 # define mhd_SCKT_ERR_IS_EAGAIN(err) (EWOULDBLOCK == (err)) 146 # else 147 # define mhd_SCKT_ERR_IS_EAGAIN(err) ((void) (err), ! ! 0) 148 # endif 149 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 150 # define mhd_SCKT_ERR_IS_EAGAIN(err) (WSAEWOULDBLOCK == (err)) 151 #endif 152 153 #define mhd_SCKT_LERR_IS_EAGAIN() mhd_SCKT_ERR_IS_EAGAIN (mhd_SCKT_GET_LERR ()) 154 155 #if defined(MHD_SOCKETS_KIND_POSIX) 156 # ifdef EAFNOSUPPORT 157 # define mhd_SCKT_ERR_IS_AF(err) (EAFNOSUPPORT == (err)) 158 # else 159 # define mhd_SCKT_ERR_IS_AF(err) ((void) (err), ! ! 0) 160 # endif 161 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 162 # define mhd_SCKT_ERR_IS_AF(err) (WSAEAFNOSUPPORT == (err)) 163 #endif 164 165 #define mhd_SCKT_LERR_IS_AF() mhd_SCKT_ERR_IS_AF (mhd_SCKT_GET_LERR ()) 166 167 #if defined(MHD_SOCKETS_KIND_POSIX) 168 # ifdef EINVAL 169 # define mhd_SCKT_ERR_IS_EINVAL(err) (EINVAL == (err)) 170 # else 171 # define mhd_SCKT_ERR_IS_EINVAL(err) ((void) (err), ! ! 0) 172 # endif 173 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 174 # define mhd_SCKT_ERR_IS_EINVAL(err) (WSAEINVAL == (err)) 175 #endif 176 177 #if defined(MHD_SOCKETS_KIND_POSIX) 178 # ifdef EINTR 179 # define mhd_SCKT_ERR_IS_EINTR(err) (EINTR == (err)) 180 # else 181 # define mhd_SCKT_ERR_IS_EINTR(err) ((void) (err), ! ! 0) 182 # endif 183 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 184 # define mhd_SCKT_ERR_IS_EINTR(err) (WSAEINTR == (err)) 185 #endif 186 187 #if defined(MHD_SOCKETS_KIND_POSIX) 188 # ifdef ECONNRESET 189 # define mhd_SCKT_ERR_IS_CONNRESET(err) (ECONNRESET == (err)) 190 # else 191 # define mhd_SCKT_ERR_IS_CONNRESET(err) ((void) (err), ! ! 0) 192 # endif 193 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 194 # define mhd_SCKT_ERR_IS_CONNRESET(err) (WSAECONNRESET == (err)) 195 #endif 196 197 #if defined(MHD_SOCKETS_KIND_POSIX) 198 # ifdef ENOTCONN 199 # define mhd_SCKT_ERR_IS_NOTCONN(err) (ENOTCONN == (err)) 200 # else 201 # define mhd_SCKT_ERR_IS_NOTCONNT(err) ((void) (err), ! ! 0) 202 # endif 203 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 204 # define mhd_SCKT_ERR_IS_NOTCONN(err) (WSAENOTCONN == (err)) 205 #endif 206 207 #if defined(MHD_SOCKETS_KIND_POSIX) 208 # ifdef EOPNOTSUPP 209 # define mhd_SCKT_ERR_IS_OPNOTSUPP(err) (EOPNOTSUPP == (err)) 210 # else 211 # define mhd_SCKT_ERR_IS_OPNOTSUPP(err) ((void) (err), ! ! 0) 212 # endif 213 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 214 # define mhd_SCKT_ERR_IS_OPNOTSUPP(err) (WSAEOPNOTSUPP == (err)) 215 #endif 216 217 #if defined(MHD_SOCKETS_KIND_POSIX) 218 # ifdef ENOPROTOOPT 219 # define mhd_SCKT_ERR_IS_NOPROTOOPT(err) (ENOPROTOOPT == (err)) 220 # else 221 # define mhd_SCKT_ERR_IS_NOPROTOOPT(err) ((void) (err), ! ! 0) 222 # endif 223 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 224 # define mhd_SCKT_ERR_IS_NOPROTOOPT(err) (WSAENOPROTOOPT == (err)) 225 #endif 226 227 #if defined(MHD_SOCKETS_KIND_POSIX) 228 # ifdef EBADF 229 # define mhd_SCKT_ERR_IS_BADF(err) (EBADF == (err)) 230 # else 231 # define mhd_SCKT_ERR_IS_BADF(err) ((void) (err), ! ! 0) 232 # endif 233 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 234 # define mhd_SCKT_ERR_IS_BADF(err) ((void) (err), ! ! 0) 235 #endif 236 237 #if defined(MHD_SOCKETS_KIND_POSIX) 238 # ifdef ENOTSOCK 239 # define mhd_SCKT_ERR_IS_NOTSOCK(err) (ENOTSOCK == (err)) 240 # else 241 # define mhd_SCKT_ERR_IS_NOTSOCK(err) ((void) (err), ! ! 0) 242 # endif 243 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 244 # define mhd_SCKT_ERR_IS_NOTSOCK(err) (WSAENOTSOCK == (err)) 245 #endif 246 247 #if defined(MHD_SOCKETS_KIND_POSIX) 248 # ifdef EPIPE 249 # define mhd_SCKT_ERR_IS_PIPE(err) (EPIPE == (err)) 250 # else 251 # define mhd_SCKT_ERR_IS_PIPE(err) ((void) (err), ! ! 0) 252 # endif 253 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 254 # define mhd_SCKT_ERR_IS_PIPE(err) (WSAESHUTDOWN == (err)) 255 #endif 256 257 #if defined(MHD_SOCKETS_KIND_POSIX) 258 # ifdef EINPROGRESS 259 # define mhd_SCKT_ERR_IS_INPROGRESS(err) (EINPROGRESS == (err)) 260 # else 261 # define mhd_SCKT_ERR_IS_INPROGRESS(err) ((void) (err), ! ! 0) 262 # endif 263 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 264 # define mhd_SCKT_ERR_IS_INPROGRESS(err) (WSAEINPROGRESS == (err)) 265 #endif 266 267 /** 268 * Check whether is given socket error is type of "incoming connection 269 * was disconnected before 'accept()' is called". 270 * @return boolean true is @a err match described socket error code, 271 * boolean false otherwise. 272 */ 273 #if defined(MHD_SOCKETS_KIND_POSIX) 274 # ifdef ECONNABORTED 275 # define mhd_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT(err) (ECONNABORTED == (err)) 276 # else 277 # define mhd_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT(err) ((void) (err), ! ! 0) 278 # endif 279 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 280 # define mhd_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT(err) (WSAECONNRESET == (err)) 281 #endif 282 283 /** 284 * Error for any reason when the system detects connection broke, but not 285 * because of the peer. 286 * It can be keep-alive ping failure or timeout to get ACK for the 287 * transmitted data. 288 */ 289 #if defined(MHD_SOCKETS_KIND_POSIX) 290 /* + EHOSTUNREACH: probably reported by intermediate 291 + ETIMEDOUT: probably keep-alive ping failure 292 + ENETUNREACH: probably cable physically disconnected or similar */ 293 # define mhd_SCKT_ERR_IS_CONN_BROKEN(err) \ 294 ((0 != (err)) && \ 295 ((mhd_EHOSTUNREACH_OR_ZERO == (err)) || \ 296 (mhd_ETIMEDOUT_OR_ZERO == (err)) || \ 297 (mhd_ENETUNREACH_OR_ZERO == (err)))) 298 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 299 # define mhd_SCKT_ERR_IS_CONN_BROKEN(err) \ 300 ( (WSAENETRESET == (err)) || (WSAECONNABORTED == (err)) || \ 301 (WSAETIMEDOUT == (err)) ) 302 #endif 303 304 /** 305 * Check whether given socket error is any kind of "low resource" error. 306 * @return boolean true if @a err is any kind of "low resource" error, 307 * boolean false otherwise. 308 */ 309 #if defined(MHD_SOCKETS_KIND_POSIX) 310 # define mhd_SCKT_ERR_IS_LOW_RESOURCES(err) \ 311 ((0 != (err)) && \ 312 ((mhd_EMFILE_OR_ZERO == (err)) || (mhd_ENFILE_OR_ZERO == (err)) || \ 313 (mhd_ENOMEM_OR_ZERO == (err)) || (mhd_ENOBUFS_OR_ZERO == (err)))) 314 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 315 # define mhd_SCKT_ERR_IS_LOW_RESOURCES(err) \ 316 ( (WSAEMFILE == (err)) || (WSAENOBUFS == (err)) ) 317 #endif 318 319 /** 320 * Check whether given socket error is any kind of "low memory" error. 321 * This is subset of #mhd_SCKT_ERR_IS_LOW_RESOURCES() 322 * @return boolean true if @a err is any kind of "low memory" error, 323 * boolean false otherwise. 324 */ 325 #if defined(MHD_SOCKETS_KIND_POSIX) 326 # define mhd_SCKT_ERR_IS_LOW_MEM(err) \ 327 ((0 != (err)) && \ 328 ((mhd_ENOMEM_OR_ZERO == (err)) || (mhd_ENOBUFS_OR_ZERO == (err)))) 329 #elif defined(MHD_SOCKETS_KIND_WINSOCK) 330 # define mhd_SCKT_ERR_IS_LOW_MEM(err) (WSAENOBUFS == (err)) 331 #endif 332 333 334 #if defined(MHD_SOCKETS_KIND_POSIX) 335 # ifdef HAVE_SOCKETPAIR 336 # ifdef MHD_AF_UNIX 337 # define mhd_socket_pair(fdarr_ptr) \ 338 (0 != socketpair (MHD_AF_UNIX, SOCK_STREAM, 0, (fdarr_ptr))) 339 # else 340 # define mhd_socket_pair(fdarr_ptr) \ 341 (0 != socketpair (AF_INET, SOCK_STREAM, 0, (fdarr_ptr))) /* Fallback, could be broken on many platforms */ 342 # endif 343 # if defined(HAVE_DCLR_SOCK_NONBLOCK) 344 # ifdef MHD_AF_UNIX 345 # define mhd_socket_pair_nblk(fdarr_ptr) \ 346 (0 != socketpair (MHD_AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, \ 347 (fdarr_ptr))) 348 # else 349 # define mhd_socket_pair_nblk(fdarr_ptr) \ 350 (0 != socketpair (AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0, (fdarr_ptr))) /* Fallback, could be broken on many platforms */ 351 # endif 352 # endif /* HAVE_DCLR_SOCK_NONBLOCK*/ 353 # endif /* HAVE_SOCKETPAIR */ 354 #endif 355 356 #ifndef mhd_socket_pair 357 /* mhd_socket_pair() implemented in "mhd_sockets_funcs.h" based on local function */ 358 #endif 359 360 #endif /* ! MHD_SOCKETS_MACROS_H */