Blame src/microhttpd/mhd_sockets.h

Packit 875988
/*
Packit 875988
  This file is part of libmicrohttpd
Packit 875988
  Copyright (C) 2014-2016 Karlson2k (Evgeny Grin)
Packit 875988
Packit 875988
  This library is free software; you can redistribute it and/or
Packit 875988
  modify it under the terms of the GNU Lesser General Public
Packit 875988
  License as published by the Free Software Foundation; either
Packit 875988
  version 2.1 of the License, or (at your option) any later version.
Packit 875988
Packit 875988
  This library is distributed in the hope that it will be useful,
Packit 875988
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 875988
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 875988
  Lesser General Public License for more details.
Packit 875988
Packit 875988
  You should have received a copy of the GNU Lesser General Public
Packit 875988
  License along with this library; if not, write to the Free Software
Packit 875988
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit 875988
Packit 875988
*/
Packit 875988
Packit 875988
/**
Packit 875988
 * @file microhttpd/mhd_sockets.c
Packit 875988
 * @brief  Header for platform-independent sockets abstraction
Packit 875988
 * @author Karlson2k (Evgeny Grin)
Packit 875988
 *
Packit 875988
 * Provides basic abstraction for sockets.
Packit 875988
 * Any functions can be implemented as macro on some platforms
Packit 875988
 * unless explicitly marked otherwise.
Packit 875988
 * Any function argument can be skipped in macro, so avoid
Packit 875988
 * variable modification in function parameters.
Packit 875988
 */
Packit 875988
Packit 875988
#ifndef MHD_SOCKETS_H
Packit 875988
#define MHD_SOCKETS_H 1
Packit 875988
#include "mhd_options.h"
Packit 875988
Packit 875988
#include <errno.h>
Packit 875988
Packit 875988
#if !defined(MHD_POSIX_SOCKETS) && !defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  if !defined(_WIN32) || defined(__CYGWIN__)
Packit 875988
#    define MHD_POSIX_SOCKETS 1
Packit 875988
#  else  /* defined(_WIN32) && !defined(__CYGWIN__) */
Packit 875988
#    define MHD_WINSOCK_SOCKETS 1
Packit 875988
#  endif /* defined(_WIN32) && !defined(__CYGWIN__) */
Packit 875988
#endif /* !MHD_POSIX_SOCKETS && !MHD_WINSOCK_SOCKETS */
Packit 875988
Packit 875988
/*
Packit 875988
 * MHD require headers that define socket type, socket basic functions
Packit 875988
 * (socket(), accept(), listen(), bind(), send(), recv(), select()), socket
Packit 875988
 * parameters like SOCK_CLOEXEC, SOCK_NONBLOCK, additional socket functions
Packit 875988
 * (poll(), epoll(), accept4()), struct timeval and other types, required
Packit 875988
 * for socket function.
Packit 875988
 */
Packit 875988
#if defined(MHD_POSIX_SOCKETS)
Packit 875988
#  ifdef HAVE_SYS_TYPES_H
Packit 875988
#    include <sys/types.h> /* required on old platforms */
Packit 875988
#  endif
Packit 875988
#  ifdef HAVE_SYS_SOCKET_H
Packit 875988
#    include <sys/socket.h>
Packit 875988
#  endif
Packit 875988
#  if defined(__VXWORKS__) || defined(__vxworks) || defined(OS_VXWORKS)
Packit 875988
#    ifdef HAVE_SOCKLIB_H
Packit 875988
#      include <sockLib.h>
Packit 875988
#    endif /* HAVE_SOCKLIB_H */
Packit 875988
#    ifdef HAVE_INETLIB_H
Packit 875988
#      include <inetLib.h>
Packit 875988
#    endif /* HAVE_INETLIB_H */
Packit 875988
#    include <strings.h>  /* required for FD_SET (bzero() function) */
Packit 875988
#  endif /* __VXWORKS__ || __vxworks || OS_VXWORKS */
Packit 875988
#  ifdef HAVE_NETINET_IN_H
Packit 875988
#    include <netinet/in.h>
Packit 875988
#  endif /* HAVE_NETINET_IN_H */
Packit 875988
#  ifdef HAVE_ARPA_INET_H
Packit 875988
#    include <arpa/inet.h>
Packit 875988
#  endif
Packit 875988
#  ifdef HAVE_NET_IF_H
Packit 875988
#    include <net/if.h>
Packit 875988
#  endif
Packit 875988
#  ifdef HAVE_SYS_TIME_H
Packit 875988
#    include <sys/time.h>
Packit 875988
#  endif
Packit 875988
#  ifdef HAVE_TIME_H
Packit 875988
#    include <time.h>
Packit 875988
#  endif
Packit 875988
#  ifdef HAVE_NETDB_H
Packit 875988
#    include <netdb.h>
Packit 875988
#  endif
Packit 875988
#  ifdef HAVE_SYS_SELECT_H
Packit 875988
#    include <sys/select.h>
Packit 875988
#  endif
Packit 875988
#  ifdef EPOLL_SUPPORT
Packit 875988
#    include <sys/epoll.h>
Packit 875988
#  endif
Packit 875988
#  ifdef HAVE_NETINET_TCP_H
Packit 875988
     /* for TCP_FASTOPEN and TCP_CORK */
Packit 875988
#    include <netinet/tcp.h>
Packit 875988
#  endif
Packit 875988
#  ifdef HAVE_STRING_H
Packit 875988
#    include <string.h> /* for strerror() */
Packit 875988
#  endif
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  ifndef WIN32_LEAN_AND_MEAN
Packit 875988
#    define WIN32_LEAN_AND_MEAN 1
Packit 875988
#  endif /* !WIN32_LEAN_AND_MEAN */
Packit 875988
#  include <winsock2.h>
Packit 875988
#  include <ws2tcpip.h>
Packit 875988
#endif /* MHD_WINSOCK_SOCKETS */
Packit 875988
Packit 875988
#if defined(HAVE_POLL_H) && defined(HAVE_POLL)
Packit 875988
#  include <poll.h>
Packit 875988
#endif
Packit 875988
Packit 875988
#include <stddef.h>
Packit 875988
#if defined(_MSC_FULL_VER) && !defined (_SSIZE_T_DEFINED)
Packit 875988
#  include <stdint.h>
Packit 875988
#  define _SSIZE_T_DEFINED
Packit 875988
   typedef intptr_t ssize_t;
Packit 875988
#endif /* !_SSIZE_T_DEFINED */
Packit 875988
Packit 875988
#include "mhd_limits.h"
Packit 875988
Packit 875988
#ifdef _MHD_FD_SETSIZE_IS_DEFAULT
Packit 875988
#  define _MHD_SYS_DEFAULT_FD_SETSIZE FD_SETSIZE
Packit 875988
#else  /* ! _MHD_FD_SETSIZE_IS_DEFAULT */
Packit 875988
#  include "sysfdsetsize.h"
Packit 875988
#  define _MHD_SYS_DEFAULT_FD_SETSIZE get_system_fdsetsize_value()
Packit 875988
#endif /* ! _MHD_FD_SETSIZE_IS_DEFAULT */
Packit 875988
Packit 875988
#ifndef MHD_PANIC
Packit 875988
#  include <stdio.h>
Packit 875988
#  include <stdlib.h>
Packit 875988
/* Simple implementation of MHD_PANIC, to be used outside lib */
Packit 875988
#  define MHD_PANIC(msg) do { fprintf (stderr,           \
Packit 875988
     "Abnormal termination at %d line in file %s: %s\n", \
Packit 875988
     (int)__LINE__, __FILE__, msg); abort();} while(0)
Packit 875988
#endif /* ! MHD_PANIC */
Packit 875988
Packit 875988
#ifndef MHD_SOCKET_DEFINED
Packit 875988
/**
Packit 875988
 * MHD_socket is type for socket FDs
Packit 875988
 */
Packit 875988
#  if defined(MHD_POSIX_SOCKETS)
Packit 875988
     typedef int MHD_socket;
Packit 875988
#    define MHD_INVALID_SOCKET (-1)
Packit 875988
#  elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
     typedef SOCKET MHD_socket;
Packit 875988
#    define MHD_INVALID_SOCKET (INVALID_SOCKET)
Packit 875988
#  endif /* MHD_WINSOCK_SOCKETS */
Packit 875988
Packit 875988
#  define MHD_SOCKET_DEFINED 1
Packit 875988
#endif /* ! MHD_SOCKET_DEFINED */
Packit 875988
Packit 875988
#ifdef SOCK_CLOEXEC
Packit 875988
#  define MAYBE_SOCK_CLOEXEC SOCK_CLOEXEC
Packit 875988
#else  /* ! SOCK_CLOEXEC */
Packit 875988
#  define MAYBE_SOCK_CLOEXEC 0
Packit 875988
#endif /* ! SOCK_CLOEXEC */
Packit 875988
Packit 875988
#ifdef HAVE_SOCK_NONBLOCK
Packit 875988
#  define MAYBE_SOCK_NONBLOCK SOCK_NONBLOCK
Packit 875988
#else  /* ! HAVE_SOCK_NONBLOCK */
Packit 875988
#  define MAYBE_SOCK_NONBLOCK 0
Packit 875988
#endif /* ! HAVE_SOCK_NONBLOCK */
Packit 875988
Packit 875988
#ifdef MSG_NOSIGNAL
Packit 875988
#  define MAYBE_MSG_NOSIGNAL MSG_NOSIGNAL
Packit 875988
#else  /* ! MSG_NOSIGNAL */
Packit 875988
#  define MAYBE_MSG_NOSIGNAL 0
Packit 875988
#endif /* ! MSG_NOSIGNAL */
Packit 875988
Packit 875988
#if !defined(SHUT_WR) && defined(SD_SEND)
Packit 875988
#  define SHUT_WR SD_SEND
Packit 875988
#endif
Packit 875988
#if !defined(SHUT_RD) && defined(SD_RECEIVE)
Packit 875988
#  define SHUT_RD SD_RECEIVE
Packit 875988
#endif
Packit 875988
#if !defined(SHUT_RDWR) && defined(SD_BOTH)
Packit 875988
#  define SHUT_RDWR SD_BOTH
Packit 875988
#endif
Packit 875988
Packit 875988
#if HAVE_ACCEPT4+0 != 0 && (defined(HAVE_SOCK_NONBLOCK) || defined(SOCK_CLOEXEC))
Packit 875988
#  define USE_ACCEPT4 1
Packit 875988
#endif
Packit 875988
Packit 875988
#if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC)
Packit 875988
#  define USE_EPOLL_CREATE1 1
Packit 875988
#endif /* HAVE_EPOLL_CREATE1 && EPOLL_CLOEXEC */
Packit 875988
Packit 875988
#ifdef TCP_FASTOPEN
Packit 875988
/**
Packit 875988
 * Default TCP fastopen queue size.
Packit 875988
 */
Packit 875988
#define MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT 10
Packit 875988
#endif
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_SCKT_OPT_BOOL_ is type for bool parameters for setsockopt()/getsockopt()
Packit 875988
 */
Packit 875988
#ifdef MHD_POSIX_SOCKETS
Packit 875988
  typedef int MHD_SCKT_OPT_BOOL_;
Packit 875988
#else /* MHD_WINSOCK_SOCKETS */
Packit 875988
  typedef BOOL MHD_SCKT_OPT_BOOL_;
Packit 875988
#endif /* MHD_WINSOCK_SOCKETS */
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_SCKT_SEND_SIZE_ is type used to specify size for send and recv
Packit 875988
 * functions
Packit 875988
 */
Packit 875988
#if !defined(MHD_WINSOCK_SOCKETS)
Packit 875988
  typedef size_t MHD_SCKT_SEND_SIZE_;
Packit 875988
#else
Packit 875988
  typedef int MHD_SCKT_SEND_SIZE_;
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_SCKT_SEND_MAX_SIZE_ is maximum send()/recv() size value.
Packit 875988
 */
Packit 875988
#if !defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_SCKT_SEND_MAX_SIZE_ SSIZE_MAX
Packit 875988
#else
Packit 875988
#  define MHD_SCKT_SEND_MAX_SIZE_ INT_MAX
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_socket_close_(fd) close any FDs (non-W32) / close only socket
Packit 875988
 * FDs (W32).  Note that on HP-UNIX, this function may leak the FD if
Packit 875988
 * errno is set to EINTR.  Do not use HP-UNIX.
Packit 875988
 *
Packit 875988
 * @param fd descriptor to close
Packit 875988
 * @return boolean true on success (error codes like EINTR and EIO are
Packit 875988
 *         counted as success, only EBADF counts as an error!),
Packit 875988
 *         boolean false otherwise.
Packit 875988
 */
Packit 875988
#if !defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_socket_close_(fd) ((0 == close((fd))) || (EBADF != errno))
Packit 875988
#else
Packit 875988
#  define MHD_socket_close_(fd) (0 == closesocket((fd)))
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_socket_close_chk_(fd) close socket and abort execution
Packit 875988
 * if error is detected.
Packit 875988
 * @param fd socket to close
Packit 875988
 */
Packit 875988
#define MHD_socket_close_chk_(fd) do {        \
Packit 875988
    if (!MHD_socket_close_(fd))               \
Packit 875988
      MHD_PANIC(_("Close socket failed.\n")); \
Packit 875988
  } while(0)
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_send_ is wrapper for system's send()
Packit 875988
 * @param s the socket to use
Packit 875988
 * @param b the buffer with data to send
Packit 875988
 * @param l the length of data in @a b
Packit 875988
 * @return ssize_t type value
Packit 875988
 */
Packit 875988
#define MHD_send_(s,b,l) \
Packit 875988
  ((ssize_t)send((s),(const void*)(b),((MHD_SCKT_SEND_SIZE_)l), MAYBE_MSG_NOSIGNAL))
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_recv_ is wrapper for system's recv()
Packit 875988
 * @param s the socket to use
Packit 875988
 * @param b the buffer for data to receive
Packit 875988
 * @param l the length of @a b
Packit 875988
 * @return ssize_t type value
Packit 875988
 */
Packit 875988
#define MHD_recv_(s,b,l) \
Packit 875988
  ((ssize_t)recv((s),(void*)(b),((MHD_SCKT_SEND_SIZE_)l), 0))
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether FD can be added to fd_set with specified FD_SETSIZE.
Packit 875988
 * @param fd   the fd to check
Packit 875988
 * @param pset the pointer to fd_set to check or NULL to check
Packit 875988
 *             whether FD can be used with fd_sets.
Packit 875988
 * @param setsize the value of FD_SETSIZE.
Packit 875988
 * @return boolean true if FD can be added to fd_set,
Packit 875988
 *         boolean false otherwise.
Packit 875988
 */
Packit 875988
#if defined(MHD_POSIX_SOCKETS)
Packit 875988
#  define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ((fd) < ((MHD_socket)setsize))
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd,pset,setsize) ( ((void*)(pset)==(void*)0) || \
Packit 875988
                                                             (((fd_set*)(pset))->fd_count < ((unsigned)setsize)) || \
Packit 875988
                                                             (FD_ISSET((fd),(pset))) )
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether FD can be added to fd_set with current FD_SETSIZE.
Packit 875988
 * @param fd   the fd to check
Packit 875988
 * @param pset the pointer to fd_set to check or NULL to check
Packit 875988
 *             whether FD can be used with fd_sets.
Packit 875988
 * @return boolean true if FD can be added to fd_set,
Packit 875988
 *         boolean false otherwise.
Packit 875988
 */
Packit 875988
#define MHD_SCKT_FD_FITS_FDSET_(fd,pset) MHD_SCKT_FD_FITS_FDSET_SETSIZE_((fd),(pset),FD_SETSIZE)
Packit 875988
Packit 875988
/**
Packit 875988
 * Add FD to fd_set with specified FD_SETSIZE.
Packit 875988
 * @param fd   the fd to add
Packit 875988
 * @param pset the valid pointer to fd_set.
Packit 875988
 * @param setsize the value of FD_SETSIZE.
Packit 875988
 * @note  To work on W32 with value of FD_SETSIZE different from currently defined value,
Packit 875988
 *        system definition of FD_SET() is not used.
Packit 875988
 */
Packit 875988
#if defined(MHD_POSIX_SOCKETS)
Packit 875988
#  define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize) FD_SET((fd),(pset))
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd,pset,setsize)                     \
Packit 875988
        do {                                                                     \
Packit 875988
           u_int _i_ = 0;                                                        \
Packit 875988
           fd_set* const _s_ = (fd_set*)(pset);                                  \
Packit 875988
           while((_i_ < _s_->fd_count) && ((fd) != _s_->fd_array[_i_])) {++_i_;} \
Packit 875988
           if ((_i_ == _s_->fd_count)) {_s_->fd_array[_s_->fd_count++] = (fd);}  \
Packit 875988
        } while(0)
Packit 875988
#endif
Packit 875988
Packit 875988
 /* MHD_SYS_select_ is wrapper macro for system select() function */
Packit 875988
#if !defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t))
Packit 875988
#else
Packit 875988
#  define MHD_SYS_select_(n,r,w,e,t) \
Packit 875988
( ( (((void*)(r) == (void*)0) || ((fd_set*)(r))->fd_count == 0) &&  \
Packit 875988
    (((void*)(w) == (void*)0) || ((fd_set*)(w))->fd_count == 0) &&  \
Packit 875988
    (((void*)(e) == (void*)0) || ((fd_set*)(e))->fd_count == 0) ) ? \
Packit 875988
  ( ((void*)(t) == (void*)0) ? 0 :                                  \
Packit 875988
    (Sleep(((struct timeval*)(t))->tv_sec * 1000 +                  \
Packit 875988
           ((struct timeval*)(t))->tv_usec / 1000), 0) ) :          \
Packit 875988
  (select((int)0,(r),(w),(e),(t))) )
Packit 875988
#endif
Packit 875988
Packit 875988
#if defined(HAVE_POLL)
Packit 875988
/* MHD_sys_poll_ is wrapper macro for system poll() function */
Packit 875988
#  if !defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#    define MHD_sys_poll_ poll
Packit 875988
#  else  /* MHD_WINSOCK_SOCKETS */
Packit 875988
#    define MHD_sys_poll_ WSAPoll
Packit 875988
#  endif /* MHD_WINSOCK_SOCKETS */
Packit 875988
Packit 875988
#  ifdef POLLPRI
Packit 875988
#    define MHD_POLLPRI_OR_ZERO POLLPRI
Packit 875988
#  else  /* ! POLLPRI */
Packit 875988
#    define MHD_POLLPRI_OR_ZERO 0
Packit 875988
#  endif /* ! POLLPRI */
Packit 875988
#  ifdef POLLRDBAND
Packit 875988
#    define MHD_POLLRDBAND_OR_ZERO POLLRDBAND
Packit 875988
#  else  /* ! POLLRDBAND */
Packit 875988
#    define MHD_POLLRDBAND_OR_ZERO 0
Packit 875988
#  endif /* ! POLLRDBAND */
Packit 875988
#  ifdef POLLNVAL
Packit 875988
#    define MHD_POLLNVAL_OR_ZERO POLLNVAL
Packit 875988
#  else  /* ! POLLNVAL */
Packit 875988
#    define MHD_POLLNVAL_OR_ZERO 0
Packit 875988
#  endif /* ! POLLNVAL */
Packit 875988
Packit 875988
/* MHD_POLL_EVENTS_ERR_DISC is 'events' mask for errors and disconnect.
Packit 875988
 * Note: Out-of-band data is treated as error. */
Packit 875988
#  if defined(_WIN32) && ! defined(__CYGWIN__)
Packit 875988
#    define MHD_POLL_EVENTS_ERR_DISC POLLRDBAND
Packit 875988
#  elif defined(__linux__)
Packit 875988
#    define MHD_POLL_EVENTS_ERR_DISC POLLPRI
Packit 875988
#  else /* ! __linux__ */
Packit 875988
#    define MHD_POLL_EVENTS_ERR_DISC (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO)
Packit 875988
#  endif /* ! __linux__ */
Packit 875988
/* MHD_POLL_REVENTS_ERR_DISC is 'revents' mask for errors and disconnect.
Packit 875988
 * Note: Out-of-band data is treated as error. */
Packit 875988
#  define MHD_POLL_REVENTS_ERR_DISC \
Packit 875988
     (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR | POLLHUP)
Packit 875988
/* MHD_POLL_REVENTS_ERRROR is 'revents' mask for errors.
Packit 875988
 * Note: Out-of-band data is treated as error. */
Packit 875988
#  define MHD_POLL_REVENTS_ERRROR \
Packit 875988
     (MHD_POLLPRI_OR_ZERO | MHD_POLLRDBAND_OR_ZERO | MHD_POLLNVAL_OR_ZERO | POLLERR)
Packit 875988
#endif /* HAVE_POLL */
Packit 875988
Packit 875988
#define MHD_SCKT_MISSING_ERR_CODE_ 31450
Packit 875988
Packit 875988
#if defined(MHD_POSIX_SOCKETS)
Packit 875988
#  if defined(EAGAIN)
Packit 875988
#    define MHD_SCKT_EAGAIN_      EAGAIN
Packit 875988
#  elif defined(EWOULDBLOCK)
Packit 875988
#    define MHD_SCKT_EAGAIN_      EWOULDBLOCK
Packit 875988
#  else  /* !EAGAIN && !EWOULDBLOCK */
Packit 875988
#    define MHD_SCKT_EAGAIN_      MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* !EAGAIN && !EWOULDBLOCK */
Packit 875988
#  if defined(EWOULDBLOCK)
Packit 875988
#    define MHD_SCKT_EWOULDBLOCK_ EWOULDBLOCK
Packit 875988
#  elif defined(EAGAIN)
Packit 875988
#    define MHD_SCKT_EWOULDBLOCK_ EAGAIN
Packit 875988
#  else  /* !EWOULDBLOCK && !EAGAIN */
Packit 875988
#    define MHD_SCKT_EWOULDBLOCK_ MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* !EWOULDBLOCK && !EAGAIN */
Packit 875988
#  ifdef EINTR
Packit 875988
#    define MHD_SCKT_EINTR_       EINTR
Packit 875988
#  else  /* ! EINTR */
Packit 875988
#    define MHD_SCKT_EINTR_       MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! EINTR */
Packit 875988
#  ifdef ECONNRESET
Packit 875988
#    define MHD_SCKT_ECONNRESET_  ECONNRESET
Packit 875988
#  else  /* ! ECONNRESET */
Packit 875988
#    define MHD_SCKT_ECONNRESET_  MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ECONNRESET */
Packit 875988
#  ifdef ECONNABORTED
Packit 875988
#    define MHD_SCKT_ECONNABORTED_  ECONNABORTED
Packit 875988
#  else  /* ! ECONNABORTED */
Packit 875988
#    define MHD_SCKT_ECONNABORTED_  MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ECONNABORTED */
Packit 875988
#  ifdef ENOTCONN
Packit 875988
#    define MHD_SCKT_ENOTCONN_    ENOTCONN
Packit 875988
#  else  /* ! ENOTCONN */
Packit 875988
#    define MHD_SCKT_ENOTCONN_    MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ENOTCONN */
Packit 875988
#  ifdef EMFILE
Packit 875988
#    define MHD_SCKT_EMFILE_      EMFILE
Packit 875988
#  else  /* ! EMFILE */
Packit 875988
#    define MHD_SCKT_EMFILE_      MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! EMFILE */
Packit 875988
#  ifdef ENFILE
Packit 875988
#    define MHD_SCKT_ENFILE_      ENFILE
Packit 875988
#  else  /* ! ENFILE */
Packit 875988
#    define MHD_SCKT_ENFILE_      MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ENFILE */
Packit 875988
#  ifdef ENOMEM
Packit 875988
#    define MHD_SCKT_ENOMEM_      ENOMEM
Packit 875988
#  else  /* ! ENOMEM */
Packit 875988
#    define MHD_SCKT_ENOMEM_      MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ENOMEM */
Packit 875988
#  ifdef ENOBUFS
Packit 875988
#    define MHD_SCKT_ENOBUFS_     ENOBUFS
Packit 875988
#  else  /* ! ENOBUFS */
Packit 875988
#    define MHD_SCKT_ENOBUFS_     MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ENOBUFS */
Packit 875988
#  ifdef EBADF
Packit 875988
#    define MHD_SCKT_EBADF_       EBADF
Packit 875988
#  else  /* ! EBADF */
Packit 875988
#    define MHD_SCKT_EBADF_       MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! EBADF */
Packit 875988
#  ifdef ENOTSOCK
Packit 875988
#    define MHD_SCKT_ENOTSOCK_    ENOTSOCK
Packit 875988
#  else  /* ! ENOTSOCK */
Packit 875988
#    define MHD_SCKT_ENOTSOCK_    MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ENOTSOCK */
Packit 875988
#  ifdef EINVAL
Packit 875988
#    define MHD_SCKT_EINVAL_      EINVAL
Packit 875988
#  else  /* ! EINVAL */
Packit 875988
#    define MHD_SCKT_EINVAL_      MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! EINVAL */
Packit 875988
#  ifdef EFAULT
Packit 875988
#    define MHD_SCKT_EFAUL_       EFAULT
Packit 875988
#  else  /* ! EFAULT */
Packit 875988
#    define MHD_SCKT_EFAUL_       MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! EFAULT */
Packit 875988
#  ifdef ENOSYS
Packit 875988
#    define MHD_SCKT_ENOSYS_      ENOSYS
Packit 875988
#  else  /* ! ENOSYS */
Packit 875988
#    define MHD_SCKT_ENOSYS_      MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ENOSYS */
Packit 875988
#  ifdef ENOTSUP
Packit 875988
#    define MHD_SCKT_ENOTSUP_     ENOTSUP
Packit 875988
#  else  /* ! ENOTSUP */
Packit 875988
#    define MHD_SCKT_ENOTSUP_     MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ENOTSUP */
Packit 875988
#  ifdef EOPNOTSUPP
Packit 875988
#    define MHD_SCKT_EOPNOTSUPP_  EOPNOTSUPP
Packit 875988
#  else  /* ! EOPNOTSUPP */
Packit 875988
#    define MHD_SCKT_EOPNOTSUPP_  MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! EOPNOTSUPP */
Packit 875988
#  ifdef EACCES
Packit 875988
#    define MHD_SCKT_EACCESS_     EACCES
Packit 875988
#  else  /* ! EACCES */
Packit 875988
#    define MHD_SCKT_EACCESS_     MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! EACCES */
Packit 875988
#  ifdef ENETDOWN
Packit 875988
#    define MHD_SCKT_ENETDOWN_    ENETDOWN
Packit 875988
#  else  /* ! ENETDOWN */
Packit 875988
#    define MHD_SCKT_ENETDOWN_    MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  endif /* ! ENETDOWN */
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_SCKT_EAGAIN_        WSAEWOULDBLOCK
Packit 875988
#  define MHD_SCKT_EWOULDBLOCK_   WSAEWOULDBLOCK
Packit 875988
#  define MHD_SCKT_EINTR_         WSAEINTR
Packit 875988
#  define MHD_SCKT_ECONNRESET_    WSAECONNRESET
Packit 875988
#  define MHD_SCKT_ECONNABORTED_  WSAECONNABORTED
Packit 875988
#  define MHD_SCKT_ENOTCONN_      WSAENOTCONN
Packit 875988
#  define MHD_SCKT_EMFILE_        WSAEMFILE
Packit 875988
#  define MHD_SCKT_ENFILE_        MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  define MHD_SCKT_ENOMEM_        MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  define MHD_SCKT_ENOBUFS_       WSAENOBUFS
Packit 875988
#  define MHD_SCKT_EBADF_         WSAEBADF
Packit 875988
#  define MHD_SCKT_ENOTSOCK_      WSAENOTSOCK
Packit 875988
#  define MHD_SCKT_EINVAL_        WSAEINVAL
Packit 875988
#  define MHD_SCKT_EFAUL_         WSAEFAULT
Packit 875988
#  define MHD_SCKT_ENOSYS_        MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  define MHD_SCKT_ENOTSUP_       MHD_SCKT_MISSING_ERR_CODE_
Packit 875988
#  define MHD_SCKT_EOPNOTSUPP_    WSAEOPNOTSUPP
Packit 875988
#  define MHD_SCKT_EACCESS_       WSAEACCES
Packit 875988
#  define MHD_SCKT_ENETDOWN_      WSAENETDOWN
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_socket_error_ return system native error code for last socket error.
Packit 875988
 * @return system error code for last socket error.
Packit 875988
 */
Packit 875988
#if defined(MHD_POSIX_SOCKETS)
Packit 875988
#  define MHD_socket_get_error_() (errno)
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_socket_get_error_() WSAGetLastError()
Packit 875988
#endif
Packit 875988
Packit 875988
#ifdef MHD_WINSOCK_SOCKETS
Packit 875988
  /* POSIX-W32 sockets compatibility functions */
Packit 875988
Packit 875988
/**
Packit 875988
 * Return pointer to string description of specified WinSock error
Packit 875988
 * @param err the WinSock error code.
Packit 875988
 * @return pointer to string description of specified WinSock error.
Packit 875988
 */
Packit 875988
  const char* MHD_W32_strerror_winsock_(int err);
Packit 875988
#endif /* MHD_WINSOCK_SOCKETS */
Packit 875988
Packit 875988
/* MHD_socket_last_strerr_ is description string of specified socket error code */
Packit 875988
#if defined(MHD_POSIX_SOCKETS)
Packit 875988
#  define MHD_socket_strerr_(err) strerror((err))
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_((err))
Packit 875988
#endif
Packit 875988
Packit 875988
/* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
Packit 875988
 *                            description string of last socket error (W32) */
Packit 875988
#define MHD_socket_last_strerr_() MHD_socket_strerr_(MHD_socket_get_error_())
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_socket_fset_error_() set socket system native error code.
Packit 875988
 */
Packit 875988
#if defined(MHD_POSIX_SOCKETS)
Packit 875988
#  define MHD_socket_fset_error_(err) (errno = (err))
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_socket_fset_error_(err) (WSASetLastError((err)))
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_socket_try_set_error_() set socket system native error code if
Packit 875988
 * specified code is defined on system.
Packit 875988
 * @return non-zero if specified @a err code is defined on system
Packit 875988
 *         and error was set;
Packit 875988
 *         zero if specified @a err code is not defined on system
Packit 875988
 *         and error was not set.
Packit 875988
 */
Packit 875988
#define MHD_socket_try_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \
Packit 875988
                                         (MHD_socket_fset_error_((err)), !0) : 0 )
Packit 875988
Packit 875988
/**
Packit 875988
 * MHD_socket_set_error_() set socket system native error code to
Packit 875988
 * specified code or replacement code if specified code is not
Packit 875988
 * defined on system.
Packit 875988
 */
Packit 875988
#if defined(MHD_POSIX_SOCKETS)
Packit 875988
#  if defined(ENOSYS)
Packit 875988
#    define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
Packit 875988
                                         (errno = ENOSYS) : (errno = (err)) )
Packit 875988
#  elif defined(EOPNOTSUPP)
Packit 875988
#    define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
Packit 875988
                                         (errno = EOPNOTSUPP) : (errno = (err)) )
Packit 875988
#  elif defined (EFAULT)
Packit 875988
#    define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
Packit 875988
                                         (errno = EFAULT) : (errno = (err)) )
Packit 875988
#  elif defined (EINVAL)
Packit 875988
#    define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
Packit 875988
                                         (errno = EINVAL) : (errno = (err)) )
Packit 875988
#  else  /* !EOPNOTSUPP && !EFAULT && !EINVAL */
Packit 875988
#    warning No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system.
Packit 875988
#    define MHD_socket_set_error_(err) (errno = (err))
Packit 875988
#  endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
Packit 875988
                                       (WSASetLastError((WSAEOPNOTSUPP))) : \
Packit 875988
                                       (WSASetLastError((err))) )
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether given socket error is equal to specified system
Packit 875988
 * native MHD_SCKT_E*_ code.
Packit 875988
 * If platform don't have specific error code, result is
Packit 875988
 * always boolean false.
Packit 875988
 * @return boolean true if @a code is real error code and
Packit 875988
 *         @a err equals to MHD_SCKT_E*_ @a code;
Packit 875988
 *         boolean false otherwise
Packit 875988
 */
Packit 875988
#define MHD_SCKT_ERR_IS_(err,code) ( (MHD_SCKT_MISSING_ERR_CODE_ != (code)) && \
Packit 875988
                                     ((code) == (err)) )
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether last socket error is equal to specified system
Packit 875988
 * native MHD_SCKT_E*_ code.
Packit 875988
 * If platform don't have specific error code, result is
Packit 875988
 * always boolean false.
Packit 875988
 * @return boolean true if @a code is real error code and
Packit 875988
 *         last socket error equals to MHD_SCKT_E*_ @a code;
Packit 875988
 *         boolean false otherwise
Packit 875988
 */
Packit 875988
#define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_(MHD_socket_get_error_() ,(code))
Packit 875988
Packit 875988
/* Specific error code checks */
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether given socket error is equal to system's
Packit 875988
 * socket error codes for EINTR.
Packit 875988
 * @return boolean true if @a err is equal to sockets' EINTR code;
Packit 875988
 *         boolean false otherwise.
Packit 875988
 */
Packit 875988
#define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EINTR_)
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether given socket error is equal to system's
Packit 875988
 * socket error codes for EAGAIN or EWOULDBLOCK.
Packit 875988
 * @return boolean true if @a err is equal to sockets' EAGAIN or EWOULDBLOCK codes;
Packit 875988
 *         boolean false otherwise.
Packit 875988
 */
Packit 875988
#if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_
Packit 875988
#  define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_)
Packit 875988
#else  /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
Packit 875988
#  define MHD_SCKT_ERR_IS_EAGAIN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_) || \
Packit 875988
                                         MHD_SCKT_ERR_IS_((err),MHD_SCKT_EWOULDBLOCK_) )
Packit 875988
#endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether given socket error is any kind of "low resource" error.
Packit 875988
 * @return boolean true if @a err is any kind of "low resource" error,
Packit 875988
 *         boolean false otherwise.
Packit 875988
 */
Packit 875988
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EMFILE_) || \
Packit 875988
                                              MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENFILE_) || \
Packit 875988
                                              MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOMEM_) || \
Packit 875988
                                              MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOBUFS_) )
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether is given socket error is type of "incoming connection
Packit 875988
 * was disconnected before 'accept()' is called".
Packit 875988
 * @return boolean true is @a err match described socket error code,
Packit 875988
 *         boolean false otherwise.
Packit 875988
 */
Packit 875988
#if defined(MHD_POSIX_SOCKETS)
Packit 875988
#  define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_)
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
#  define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_)
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * Check whether is given socket error is type of "connection was terminated
Packit 875988
 * by remote side".
Packit 875988
 * @return boolean true is @a err match described socket error code,
Packit 875988
 *         boolean false otherwise.
Packit 875988
 */
Packit 875988
#define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_) || \
Packit 875988
                                              MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_))
Packit 875988
Packit 875988
/* Specific error code set */
Packit 875988
Packit 875988
/**
Packit 875988
 * Set socket's error code to ENOMEM or equivalent if ENOMEM is not
Packit 875988
 * available on platform.
Packit 875988
 */
Packit 875988
#if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_
Packit 875988
#  define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_)
Packit 875988
#elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_
Packit 875988
#  define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOBUFS_)
Packit 875988
#else
Packit 875988
#  warning No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system.
Packit 875988
#  define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_)
Packit 875988
#endif
Packit 875988
Packit 875988
/* Socket functions */
Packit 875988
Packit 875988
#if defined(AF_LOCAL)
Packit 875988
#  define MHD_SCKT_LOCAL AF_LOCAL
Packit 875988
#elif defined(AF_UNIX)
Packit 875988
#  define MHD_SCKT_LOCAL AF_UNIX
Packit 875988
#endif /* AF_UNIX */
Packit 875988
Packit 875988
#if defined(MHD_POSIX_SOCKETS) && defined(MHD_SCKT_LOCAL)
Packit 875988
#  define MHD_socket_pair_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM, 0, (fdarr)))
Packit 875988
#  if defined(HAVE_SOCK_NONBLOCK)
Packit 875988
#    define MHD_socket_pair_nblk_(fdarr) (!socketpair(MHD_SCKT_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0, (fdarr)))
Packit 875988
#  endif /* HAVE_SOCK_NONBLOCK*/
Packit 875988
#elif defined(MHD_WINSOCK_SOCKETS)
Packit 875988
   /**
Packit 875988
    * Create pair of mutually connected TCP/IP sockets on loopback address
Packit 875988
    * @param sockets_pair array to receive resulted sockets
Packit 875988
    * @param non_blk if set to non-zero value, sockets created in non-blocking mode
Packit 875988
    *                otherwise sockets will be in blocking mode
Packit 875988
    * @return non-zero if succeeded, zero otherwise
Packit 875988
    */
Packit 875988
   int MHD_W32_socket_pair_(SOCKET sockets_pair[2], int non_blk);
Packit 875988
Packit 875988
#  define MHD_socket_pair_(fdarr) MHD_W32_socket_pair_((fdarr), 0)
Packit 875988
#  define MHD_socket_pair_nblk_(fdarr) MHD_W32_socket_pair_((fdarr), 1)
Packit 875988
#endif
Packit 875988
Packit 875988
/**
Packit 875988
 * Add @a fd to the @a set.  If @a fd is
Packit 875988
 * greater than @a max_fd, set @a max_fd to @a fd.
Packit 875988
 *
Packit 875988
 * @param fd file descriptor to add to the @a set
Packit 875988
 * @param set set to modify
Packit 875988
 * @param max_fd maximum value to potentially update
Packit 875988
 * @param fd_setsize value of FD_SETSIZE
Packit 875988
 * @return non-zero if succeeded, zero otherwise
Packit 875988
 */
Packit 875988
int
Packit 875988
MHD_add_to_fd_set_ (MHD_socket fd,
Packit 875988
                    fd_set *set,
Packit 875988
                    MHD_socket *max_fd,
Packit 875988
                    unsigned int fd_setsize);
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Change socket options to be non-blocking.
Packit 875988
 *
Packit 875988
 * @param sock socket to manipulate
Packit 875988
 * @return non-zero if succeeded, zero otherwise
Packit 875988
 */
Packit 875988
int
Packit 875988
MHD_socket_nonblocking_ (MHD_socket sock);
Packit 875988
Packit 875988
Packit 875988
/**
Packit 875988
 * Change socket options to be non-inheritable.
Packit 875988
 *
Packit 875988
 * @param sock socket to manipulate
Packit 875988
 * @return non-zero if succeeded, zero otherwise
Packit 875988
 * @warning Does not set socket error on W32.
Packit 875988
 */
Packit 875988
int
Packit 875988
MHD_socket_noninheritable_ (MHD_socket sock);
Packit 875988
Packit 875988
Packit 875988
#if defined(SOL_SOCKET) && defined(SO_NOSIGPIPE)
Packit 875988
   static const int _MHD_socket_int_one = 1;
Packit 875988
/**
Packit 875988
 * Change socket options to no signal on remote disconnect.
Packit 875988
 *
Packit 875988
 * @param sock socket to manipulate
Packit 875988
 * @return non-zero if succeeded, zero otherwise
Packit 875988
 */
Packit 875988
#  define MHD_socket_nosignal_(sock) \
Packit 875988
    (!setsockopt((sock),SOL_SOCKET,SO_NOSIGPIPE,&_MHD_socket_int_one,sizeof(_MHD_socket_int_one)))
Packit 875988
#endif /* SOL_SOCKET && SO_NOSIGPIPE */
Packit 875988
Packit 875988
/**
Packit 875988
 * Create a listen socket, with noninheritable flag if possible.
Packit 875988
 *
Packit 875988
 * @param use_ipv6 if set to non-zero IPv6 is used
Packit 875988
 * @return created socket or MHD_INVALID_SOCKET in case of errors
Packit 875988
 */
Packit 875988
MHD_socket
Packit 875988
MHD_socket_create_listen_ (int use_ipv6);
Packit 875988
Packit 875988
#endif /* ! MHD_SOCKETS_H */