libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

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 */