add platform abstraction for errno and strerror, check EWOULDBLOCK additionally to EAGAIN

This commit is contained in:
Evgeny Grin (Karlson2k) committed 2014-02-18 18:38:21 +00:00
1 parent 4e0abfce9e
commit c443fe60fd
9 files changed
+834 -62

No files matched your search

+5 -1
View File
@@ -2,6 +2,10 @@ if USE_PRIVATE_PLIBC_H
PLIBC_INCLUDE = -I$(top_srcdir)/src/include/plibc
endif
if HAVE_W32
W32FUNC_SRC = ../platform/w32functions.c ../platform/w32functions.h
endif
AM_CPPFLAGS = \
$(PLIBC_INCLUDE) \
-I$(top_srcdir)/src/include \
@@ -22,7 +26,7 @@ libmicrohttpd_la_SOURCES = \
internal.c internal.h \
memorypool.c memorypool.h \
response.c response.h \
../platform/platform_interface.h
../platform/platform_interface.h $(W32FUNC_SRC)
libmicrohttpd_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
-DBUILDING_MHD_LIB=1
+14 -9
View File
@@ -1583,7 +1583,9 @@ do_read (struct MHD_Connection *connection)
connection->read_buffer_offset);
if (bytes_read < 0)
{
if ((EINTR == errno) || (EAGAIN == errno) || (ECONNRESET == errno))
const int err = MHD_socket_errno_;
if ((EINTR == err) || (EAGAIN == err) || (ECONNRESET == err)
|| (EWOULDBLOCK == err))
return MHD_NO;
#if HAVE_MESSAGES
#if HTTPS_SUPPORT
@@ -1595,7 +1597,7 @@ do_read (struct MHD_Connection *connection)
#endif
MHD_DLOG (connection->daemon,
"Failed to receive data: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
CONNECTION_CLOSE_ERROR (connection, NULL);
return MHD_YES;
@@ -1636,7 +1638,8 @@ do_write (struct MHD_Connection *connection)
if (ret < 0)
{
if ((EINTR == errno) || (EAGAIN == errno))
const int err = MHD_socket_errno_;
if ((EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err))
return MHD_NO;
#if HAVE_MESSAGES
#if HTTPS_SUPPORT
@@ -1647,7 +1650,7 @@ do_write (struct MHD_Connection *connection)
else
#endif
MHD_DLOG (connection->daemon,
"Failed to send data: %s\n", STRERROR (errno));
"Failed to send data: %s\n", MHD_socket_last_strerr_ ());
#endif
CONNECTION_CLOSE_ERROR (connection, NULL);
return MHD_YES;
@@ -2022,12 +2025,13 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
connection->continue_message_write_offset);
if (ret < 0)
{
if ((errno == EINTR) || (errno == EAGAIN))
const int err = MHD_socket_errno_;
if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err))
break;
#if HAVE_MESSAGES
MHD_DLOG (connection->daemon,
"Failed to send data: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
CONNECTION_CLOSE_ERROR (connection, NULL);
return MHD_YES;
@@ -2068,6 +2072,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
response->data_size -
(connection->response_write_position
- response->data_start));
const int err = MHD_socket_errno_;
#if DEBUG_SEND_DATA
if (ret > 0)
FPRINTF (stderr,
@@ -2080,12 +2085,12 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
pthread_mutex_unlock (&response->mutex);
if (ret < 0)
{
if ((errno == EINTR) || (errno == EAGAIN))
if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err))
return MHD_YES;
#if HAVE_MESSAGES
MHD_DLOG (connection->daemon,
"Failed to send data: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
CONNECTION_CLOSE_ERROR (connection, NULL);
return MHD_YES;
@@ -2658,7 +2663,7 @@ MHD_connection_epoll_update_ (struct MHD_Connection *connection)
if (0 != (daemon->options & MHD_USE_DEBUG))
MHD_DLOG (daemon,
"Call to epoll_ctl failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
connection->state = MHD_CONNECTION_CLOSED;
cleanup_connection (connection);
+50 -50
View File
@@ -25,7 +25,6 @@
* @author Christian Grothoff
*/
#include "platform.h"
#include "platform_interface.h"
#include "internal.h"
#include "response.h"
#include "connection.h"
@@ -409,7 +408,7 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
if ( (GNUTLS_E_AGAIN == res) ||
(GNUTLS_E_INTERRUPTED == res) )
{
errno = EINTR;
MHD_set_socket_errno_ (EINTR);
#if EPOLL_SUPPORT
connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
#endif
@@ -420,7 +419,7 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
/* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
disrupted); set errno to something caller will interpret
correctly as a hard error */
errno = EPIPE;
MHD_set_socket_errno_ (ECONNRESET);
return res;
}
if (res == i)
@@ -450,7 +449,7 @@ send_tls_adapter (struct MHD_Connection *connection,
if ( (GNUTLS_E_AGAIN == res) ||
(GNUTLS_E_INTERRUPTED == res) )
{
errno = EINTR;
MHD_set_socket_errno_ (EINTR);
#if EPOLL_SUPPORT
connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
#endif
@@ -732,13 +731,13 @@ MHD_handle_connection (void *data)
num_ready = SELECT (max + 1, &rs, &ws, NULL, tvp);
if (num_ready < 0)
{
if (EINTR == errno)
if (EINTR == MHD_socket_errno_)
continue;
#if HAVE_MESSAGES
MHD_DLOG (con->daemon,
"Error during select (%d): `%s'\n",
max,
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
break;
}
@@ -784,11 +783,11 @@ MHD_handle_connection (void *data)
if (poll (p, 1,
(NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
{
if (EINTR == errno)
if (EINTR == MHD_socket_errno_)
continue;
#if HAVE_MESSAGES
MHD_DLOG (con->daemon, "Error during poll: `%s'\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
break;
}
@@ -848,7 +847,7 @@ recv_param_adapter (struct MHD_Connection *connection,
if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
(MHD_CONNECTION_CLOSED == connection->state) )
{
errno = ENOTCONN;
MHD_set_socket_errno_ (ENOTCONN);
return -1;
}
ret = RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
@@ -886,7 +885,7 @@ send_param_adapter (struct MHD_Connection *connection,
if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
(MHD_CONNECTION_CLOSED == connection->state) )
{
errno = ENOTCONN;
MHD_set_socket_errno_ (ENOTCONN);
return -1;
}
if (0 != (connection->daemon->options & MHD_USE_SSL))
@@ -916,9 +915,10 @@ send_param_adapter (struct MHD_Connection *connection,
#endif
return ret;
}
if ( (EINTR == errno) || (EAGAIN == errno) )
const int err = MHD_socket_errno_;
if ( (EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err) )
return 0;
if ( (EINVAL == errno) || (EBADF == errno) )
if ( (EINVAL == err) || (EBADF == err) )
return -1;
/* None of the 'usual' sendfile errors occurred, so we should try
to fall back to 'SEND'; see also this thread for info on
@@ -1137,7 +1137,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Error allocating memory: %s\n",
STRERROR (errno));
MHD_strerror_ (errno));
#endif
if (0 != MHD_socket_close_ (client_socket))
MHD_PANIC ("close failed\n");
@@ -1152,7 +1152,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Error allocating memory: %s\n",
STRERROR (errno));
MHD_strerror_ (errno));
#endif
if (0 != MHD_socket_close_ (client_socket))
MHD_PANIC ("close failed\n");
@@ -1171,7 +1171,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Error allocating memory: %s\n",
STRERROR (errno));
MHD_strerror_ (errno));
#endif
if (0 != MHD_socket_close_ (client_socket))
MHD_PANIC ("close failed\n");
@@ -1211,7 +1211,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to make socket non-blocking: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
}
#else
@@ -1221,7 +1221,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to make socket non-blocking: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
}
#endif
@@ -1299,7 +1299,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
eno = errno;
#if HAVE_MESSAGES
MHD_DLOG (daemon, "Failed to create a thread: %s\n",
STRERROR (res_thread_create));
MHD_strerror_ (res_thread_create));
#endif
goto cleanup;
}
@@ -1332,7 +1332,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Call to epoll_ctl failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
goto cleanup;
}
@@ -1584,7 +1584,7 @@ make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to make socket non-blocking: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
}
if (!GetHandleInformation ((HANDLE) sock, &dwFlags) ||
@@ -1592,10 +1592,9 @@ make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
!SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)))
{
#if HAVE_MESSAGES
SetErrnoFromWinError (GetLastError ());
MHD_DLOG (daemon,
"Failed to make socket non-inheritable: %s\n",
STRERROR (errno));
"Failed to make socket non-inheritable: %u\n",
(unsigned int) GetLastError ());
#endif
}
#else
@@ -1615,7 +1614,7 @@ make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to make socket non-inheritable: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
}
#endif
@@ -1713,11 +1712,12 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0))
{
#if HAVE_MESSAGES
const int err = MHD_socket_errno_;
/* This could be a common occurance with multiple worker threads */
if ((EAGAIN != errno) && (EWOULDBLOCK != errno))
if ((EAGAIN != err) && (EWOULDBLOCK != err))
MHD_DLOG (daemon,
"Error accepting connection: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
if (MHD_INVALID_SOCKET != s)
{
@@ -2094,10 +2094,10 @@ MHD_select (struct MHD_Daemon *daemon,
return MHD_NO;
if (num_ready < 0)
{
if (EINTR == errno)
if (EINTR == MHD_socket_errno_)
return MHD_YES;
#if HAVE_MESSAGES
MHD_DLOG (daemon, "select failed: %s\n", STRERROR (errno));
MHD_DLOG (daemon, "select failed: %s\n", MHD_socket_last_strerr_ ());
#endif
return MHD_NO;
}
@@ -2193,12 +2193,12 @@ MHD_poll_all (struct MHD_Daemon *daemon,
return MHD_YES;
if (poll (p, poll_server + num_connections, timeout) < 0)
{
if (EINTR == errno)
if (EINTR == MHD_socket_errno_)
return MHD_YES;
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"poll failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
return MHD_NO;
}
@@ -2299,10 +2299,10 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
return MHD_YES;
if (poll (p, poll_count, timeout) < 0)
{
if (EINTR == errno)
if (EINTR == MHD_socket_errno_)
return MHD_YES;
#if HAVE_MESSAGES
MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno));
MHD_DLOG (daemon, "poll failed: %s\n", MHD_socket_last_strerr_ ());
#endif
return MHD_NO;
}
@@ -2396,7 +2396,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
if (0 != (daemon->options & MHD_USE_DEBUG))
MHD_DLOG (daemon,
"Call to epoll_ctl failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
return MHD_NO;
}
@@ -2442,13 +2442,13 @@ MHD_epoll (struct MHD_Daemon *daemon,
events, MAX_EVENTS, timeout_ms);
if (-1 == num_events)
{
if (EINTR == errno)
if (EINTR == MHD_socket_errno_)
return MHD_YES;
#if HAVE_MESSAGES
if (0 != (daemon->options & MHD_USE_DEBUG))
MHD_DLOG (daemon,
"Call to epoll_wait failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
return MHD_NO;
}
@@ -3083,7 +3083,7 @@ create_socket (struct MHD_Daemon *daemon,
/* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
* implementations do not set ai_socktype, e.g. RHL6.2. */
fd = SOCKET (domain, ctype, protocol);
if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == errno) && (0 != SOCK_CLOEXEC) )
if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == MHD_socket_errno_) && (0 != SOCK_CLOEXEC) )
{
ctype = type;
fd = SOCKET(domain, type, protocol);
@@ -3116,7 +3116,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
if (0 != (daemon->options & MHD_USE_DEBUG))
MHD_DLOG (daemon,
"Call to epoll_create1 failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
return MHD_NO;
}
@@ -3136,7 +3136,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
if (0 != (daemon->options & MHD_USE_DEBUG))
MHD_DLOG (daemon,
"Call to epoll_ctl failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
return MHD_NO;
}
@@ -3155,7 +3155,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
if (0 != (daemon->options & MHD_USE_DEBUG))
MHD_DLOG (daemon,
"Call to epoll_ctl failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
return MHD_NO;
}
@@ -3274,7 +3274,7 @@ MHD_start_daemon_va (unsigned int flags,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to create control pipe: %s\n",
STRERROR (errno));
MHD_strerror_ (errno));
#endif
free (daemon);
return NULL;
@@ -3342,7 +3342,7 @@ MHD_start_daemon_va (unsigned int flags,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to allocate memory for nonce-nc map: %s\n",
STRERROR (errno));
MHD_strerror_ (errno));
#endif
#if HTTPS_SUPPORT
if (0 != (flags & MHD_USE_SSL))
@@ -3442,7 +3442,7 @@ MHD_start_daemon_va (unsigned int flags,
if (0 != (flags & MHD_USE_DEBUG))
MHD_DLOG (daemon,
"Call to socket failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
goto free_and_fail;
}
@@ -3455,7 +3455,7 @@ MHD_start_daemon_va (unsigned int flags,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"setsockopt failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
}
@@ -3515,7 +3515,7 @@ MHD_start_daemon_va (unsigned int flags,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"setsockopt failed: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
}
#endif
@@ -3528,7 +3528,7 @@ MHD_start_daemon_va (unsigned int flags,
MHD_DLOG (daemon,
"Failed to bind to port %u: %s\n",
(unsigned int) port,
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
if (0 != MHD_socket_close_ (socket_fd))
MHD_PANIC ("close failed\n");
@@ -3543,7 +3543,7 @@ MHD_start_daemon_va (unsigned int flags,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to make listen socket non-blocking: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
if (0 != MHD_socket_close_ (socket_fd))
MHD_PANIC ("close failed\n");
@@ -3557,7 +3557,7 @@ MHD_start_daemon_va (unsigned int flags,
if (0 != (flags & MHD_USE_DEBUG))
MHD_DLOG (daemon,
"Failed to listen for connections: %s\n",
STRERROR (errno));
MHD_socket_last_strerr_ ());
#endif
if (0 != MHD_socket_close_ (socket_fd))
MHD_PANIC ("close failed\n");
@@ -3635,7 +3635,7 @@ MHD_start_daemon_va (unsigned int flags,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to create listen thread: %s\n",
STRERROR (res_thread_create));
MHD_strerror_ (res_thread_create));
#endif
pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
@@ -3715,7 +3715,7 @@ MHD_start_daemon_va (unsigned int flags,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to create worker control pipe: %s\n",
STRERROR (errno));
MHD_strerror_ (errno));
#endif
goto thread_failed;
}
@@ -3764,7 +3764,7 @@ MHD_start_daemon_va (unsigned int flags,
#if HAVE_MESSAGES
MHD_DLOG (daemon,
"Failed to create pool thread: %s\n",
STRERROR (res_thread_create));
MHD_strerror_ (res_thread_create));
#endif
/* Free memory for this worker; cleanup below handles
* all previously-created workers. */
+1
View File
@@ -29,6 +29,7 @@
#include "platform.h"
#include "microhttpd.h"
#include "platform_interface.h"
#if HTTPS_SUPPORT
#include <gnutls/gnutls.h>
#if GNUTLS_VERSION_MAJOR >= 3
+33
View File
@@ -26,6 +26,10 @@
#ifndef MHD_PLATFORM_INTERFACE_H
#define MHD_PLATFORM_INTERFACE_H
#if defined(_WIN32) && !defined(__CYGWIN__)
#include "w32functions.h"
#endif
/* MHD_socket_close_(fd) close any FDs (non-W32) / close only socket FDs (W32) */
#if !defined(_WIN32) || defined(__CYGWIN__)
#define MHD_socket_close_(fd) close((fd))
@@ -33,4 +37,33 @@
#define MHD_socket_close_(fd) closesocket((fd))
#endif
/* MHD_socket_errno_ is errno of last function (non-W32) / errno of last socket function (W32) */
#if !defined(_WIN32) || defined(__CYGWIN__)
#define MHD_socket_errno_ errno
#else
#define MHD_socket_errno_ MHD_W32_errno_from_winsock_()
#endif
/* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
* description string of last socket error (W32) */
#if !defined(_WIN32) || defined(__CYGWIN__)
#define MHD_socket_last_strerr_() strerror(errno)
#else
#define MHD_socket_last_strerr_() MHD_W32_strerror_last_winsock_()
#endif
/* MHD_strerror_ is strerror (both non-W32/W32) */
#if !defined(_WIN32) || defined(__CYGWIN__)
#define MHD_strerror_(errnum) strerror((errnum))
#else
#define MHD_strerror_(errnum) MHD_W32_strerror_((errnum))
#endif
/* MHD_set_socket_errno_ set errno to errnum (non-W32) / set socket last error to errnum (W32) */
#if !defined(_WIN32) || defined(__CYGWIN__)
#define MHD_set_socket_errno_(errnum) errno=(errnum)
#else
#define MHD_set_socket_errno_(errnum) MHD_W32_set_last_winsock_error_((errnum))
#endif
#endif // MHD_PLATFORM_INTERFACE_H
+543
View File
@@ -0,0 +1,543 @@
/*
This file is part of libmicrohttpd
(C) 2014 Karlson2k (Evgeny Grin)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file platform/w32functions.h
* @brief internal functions for W32 systems
* @author Karlson2k (Evgeny Grin)
*/
#include "w32functions.h"
#include <errno.h>
#include <winsock2.h>
#include <string.h>
/**
* Return errno equivalent of last winsock error
* @return errno equivalent of last winsock error
*/
int MHD_W32_errno_from_winsock_(void)
{
switch(WSAGetLastError())
{
case 0: return 0;
case WSA_INVALID_HANDLE: return EBADF;
case WSA_NOT_ENOUGH_MEMORY: return ENOMEM;
case WSA_INVALID_PARAMETER: return EINVAL;
case WSAEINTR: return EINTR;
case WSAEWOULDBLOCK: return EWOULDBLOCK;
case WSAEINPROGRESS: return EINPROGRESS;
case WSAEALREADY: return EALREADY;
case WSAENOTSOCK: return ENOTSOCK;
case WSAEDESTADDRREQ: return EDESTADDRREQ;
case WSAEMSGSIZE: return EMSGSIZE;
case WSAEPROTOTYPE: return EPROTOTYPE;
case WSAENOPROTOOPT: return ENOPROTOOPT;
case WSAEPROTONOSUPPORT: return EPROTONOSUPPORT;
case WSAESOCKTNOSUPPORT: return ESOCKTNOSUPPORT;
case WSAEOPNOTSUPP: return EOPNOTSUPP;
case WSAEPFNOSUPPORT: return EPFNOSUPPORT;
case WSAEAFNOSUPPORT: return EAFNOSUPPORT;
case WSAEADDRINUSE: return EADDRINUSE;
case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL;
case WSAENETDOWN: return ENETDOWN;
case WSAENETUNREACH: return ENETUNREACH;
case WSAENETRESET: return ENETRESET;
case WSAECONNABORTED: return ECONNABORTED;
case WSAECONNRESET: return ECONNRESET;
case WSAENOBUFS: return ENOBUFS;
case WSAEISCONN: return EISCONN;
case WSAENOTCONN: return ENOTCONN;
case WSAESHUTDOWN: return ESHUTDOWN;
case WSAETOOMANYREFS: return ETOOMANYREFS;
case WSAETIMEDOUT: return ETIMEDOUT;
case WSAECONNREFUSED: return ECONNREFUSED;
case WSAELOOP: return ELOOP;
case WSAENAMETOOLONG: return ENAMETOOLONG;
case WSAEHOSTDOWN: return EHOSTDOWN;
case WSAEHOSTUNREACH: return EHOSTUNREACH;
case WSAENOTEMPTY: return ENOTEMPTY;
case WSAEPROCLIM: return EPROCLIM;
case WSAEUSERS: return EUSERS;
case WSAEDQUOT: return EDQUOT;
case WSAESTALE: return ESTALE;
case WSAEREMOTE: return EREMOTE;
case WSAEINVAL: return EINVAL;
case WSAEFAULT: return EFAULT;
case WSANO_DATA: return ENODATA;
/* Rough equivalents */
case WSAEDISCON: return ECONNRESET;
case WSAEINVALIDPROCTABLE: return EFAULT;
case WSASYSNOTREADY:
case WSANOTINITIALISED:
case WSASYSCALLFAILURE: return ENOBUFS;
case WSAVERNOTSUPPORTED: return EOPNOTSUPP;
case WSAEREFUSED: return EIO;
}
return EINVAL;
}
/**
* Return pointer to string description of errnum error
* Works fine with both standard errno errnums
* and errnums from MHD_W32_errno_from_winsock_
* @param errnum the errno or value from MHD_W32_errno_from_winsock_()
* @return pointer to string description of error
*/
const char* MHD_W32_strerror_(int errnum)
{
switch(errnum)
{
case 0:
return "No error";
case EWOULDBLOCK:
return "Operation would block";
case EINPROGRESS:
return "Connection already in progress";
case EALREADY:
return "Socket already connected";
case ENOTSOCK:
return "Socket operation on non-socket";
case EDESTADDRREQ:
return "Destination address required";
case EMSGSIZE:
return "Message too long";
case EPROTOTYPE:
return "Protocol wrong type for socket";
case ENOPROTOOPT:
return "Protocol not available";
case EPROTONOSUPPORT:
return "Unknown protocol";
case ESOCKTNOSUPPORT:
return "Socket type not supported";
case EOPNOTSUPP:
return "Operation not supported on socket";
case EPFNOSUPPORT:
return "Protocol family not supported";
case EAFNOSUPPORT:
return "Address family not supported by protocol family";
case EADDRINUSE:
return "Address already in use";
case EADDRNOTAVAIL:
return "Cannot assign requested address";
case ENETDOWN:
return "Network is down";
case ENETUNREACH:
return "Network is unreachable";
case ENETRESET:
return "Network dropped connection on reset";
case ECONNABORTED:
return "Software caused connection abort";
case ECONNRESET:
return "Connection reset by peer";
case ENOBUFS:
return "No system resources available";
case EISCONN:
return "Socket is already connected";
case ENOTCONN:
return "Socket is not connected";
case ESHUTDOWN:
return "Can't send after socket shutdown";
case ETOOMANYREFS:
return "Too many references: cannot splice";
case ETIMEDOUT:
return "Connection timed out";
case ECONNREFUSED:
return "Connection refused";
case ELOOP:
return "Cannot translate name";
case EHOSTDOWN:
return "Host is down";
case EHOSTUNREACH:
return "Host is unreachable";
case EPROCLIM:
return "Too many processes";
case EUSERS:
return "Too many users";
case EDQUOT:
return "Disk quota exceeded";
case ESTALE:
return "Stale file handle reference";
case EREMOTE:
return "Resource is remote";
case ENODATA:
return "No data available";
}
return strerror(errnum);
}
/**
* Return pointer to string description of last winsock error
* @return pointer to string description of last winsock error
*/
const char* MHD_W32_strerror_last_winsock_(void)
{
switch (WSAGetLastError())
{
case 0:
return "No error";
case WSA_INVALID_HANDLE:
return "Specified event object handle is invalid";
case WSA_NOT_ENOUGH_MEMORY:
return "Insufficient memory available";
case WSA_INVALID_PARAMETER:
return "One or more parameters are invalid";
case WSA_OPERATION_ABORTED:
return "Overlapped operation aborted";
case WSA_IO_INCOMPLETE:
return "Overlapped I/O event object not in signaled state";
case WSA_IO_PENDING:
return "Overlapped operations will complete later";
case WSAEINTR:
return "Interrupted function call";
case WSAEBADF:
return "File handle is not valid";
case WSAEACCES:
return "Permission denied";
case WSAEFAULT:
return "Bad address";
case WSAEINVAL:
return "Invalid argument";
case WSAEMFILE:
return "Too many open files";
case WSAEWOULDBLOCK:
return "Resource temporarily unavailable";
case WSAEINPROGRESS:
return "Operation now in progress";
case WSAEALREADY:
return "Operation already in progress";
case WSAENOTSOCK:
return "Socket operation on nonsocket";
case WSAEDESTADDRREQ:
return "Destination address required";
case WSAEMSGSIZE:
return "Message too long";
case WSAEPROTOTYPE:
return "Protocol wrong type for socket";
case WSAENOPROTOOPT:
return "Bad protocol option";
case WSAEPROTONOSUPPORT:
return "Protocol not supported";
case WSAESOCKTNOSUPPORT:
return "Socket type not supported";
case WSAEOPNOTSUPP:
return "Operation not supported";
case WSAEPFNOSUPPORT:
return "Protocol family not supported";
case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family";
case WSAEADDRINUSE:
return "Address already in use";
case WSAEADDRNOTAVAIL:
return "Cannot assign requested address";
case WSAENETDOWN:
return "Network is down";
case WSAENETUNREACH:
return "Network is unreachable";
case WSAENETRESET:
return "Network dropped connection on reset";
case WSAECONNABORTED:
return "Software caused connection abort";
case WSAECONNRESET:
return "Connection reset by peer";
case WSAENOBUFS:
return "No buffer space available";
case WSAEISCONN:
return "Socket is already connected";
case WSAENOTCONN:
return "Socket is not connected";
case WSAESHUTDOWN:
return "Cannot send after socket shutdown";
case WSAETOOMANYREFS:
return "Too many references";
case WSAETIMEDOUT:
return "Connection timed out";
case WSAECONNREFUSED:
return "Connection refused";
case WSAELOOP:
return "Cannot translate name";
case WSAENAMETOOLONG:
return "Name too long";
case WSAEHOSTDOWN:
return "Host is down";
case WSAEHOSTUNREACH:
return "No route to host";
case WSAENOTEMPTY:
return "Directory not empty";
case WSAEPROCLIM:
return "Too many processes";
case WSAEUSERS:
return "User quota exceeded";
case WSAEDQUOT:
return "Disk quota exceeded";
case WSAESTALE:
return "Stale file handle reference";
case WSAEREMOTE:
return "Item is remote";
case WSASYSNOTREADY:
return "Network subsystem is unavailable";
case WSAVERNOTSUPPORTED:
return "Winsock.dll version out of range";
case WSANOTINITIALISED:
return "Successful WSAStartup not yet performed";
case WSAEDISCON:
return "Graceful shutdown in progress";
case WSAENOMORE:
return "No more results";
case WSAECANCELLED:
return "Call has been canceled";
case WSAEINVALIDPROCTABLE:
return "Procedure call table is invalid";
case WSAEINVALIDPROVIDER:
return "Service provider is invalid";
case WSAEPROVIDERFAILEDINIT:
return "Service provider failed to initialize";
case WSASYSCALLFAILURE:
return "System call failure";
case WSASERVICE_NOT_FOUND:
return "Service not found";
case WSATYPE_NOT_FOUND:
return "Class type not found";
case WSA_E_NO_MORE:
return "No more results";
case WSA_E_CANCELLED:
return "Call was canceled";
case WSAEREFUSED:
return "Database query was refused";
case WSAHOST_NOT_FOUND:
return "Host not found";
case WSATRY_AGAIN:
return "Nonauthoritative host not found";
case WSANO_RECOVERY:
return "This is a nonrecoverable error";
case WSANO_DATA:
return "Valid name, no data record of requested type";
case WSA_QOS_RECEIVERS:
return "QoS receivers";
case WSA_QOS_SENDERS:
return "QoS senders";
case WSA_QOS_NO_SENDERS:
return "No QoS senders";
case WSA_QOS_NO_RECEIVERS:
return "QoS no receivers";
case WSA_QOS_REQUEST_CONFIRMED:
return "QoS request confirmed";
case WSA_QOS_ADMISSION_FAILURE:
return "QoS admission error";
case WSA_QOS_POLICY_FAILURE:
return "QoS policy failure";
case WSA_QOS_BAD_STYLE:
return "QoS bad style";
case WSA_QOS_BAD_OBJECT:
return "QoS bad object";
case WSA_QOS_TRAFFIC_CTRL_ERROR:
return "QoS traffic control error";
case WSA_QOS_GENERIC_ERROR:
return "QoS generic error";
case WSA_QOS_ESERVICETYPE:
return "QoS service type error";
case WSA_QOS_EFLOWSPEC:
return "QoS flowspec error";
case WSA_QOS_EPROVSPECBUF:
return "Invalid QoS provider buffer";
case WSA_QOS_EFILTERSTYLE:
return "Invalid QoS filter style";
case WSA_QOS_EFILTERTYPE:
return "Invalid QoS filter type";
case WSA_QOS_EFILTERCOUNT:
return "Incorrect QoS filter count";
case WSA_QOS_EOBJLENGTH:
return "Invalid QoS object length";
case WSA_QOS_EFLOWCOUNT:
return "Incorrect QoS flow count";
case WSA_QOS_EUNKOWNPSOBJ:
return "Unrecognized QoS object";
case WSA_QOS_EPOLICYOBJ:
return "Invalid QoS policy object";
case WSA_QOS_EFLOWDESC:
return "Invalid QoS flow descriptor";
case WSA_QOS_EPSFLOWSPEC:
return "Invalid QoS provider-specific flowspec";
case WSA_QOS_EPSFILTERSPEC:
return "Invalid QoS provider-specific filterspec";
case WSA_QOS_ESDMODEOBJ:
return "Invalid QoS shape discard mode object";
case WSA_QOS_ESHAPERATEOBJ:
return "Invalid QoS shaping rate object";
case WSA_QOS_RESERVED_PETYPE:
return "Reserved policy QoS element type";
}
return "Unknown winsock error";
}
/**
* Set last winsock error to equivalent of given errno value
* @param errnum the errno value to set
*/
void MHD_W32_set_last_winsock_error_(int errnum)
{
switch (errnum)
{
case 0:
WSASetLastError(0);
break;
case EBADF:
WSASetLastError(WSA_INVALID_HANDLE);
break;
case ENOMEM:
WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
break;
case EINVAL:
WSASetLastError(WSA_INVALID_PARAMETER);
break;
case EINTR:
WSASetLastError(WSAEINTR);
break;
case EWOULDBLOCK:
WSASetLastError(WSAEWOULDBLOCK);
break;
case EINPROGRESS:
WSASetLastError(WSAEINPROGRESS);
break;
case EALREADY:
WSASetLastError(WSAEALREADY);
break;
case ENOTSOCK:
WSASetLastError(WSAENOTSOCK);
break;
case EDESTADDRREQ:
WSASetLastError(WSAEDESTADDRREQ);
break;
case EMSGSIZE:
WSASetLastError(WSAEMSGSIZE);
break;
case EPROTOTYPE:
WSASetLastError(WSAEPROTOTYPE);
break;
case ENOPROTOOPT:
WSASetLastError(WSAENOPROTOOPT);
break;
case EPROTONOSUPPORT:
WSASetLastError(WSAEPROTONOSUPPORT);
break;
case ESOCKTNOSUPPORT:
WSASetLastError(WSAESOCKTNOSUPPORT);
break;
case EOPNOTSUPP:
WSASetLastError(WSAEOPNOTSUPP);
break;
case EPFNOSUPPORT:
WSASetLastError(WSAEPFNOSUPPORT);
break;
case EAFNOSUPPORT:
WSASetLastError(WSAEAFNOSUPPORT);
break;
case EADDRINUSE:
WSASetLastError(WSAEADDRINUSE);
break;
case EADDRNOTAVAIL:
WSASetLastError(WSAEADDRNOTAVAIL);
break;
case ENETDOWN:
WSASetLastError(WSAENETDOWN);
break;
case ENETUNREACH:
WSASetLastError(WSAENETUNREACH);
break;
case ENETRESET:
WSASetLastError(WSAENETRESET);
break;
case ECONNABORTED:
WSASetLastError(WSAECONNABORTED);
break;
case ECONNRESET:
WSASetLastError(WSAECONNRESET);
break;
case ENOBUFS:
WSASetLastError(WSAENOBUFS);
break;
case EISCONN:
WSASetLastError(WSAEISCONN);
break;
case ENOTCONN:
WSASetLastError(WSAENOTCONN);
break;
case ESHUTDOWN:
WSASetLastError(WSAESHUTDOWN);
break;
case ETOOMANYREFS:
WSASetLastError(WSAETOOMANYREFS);
break;
case ETIMEDOUT:
WSASetLastError(WSAETIMEDOUT);
break;
case ECONNREFUSED:
WSASetLastError(WSAECONNREFUSED);
break;
case ELOOP:
WSASetLastError(WSAELOOP);
break;
case ENAMETOOLONG:
WSASetLastError(WSAENAMETOOLONG);
break;
case EHOSTDOWN:
WSASetLastError(WSAEHOSTDOWN);
break;
case EHOSTUNREACH:
WSASetLastError(WSAEHOSTUNREACH);
break;
case ENOTEMPTY:
WSASetLastError(WSAENOTEMPTY);
break;
case EPROCLIM:
WSASetLastError(WSAEPROCLIM);
break;
case EUSERS:
WSASetLastError(WSAEUSERS);
break;
case EDQUOT:
WSASetLastError(WSAEDQUOT);
break;
case ESTALE:
WSASetLastError(WSAESTALE);
break;
case EREMOTE:
WSASetLastError(WSAEREMOTE);
break;
case EFAULT:
WSASetLastError(WSAEFAULT);
break;
case ENODATA:
WSASetLastError(WSANO_DATA);
break;
#if EAGAIN != EWOULDBLOCK
case EAGAIN:
WSASetLastError(WSAEWOULDBLOCK);
break;
#endif
/* Rough equivalent */
case EIO:
WSASetLastError(WSAEREFUSED);
break;
default: /* Unmapped errors */
WSASetLastError(WSAENOBUFS);
break;
}
}
+176
View File
@@ -0,0 +1,176 @@
/*
This file is part of libmicrohttpd
(C) 2014 Karlson2k (Evgeny Grin)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file platform/w32functions.h
* @brief internal functions for W32 systems
* @author Karlson2k (Evgeny Grin)
*/
#ifndef MHD_W32FUNCTIONS_H
#define MHD_W32FUNCTIONS_H
#ifndef _WIN32
#error w32functions.h is designed only for W32 systems
#endif
#include <errno.h>
#include <winsock2.h>
#include "platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define MHDW32ERRBASE 3300
#ifndef EWOULDBLOCK
#define EWOULDBLOCK (MHDW32ERRBASE+1)
#endif
#ifndef EINPROGRESS
#define EINPROGRESS (MHDW32ERRBASE+2)
#endif
#ifndef EALREADY
#define EALREADY (MHDW32ERRBASE+3)
#endif
#ifndef ENOTSOCK
#define ENOTSOCK (MHDW32ERRBASE+4)
#endif
#ifndef EDESTADDRREQ
#define EDESTADDRREQ (MHDW32ERRBASE+5)
#endif
#ifndef EMSGSIZE
#define EMSGSIZE (MHDW32ERRBASE+6)
#endif
#ifndef EPROTOTYPE
#define EPROTOTYPE (MHDW32ERRBASE+7)
#endif
#ifndef ENOPROTOOPT
#define ENOPROTOOPT (MHDW32ERRBASE+8)
#endif
#ifndef EPROTONOSUPPORT
#define EPROTONOSUPPORT (MHDW32ERRBASE+9)
#endif
#ifndef EOPNOTSUPP
#define EOPNOTSUPP (MHDW32ERRBASE+10)
#endif
#ifndef EAFNOSUPPORT
#define EAFNOSUPPORT (MHDW32ERRBASE+11)
#endif
#ifndef EADDRINUSE
#define EADDRINUSE (MHDW32ERRBASE+12)
#endif
#ifndef EADDRNOTAVAIL
#define EADDRNOTAVAIL (MHDW32ERRBASE+13)
#endif
#ifndef ENETDOWN
#define ENETDOWN (MHDW32ERRBASE+14)
#endif
#ifndef ENETUNREACH
#define ENETUNREACH (MHDW32ERRBASE+15)
#endif
#ifndef ENETRESET
#define ENETRESET (MHDW32ERRBASE+16)
#endif
#ifndef ECONNABORTED
#define ECONNABORTED (MHDW32ERRBASE+17)
#endif
#ifndef ECONNRESET
#define ECONNRESET (MHDW32ERRBASE+18)
#endif
#ifndef ENOBUFS
#define ENOBUFS (MHDW32ERRBASE+19)
#endif
#ifndef EISCONN
#define EISCONN (MHDW32ERRBASE+20)
#endif
#ifndef ENOTCONN
#define ENOTCONN (MHDW32ERRBASE+21)
#endif
#ifndef ETOOMANYREFS
#define ETOOMANYREFS (MHDW32ERRBASE+22)
#endif
#ifndef ECONNREFUSED
#define ECONNREFUSED (MHDW32ERRBASE+23)
#endif
#ifndef ELOOP
#define ELOOP (MHDW32ERRBASE+24)
#endif
#ifndef EHOSTDOWN
#define EHOSTDOWN (MHDW32ERRBASE+25)
#endif
#ifndef EHOSTUNREACH
#define EHOSTUNREACH (MHDW32ERRBASE+26)
#endif
#ifndef EPROCLIM
#define EPROCLIM (MHDW32ERRBASE+27)
#endif
#ifndef EUSERS
#define EUSERS (MHDW32ERRBASE+28)
#endif
#ifndef EDQUOT
#define EDQUOT (MHDW32ERRBASE+29)
#endif
#ifndef ESTALE
#define ESTALE (MHDW32ERRBASE+30)
#endif
#ifndef EREMOTE
#define EREMOTE (MHDW32ERRBASE+31)
#endif
#ifndef ESOCKTNOSUPPORT
#define ESOCKTNOSUPPORT (MHDW32ERRBASE+32)
#endif
#ifndef EPFNOSUPPORT
#define EPFNOSUPPORT (MHDW32ERRBASE+33)
#endif
#ifndef ESHUTDOWN
#define ESHUTDOWN (MHDW32ERRBASE+34)
#endif
#ifndef ENODATA
#define ENODATA (MHDW32ERRBASE+35)
#endif
/**
* Return errno equivalent of last winsock error
* @return errno equivalent of last winsock error
*/
int MHD_W32_errno_from_winsock_(void);
/**
* Return pointer to string description of errnum error
* Works fine with both standard errno errnums
* and errnums from MHD_W32_errno_from_winsock_
* @param errnum the errno or value from MHD_W32_errno_from_winsock_()
* @return pointer to string description of error
*/
const char* MHD_W32_strerror_(int errnum);
/**
* Return pointer to string description of last winsock error
* @return pointer to string description of last winsock error
*/
const char* MHD_W32_strerror_last_winsock_(void);
/**
* Set last winsock error to equivalent of given errno value
* @param errnum the errno value to set
*/
void MHD_W32_set_last_winsock_error_(int errnum);
#ifdef __cplusplus
}
#endif
#endif //MHD_W32FUNCTIONS_H
+10 -1
View File
@@ -137,7 +137,12 @@ test_digestauth_with_arguments_LDADD = \
@LIBCURL@ @LIBGCRYPT_LIBS@
test_get_sendfile_SOURCES = \
test_get_sendfile.c
test_get_sendfile.c \
../platform/platform_interface.h
if HAVE_W32
test_get_sendfile_SOURCES += \
../platform/w32functions.h ../platform/w32functions.c
endif
test_get_sendfile_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
@@ -215,6 +220,10 @@ test_get11_LDADD = \
test_get_sendfile11_SOURCES = \
test_get_sendfile.c
if HAVE_W32
test_get_sendfile11_SOURCES += \
../platform/w32functions.h ../platform/w32functions.c
endif
test_get_sendfile11_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
+2 -1
View File
@@ -26,6 +26,7 @@
#include "MHD_config.h"
#include "platform.h"
#include "platform_interface.h"
#include <curl/curl.h>
#include <microhttpd.h>
#include <stdlib.h>
@@ -93,7 +94,7 @@ ahc_echo (void *cls,
{
fprintf (stderr, "Failed to open `%s': %s\n",
sourcefile,
STRERROR (errno));
MHD_strerror_ (errno));
exit (1);
}
response = MHD_create_response_from_fd (strlen (TESTSTR), fd);