aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/microhttpd/Makefile.am6
-rw-r--r--src/microhttpd/connection.c23
-rw-r--r--src/microhttpd/daemon.c100
-rw-r--r--src/microhttpd/internal.h1
-rw-r--r--src/platform/platform_interface.h33
-rw-r--r--src/platform/w32functions.c543
-rw-r--r--src/platform/w32functions.h176
-rw-r--r--src/testcurl/Makefile.am11
-rw-r--r--src/testcurl/test_get_sendfile.c3
9 files changed, 834 insertions, 62 deletions
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index f09c3b12..7dd6ba77 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -2,6 +2,10 @@ if USE_PRIVATE_PLIBC_H
2 PLIBC_INCLUDE = -I$(top_srcdir)/src/include/plibc 2 PLIBC_INCLUDE = -I$(top_srcdir)/src/include/plibc
3endif 3endif
4 4
5if HAVE_W32
6 W32FUNC_SRC = ../platform/w32functions.c ../platform/w32functions.h
7endif
8
5AM_CPPFLAGS = \ 9AM_CPPFLAGS = \
6 $(PLIBC_INCLUDE) \ 10 $(PLIBC_INCLUDE) \
7 -I$(top_srcdir)/src/include \ 11 -I$(top_srcdir)/src/include \
@@ -22,7 +26,7 @@ libmicrohttpd_la_SOURCES = \
22 internal.c internal.h \ 26 internal.c internal.h \
23 memorypool.c memorypool.h \ 27 memorypool.c memorypool.h \
24 response.c response.h \ 28 response.c response.h \
25 ../platform/platform_interface.h 29 ../platform/platform_interface.h $(W32FUNC_SRC)
26libmicrohttpd_la_CPPFLAGS = \ 30libmicrohttpd_la_CPPFLAGS = \
27 $(AM_CPPFLAGS) \ 31 $(AM_CPPFLAGS) \
28 -DBUILDING_MHD_LIB=1 32 -DBUILDING_MHD_LIB=1
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 414c4b17..26bf6cc0 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1583,7 +1583,9 @@ do_read (struct MHD_Connection *connection)
1583 connection->read_buffer_offset); 1583 connection->read_buffer_offset);
1584 if (bytes_read < 0) 1584 if (bytes_read < 0)
1585 { 1585 {
1586 if ((EINTR == errno) || (EAGAIN == errno) || (ECONNRESET == errno)) 1586 const int err = MHD_socket_errno_;
1587 if ((EINTR == err) || (EAGAIN == err) || (ECONNRESET == err)
1588 || (EWOULDBLOCK == err))
1587 return MHD_NO; 1589 return MHD_NO;
1588#if HAVE_MESSAGES 1590#if HAVE_MESSAGES
1589#if HTTPS_SUPPORT 1591#if HTTPS_SUPPORT
@@ -1595,7 +1597,7 @@ do_read (struct MHD_Connection *connection)
1595#endif 1597#endif
1596 MHD_DLOG (connection->daemon, 1598 MHD_DLOG (connection->daemon,
1597 "Failed to receive data: %s\n", 1599 "Failed to receive data: %s\n",
1598 STRERROR (errno)); 1600 MHD_socket_last_strerr_ ());
1599#endif 1601#endif
1600 CONNECTION_CLOSE_ERROR (connection, NULL); 1602 CONNECTION_CLOSE_ERROR (connection, NULL);
1601 return MHD_YES; 1603 return MHD_YES;
@@ -1636,7 +1638,8 @@ do_write (struct MHD_Connection *connection)
1636 1638
1637 if (ret < 0) 1639 if (ret < 0)
1638 { 1640 {
1639 if ((EINTR == errno) || (EAGAIN == errno)) 1641 const int err = MHD_socket_errno_;
1642 if ((EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err))
1640 return MHD_NO; 1643 return MHD_NO;
1641#if HAVE_MESSAGES 1644#if HAVE_MESSAGES
1642#if HTTPS_SUPPORT 1645#if HTTPS_SUPPORT
@@ -1647,7 +1650,7 @@ do_write (struct MHD_Connection *connection)
1647 else 1650 else
1648#endif 1651#endif
1649 MHD_DLOG (connection->daemon, 1652 MHD_DLOG (connection->daemon,
1650 "Failed to send data: %s\n", STRERROR (errno)); 1653 "Failed to send data: %s\n", MHD_socket_last_strerr_ ());
1651#endif 1654#endif
1652 CONNECTION_CLOSE_ERROR (connection, NULL); 1655 CONNECTION_CLOSE_ERROR (connection, NULL);
1653 return MHD_YES; 1656 return MHD_YES;
@@ -2022,12 +2025,13 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2022 connection->continue_message_write_offset); 2025 connection->continue_message_write_offset);
2023 if (ret < 0) 2026 if (ret < 0)
2024 { 2027 {
2025 if ((errno == EINTR) || (errno == EAGAIN)) 2028 const int err = MHD_socket_errno_;
2029 if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err))
2026 break; 2030 break;
2027#if HAVE_MESSAGES 2031#if HAVE_MESSAGES
2028 MHD_DLOG (connection->daemon, 2032 MHD_DLOG (connection->daemon,
2029 "Failed to send data: %s\n", 2033 "Failed to send data: %s\n",
2030 STRERROR (errno)); 2034 MHD_socket_last_strerr_ ());
2031#endif 2035#endif
2032 CONNECTION_CLOSE_ERROR (connection, NULL); 2036 CONNECTION_CLOSE_ERROR (connection, NULL);
2033 return MHD_YES; 2037 return MHD_YES;
@@ -2068,6 +2072,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2068 response->data_size - 2072 response->data_size -
2069 (connection->response_write_position 2073 (connection->response_write_position
2070 - response->data_start)); 2074 - response->data_start));
2075 const int err = MHD_socket_errno_;
2071#if DEBUG_SEND_DATA 2076#if DEBUG_SEND_DATA
2072 if (ret > 0) 2077 if (ret > 0)
2073 FPRINTF (stderr, 2078 FPRINTF (stderr,
@@ -2080,12 +2085,12 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2080 pthread_mutex_unlock (&response->mutex); 2085 pthread_mutex_unlock (&response->mutex);
2081 if (ret < 0) 2086 if (ret < 0)
2082 { 2087 {
2083 if ((errno == EINTR) || (errno == EAGAIN)) 2088 if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err))
2084 return MHD_YES; 2089 return MHD_YES;
2085#if HAVE_MESSAGES 2090#if HAVE_MESSAGES
2086 MHD_DLOG (connection->daemon, 2091 MHD_DLOG (connection->daemon,
2087 "Failed to send data: %s\n", 2092 "Failed to send data: %s\n",
2088 STRERROR (errno)); 2093 MHD_socket_last_strerr_ ());
2089#endif 2094#endif
2090 CONNECTION_CLOSE_ERROR (connection, NULL); 2095 CONNECTION_CLOSE_ERROR (connection, NULL);
2091 return MHD_YES; 2096 return MHD_YES;
@@ -2658,7 +2663,7 @@ MHD_connection_epoll_update_ (struct MHD_Connection *connection)
2658 if (0 != (daemon->options & MHD_USE_DEBUG)) 2663 if (0 != (daemon->options & MHD_USE_DEBUG))
2659 MHD_DLOG (daemon, 2664 MHD_DLOG (daemon,
2660 "Call to epoll_ctl failed: %s\n", 2665 "Call to epoll_ctl failed: %s\n",
2661 STRERROR (errno)); 2666 MHD_socket_last_strerr_ ());
2662#endif 2667#endif
2663 connection->state = MHD_CONNECTION_CLOSED; 2668 connection->state = MHD_CONNECTION_CLOSED;
2664 cleanup_connection (connection); 2669 cleanup_connection (connection);
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index af77644a..4ab43f9d 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -25,7 +25,6 @@
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 */ 26 */
27#include "platform.h" 27#include "platform.h"
28#include "platform_interface.h"
29#include "internal.h" 28#include "internal.h"
30#include "response.h" 29#include "response.h"
31#include "connection.h" 30#include "connection.h"
@@ -409,7 +408,7 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
409 if ( (GNUTLS_E_AGAIN == res) || 408 if ( (GNUTLS_E_AGAIN == res) ||
410 (GNUTLS_E_INTERRUPTED == res) ) 409 (GNUTLS_E_INTERRUPTED == res) )
411 { 410 {
412 errno = EINTR; 411 MHD_set_socket_errno_ (EINTR);
413#if EPOLL_SUPPORT 412#if EPOLL_SUPPORT
414 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 413 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
415#endif 414#endif
@@ -420,7 +419,7 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
420 /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication 419 /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
421 disrupted); set errno to something caller will interpret 420 disrupted); set errno to something caller will interpret
422 correctly as a hard error */ 421 correctly as a hard error */
423 errno = EPIPE; 422 MHD_set_socket_errno_ (ECONNRESET);
424 return res; 423 return res;
425 } 424 }
426 if (res == i) 425 if (res == i)
@@ -450,7 +449,7 @@ send_tls_adapter (struct MHD_Connection *connection,
450 if ( (GNUTLS_E_AGAIN == res) || 449 if ( (GNUTLS_E_AGAIN == res) ||
451 (GNUTLS_E_INTERRUPTED == res) ) 450 (GNUTLS_E_INTERRUPTED == res) )
452 { 451 {
453 errno = EINTR; 452 MHD_set_socket_errno_ (EINTR);
454#if EPOLL_SUPPORT 453#if EPOLL_SUPPORT
455 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 454 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
456#endif 455#endif
@@ -732,13 +731,13 @@ MHD_handle_connection (void *data)
732 num_ready = SELECT (max + 1, &rs, &ws, NULL, tvp); 731 num_ready = SELECT (max + 1, &rs, &ws, NULL, tvp);
733 if (num_ready < 0) 732 if (num_ready < 0)
734 { 733 {
735 if (EINTR == errno) 734 if (EINTR == MHD_socket_errno_)
736 continue; 735 continue;
737#if HAVE_MESSAGES 736#if HAVE_MESSAGES
738 MHD_DLOG (con->daemon, 737 MHD_DLOG (con->daemon,
739 "Error during select (%d): `%s'\n", 738 "Error during select (%d): `%s'\n",
740 max, 739 max,
741 STRERROR (errno)); 740 MHD_socket_last_strerr_ ());
742#endif 741#endif
743 break; 742 break;
744 } 743 }
@@ -784,11 +783,11 @@ MHD_handle_connection (void *data)
784 if (poll (p, 1, 783 if (poll (p, 1,
785 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) 784 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
786 { 785 {
787 if (EINTR == errno) 786 if (EINTR == MHD_socket_errno_)
788 continue; 787 continue;
789#if HAVE_MESSAGES 788#if HAVE_MESSAGES
790 MHD_DLOG (con->daemon, "Error during poll: `%s'\n", 789 MHD_DLOG (con->daemon, "Error during poll: `%s'\n",
791 STRERROR (errno)); 790 MHD_socket_last_strerr_ ());
792#endif 791#endif
793 break; 792 break;
794 } 793 }
@@ -848,7 +847,7 @@ recv_param_adapter (struct MHD_Connection *connection,
848 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 847 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
849 (MHD_CONNECTION_CLOSED == connection->state) ) 848 (MHD_CONNECTION_CLOSED == connection->state) )
850 { 849 {
851 errno = ENOTCONN; 850 MHD_set_socket_errno_ (ENOTCONN);
852 return -1; 851 return -1;
853 } 852 }
854 ret = RECV (connection->socket_fd, other, i, MSG_NOSIGNAL); 853 ret = RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
@@ -886,7 +885,7 @@ send_param_adapter (struct MHD_Connection *connection,
886 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 885 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
887 (MHD_CONNECTION_CLOSED == connection->state) ) 886 (MHD_CONNECTION_CLOSED == connection->state) )
888 { 887 {
889 errno = ENOTCONN; 888 MHD_set_socket_errno_ (ENOTCONN);
890 return -1; 889 return -1;
891 } 890 }
892 if (0 != (connection->daemon->options & MHD_USE_SSL)) 891 if (0 != (connection->daemon->options & MHD_USE_SSL))
@@ -916,9 +915,10 @@ send_param_adapter (struct MHD_Connection *connection,
916#endif 915#endif
917 return ret; 916 return ret;
918 } 917 }
919 if ( (EINTR == errno) || (EAGAIN == errno) ) 918 const int err = MHD_socket_errno_;
919 if ( (EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err) )
920 return 0; 920 return 0;
921 if ( (EINVAL == errno) || (EBADF == errno) ) 921 if ( (EINVAL == err) || (EBADF == err) )
922 return -1; 922 return -1;
923 /* None of the 'usual' sendfile errors occurred, so we should try 923 /* None of the 'usual' sendfile errors occurred, so we should try
924 to fall back to 'SEND'; see also this thread for info on 924 to fall back to 'SEND'; see also this thread for info on
@@ -1137,7 +1137,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1137#if HAVE_MESSAGES 1137#if HAVE_MESSAGES
1138 MHD_DLOG (daemon, 1138 MHD_DLOG (daemon,
1139 "Error allocating memory: %s\n", 1139 "Error allocating memory: %s\n",
1140 STRERROR (errno)); 1140 MHD_strerror_ (errno));
1141#endif 1141#endif
1142 if (0 != MHD_socket_close_ (client_socket)) 1142 if (0 != MHD_socket_close_ (client_socket))
1143 MHD_PANIC ("close failed\n"); 1143 MHD_PANIC ("close failed\n");
@@ -1152,7 +1152,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1152#if HAVE_MESSAGES 1152#if HAVE_MESSAGES
1153 MHD_DLOG (daemon, 1153 MHD_DLOG (daemon,
1154 "Error allocating memory: %s\n", 1154 "Error allocating memory: %s\n",
1155 STRERROR (errno)); 1155 MHD_strerror_ (errno));
1156#endif 1156#endif
1157 if (0 != MHD_socket_close_ (client_socket)) 1157 if (0 != MHD_socket_close_ (client_socket))
1158 MHD_PANIC ("close failed\n"); 1158 MHD_PANIC ("close failed\n");
@@ -1171,7 +1171,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1171#if HAVE_MESSAGES 1171#if HAVE_MESSAGES
1172 MHD_DLOG (daemon, 1172 MHD_DLOG (daemon,
1173 "Error allocating memory: %s\n", 1173 "Error allocating memory: %s\n",
1174 STRERROR (errno)); 1174 MHD_strerror_ (errno));
1175#endif 1175#endif
1176 if (0 != MHD_socket_close_ (client_socket)) 1176 if (0 != MHD_socket_close_ (client_socket))
1177 MHD_PANIC ("close failed\n"); 1177 MHD_PANIC ("close failed\n");
@@ -1211,7 +1211,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1211#if HAVE_MESSAGES 1211#if HAVE_MESSAGES
1212 MHD_DLOG (daemon, 1212 MHD_DLOG (daemon,
1213 "Failed to make socket non-blocking: %s\n", 1213 "Failed to make socket non-blocking: %s\n",
1214 STRERROR (errno)); 1214 MHD_socket_last_strerr_ ());
1215#endif 1215#endif
1216 } 1216 }
1217#else 1217#else
@@ -1221,7 +1221,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1221#if HAVE_MESSAGES 1221#if HAVE_MESSAGES
1222 MHD_DLOG (daemon, 1222 MHD_DLOG (daemon,
1223 "Failed to make socket non-blocking: %s\n", 1223 "Failed to make socket non-blocking: %s\n",
1224 STRERROR (errno)); 1224 MHD_socket_last_strerr_ ());
1225#endif 1225#endif
1226 } 1226 }
1227#endif 1227#endif
@@ -1299,7 +1299,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1299 eno = errno; 1299 eno = errno;
1300#if HAVE_MESSAGES 1300#if HAVE_MESSAGES
1301 MHD_DLOG (daemon, "Failed to create a thread: %s\n", 1301 MHD_DLOG (daemon, "Failed to create a thread: %s\n",
1302 STRERROR (res_thread_create)); 1302 MHD_strerror_ (res_thread_create));
1303#endif 1303#endif
1304 goto cleanup; 1304 goto cleanup;
1305 } 1305 }
@@ -1332,7 +1332,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
1332#if HAVE_MESSAGES 1332#if HAVE_MESSAGES
1333 MHD_DLOG (daemon, 1333 MHD_DLOG (daemon,
1334 "Call to epoll_ctl failed: %s\n", 1334 "Call to epoll_ctl failed: %s\n",
1335 STRERROR (errno)); 1335 MHD_socket_last_strerr_ ());
1336#endif 1336#endif
1337 goto cleanup; 1337 goto cleanup;
1338 } 1338 }
@@ -1584,7 +1584,7 @@ make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
1584#if HAVE_MESSAGES 1584#if HAVE_MESSAGES
1585 MHD_DLOG (daemon, 1585 MHD_DLOG (daemon,
1586 "Failed to make socket non-blocking: %s\n", 1586 "Failed to make socket non-blocking: %s\n",
1587 STRERROR (errno)); 1587 MHD_socket_last_strerr_ ());
1588#endif 1588#endif
1589 } 1589 }
1590 if (!GetHandleInformation ((HANDLE) sock, &dwFlags) || 1590 if (!GetHandleInformation ((HANDLE) sock, &dwFlags) ||
@@ -1592,10 +1592,9 @@ make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
1592 !SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0))) 1592 !SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)))
1593 { 1593 {
1594#if HAVE_MESSAGES 1594#if HAVE_MESSAGES
1595 SetErrnoFromWinError (GetLastError ());
1596 MHD_DLOG (daemon, 1595 MHD_DLOG (daemon,
1597 "Failed to make socket non-inheritable: %s\n", 1596 "Failed to make socket non-inheritable: %u\n",
1598 STRERROR (errno)); 1597 (unsigned int) GetLastError ());
1599#endif 1598#endif
1600 } 1599 }
1601#else 1600#else
@@ -1615,7 +1614,7 @@ make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
1615#if HAVE_MESSAGES 1614#if HAVE_MESSAGES
1616 MHD_DLOG (daemon, 1615 MHD_DLOG (daemon,
1617 "Failed to make socket non-inheritable: %s\n", 1616 "Failed to make socket non-inheritable: %s\n",
1618 STRERROR (errno)); 1617 MHD_socket_last_strerr_ ());
1619#endif 1618#endif
1620 } 1619 }
1621#endif 1620#endif
@@ -1713,11 +1712,12 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1713 if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0)) 1712 if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0))
1714 { 1713 {
1715#if HAVE_MESSAGES 1714#if HAVE_MESSAGES
1715 const int err = MHD_socket_errno_;
1716 /* This could be a common occurance with multiple worker threads */ 1716 /* This could be a common occurance with multiple worker threads */
1717 if ((EAGAIN != errno) && (EWOULDBLOCK != errno)) 1717 if ((EAGAIN != err) && (EWOULDBLOCK != err))
1718 MHD_DLOG (daemon, 1718 MHD_DLOG (daemon,
1719 "Error accepting connection: %s\n", 1719 "Error accepting connection: %s\n",
1720 STRERROR (errno)); 1720 MHD_socket_last_strerr_ ());
1721#endif 1721#endif
1722 if (MHD_INVALID_SOCKET != s) 1722 if (MHD_INVALID_SOCKET != s)
1723 { 1723 {
@@ -2094,10 +2094,10 @@ MHD_select (struct MHD_Daemon *daemon,
2094 return MHD_NO; 2094 return MHD_NO;
2095 if (num_ready < 0) 2095 if (num_ready < 0)
2096 { 2096 {
2097 if (EINTR == errno) 2097 if (EINTR == MHD_socket_errno_)
2098 return MHD_YES; 2098 return MHD_YES;
2099#if HAVE_MESSAGES 2099#if HAVE_MESSAGES
2100 MHD_DLOG (daemon, "select failed: %s\n", STRERROR (errno)); 2100 MHD_DLOG (daemon, "select failed: %s\n", MHD_socket_last_strerr_ ());
2101#endif 2101#endif
2102 return MHD_NO; 2102 return MHD_NO;
2103 } 2103 }
@@ -2193,12 +2193,12 @@ MHD_poll_all (struct MHD_Daemon *daemon,
2193 return MHD_YES; 2193 return MHD_YES;
2194 if (poll (p, poll_server + num_connections, timeout) < 0) 2194 if (poll (p, poll_server + num_connections, timeout) < 0)
2195 { 2195 {
2196 if (EINTR == errno) 2196 if (EINTR == MHD_socket_errno_)
2197 return MHD_YES; 2197 return MHD_YES;
2198#if HAVE_MESSAGES 2198#if HAVE_MESSAGES
2199 MHD_DLOG (daemon, 2199 MHD_DLOG (daemon,
2200 "poll failed: %s\n", 2200 "poll failed: %s\n",
2201 STRERROR (errno)); 2201 MHD_socket_last_strerr_ ());
2202#endif 2202#endif
2203 return MHD_NO; 2203 return MHD_NO;
2204 } 2204 }
@@ -2299,10 +2299,10 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
2299 return MHD_YES; 2299 return MHD_YES;
2300 if (poll (p, poll_count, timeout) < 0) 2300 if (poll (p, poll_count, timeout) < 0)
2301 { 2301 {
2302 if (EINTR == errno) 2302 if (EINTR == MHD_socket_errno_)
2303 return MHD_YES; 2303 return MHD_YES;
2304#if HAVE_MESSAGES 2304#if HAVE_MESSAGES
2305 MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno)); 2305 MHD_DLOG (daemon, "poll failed: %s\n", MHD_socket_last_strerr_ ());
2306#endif 2306#endif
2307 return MHD_NO; 2307 return MHD_NO;
2308 } 2308 }
@@ -2396,7 +2396,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
2396 if (0 != (daemon->options & MHD_USE_DEBUG)) 2396 if (0 != (daemon->options & MHD_USE_DEBUG))
2397 MHD_DLOG (daemon, 2397 MHD_DLOG (daemon,
2398 "Call to epoll_ctl failed: %s\n", 2398 "Call to epoll_ctl failed: %s\n",
2399 STRERROR (errno)); 2399 MHD_socket_last_strerr_ ());
2400#endif 2400#endif
2401 return MHD_NO; 2401 return MHD_NO;
2402 } 2402 }
@@ -2442,13 +2442,13 @@ MHD_epoll (struct MHD_Daemon *daemon,
2442 events, MAX_EVENTS, timeout_ms); 2442 events, MAX_EVENTS, timeout_ms);
2443 if (-1 == num_events) 2443 if (-1 == num_events)
2444 { 2444 {
2445 if (EINTR == errno) 2445 if (EINTR == MHD_socket_errno_)
2446 return MHD_YES; 2446 return MHD_YES;
2447#if HAVE_MESSAGES 2447#if HAVE_MESSAGES
2448 if (0 != (daemon->options & MHD_USE_DEBUG)) 2448 if (0 != (daemon->options & MHD_USE_DEBUG))
2449 MHD_DLOG (daemon, 2449 MHD_DLOG (daemon,
2450 "Call to epoll_wait failed: %s\n", 2450 "Call to epoll_wait failed: %s\n",
2451 STRERROR (errno)); 2451 MHD_socket_last_strerr_ ());
2452#endif 2452#endif
2453 return MHD_NO; 2453 return MHD_NO;
2454 } 2454 }
@@ -3083,7 +3083,7 @@ create_socket (struct MHD_Daemon *daemon,
3083 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo 3083 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
3084 * implementations do not set ai_socktype, e.g. RHL6.2. */ 3084 * implementations do not set ai_socktype, e.g. RHL6.2. */
3085 fd = SOCKET (domain, ctype, protocol); 3085 fd = SOCKET (domain, ctype, protocol);
3086 if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == errno) && (0 != SOCK_CLOEXEC) ) 3086 if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == MHD_socket_errno_) && (0 != SOCK_CLOEXEC) )
3087 { 3087 {
3088 ctype = type; 3088 ctype = type;
3089 fd = SOCKET(domain, type, protocol); 3089 fd = SOCKET(domain, type, protocol);
@@ -3116,7 +3116,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
3116 if (0 != (daemon->options & MHD_USE_DEBUG)) 3116 if (0 != (daemon->options & MHD_USE_DEBUG))
3117 MHD_DLOG (daemon, 3117 MHD_DLOG (daemon,
3118 "Call to epoll_create1 failed: %s\n", 3118 "Call to epoll_create1 failed: %s\n",
3119 STRERROR (errno)); 3119 MHD_socket_last_strerr_ ());
3120#endif 3120#endif
3121 return MHD_NO; 3121 return MHD_NO;
3122 } 3122 }
@@ -3136,7 +3136,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
3136 if (0 != (daemon->options & MHD_USE_DEBUG)) 3136 if (0 != (daemon->options & MHD_USE_DEBUG))
3137 MHD_DLOG (daemon, 3137 MHD_DLOG (daemon,
3138 "Call to epoll_ctl failed: %s\n", 3138 "Call to epoll_ctl failed: %s\n",
3139 STRERROR (errno)); 3139 MHD_socket_last_strerr_ ());
3140#endif 3140#endif
3141 return MHD_NO; 3141 return MHD_NO;
3142 } 3142 }
@@ -3155,7 +3155,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
3155 if (0 != (daemon->options & MHD_USE_DEBUG)) 3155 if (0 != (daemon->options & MHD_USE_DEBUG))
3156 MHD_DLOG (daemon, 3156 MHD_DLOG (daemon,
3157 "Call to epoll_ctl failed: %s\n", 3157 "Call to epoll_ctl failed: %s\n",
3158 STRERROR (errno)); 3158 MHD_socket_last_strerr_ ());
3159#endif 3159#endif
3160 return MHD_NO; 3160 return MHD_NO;
3161 } 3161 }
@@ -3274,7 +3274,7 @@ MHD_start_daemon_va (unsigned int flags,
3274#if HAVE_MESSAGES 3274#if HAVE_MESSAGES
3275 MHD_DLOG (daemon, 3275 MHD_DLOG (daemon,
3276 "Failed to create control pipe: %s\n", 3276 "Failed to create control pipe: %s\n",
3277 STRERROR (errno)); 3277 MHD_strerror_ (errno));
3278#endif 3278#endif
3279 free (daemon); 3279 free (daemon);
3280 return NULL; 3280 return NULL;
@@ -3342,7 +3342,7 @@ MHD_start_daemon_va (unsigned int flags,
3342#if HAVE_MESSAGES 3342#if HAVE_MESSAGES
3343 MHD_DLOG (daemon, 3343 MHD_DLOG (daemon,
3344 "Failed to allocate memory for nonce-nc map: %s\n", 3344 "Failed to allocate memory for nonce-nc map: %s\n",
3345 STRERROR (errno)); 3345 MHD_strerror_ (errno));
3346#endif 3346#endif
3347#if HTTPS_SUPPORT 3347#if HTTPS_SUPPORT
3348 if (0 != (flags & MHD_USE_SSL)) 3348 if (0 != (flags & MHD_USE_SSL))
@@ -3442,7 +3442,7 @@ MHD_start_daemon_va (unsigned int flags,
3442 if (0 != (flags & MHD_USE_DEBUG)) 3442 if (0 != (flags & MHD_USE_DEBUG))
3443 MHD_DLOG (daemon, 3443 MHD_DLOG (daemon,
3444 "Call to socket failed: %s\n", 3444 "Call to socket failed: %s\n",
3445 STRERROR (errno)); 3445 MHD_socket_last_strerr_ ());
3446#endif 3446#endif
3447 goto free_and_fail; 3447 goto free_and_fail;
3448 } 3448 }
@@ -3455,7 +3455,7 @@ MHD_start_daemon_va (unsigned int flags,
3455#if HAVE_MESSAGES 3455#if HAVE_MESSAGES
3456 MHD_DLOG (daemon, 3456 MHD_DLOG (daemon,
3457 "setsockopt failed: %s\n", 3457 "setsockopt failed: %s\n",
3458 STRERROR (errno)); 3458 MHD_socket_last_strerr_ ());
3459#endif 3459#endif
3460 } 3460 }
3461 3461
@@ -3515,7 +3515,7 @@ MHD_start_daemon_va (unsigned int flags,
3515#if HAVE_MESSAGES 3515#if HAVE_MESSAGES
3516 MHD_DLOG (daemon, 3516 MHD_DLOG (daemon,
3517 "setsockopt failed: %s\n", 3517 "setsockopt failed: %s\n",
3518 STRERROR (errno)); 3518 MHD_socket_last_strerr_ ());
3519#endif 3519#endif
3520 } 3520 }
3521#endif 3521#endif
@@ -3528,7 +3528,7 @@ MHD_start_daemon_va (unsigned int flags,
3528 MHD_DLOG (daemon, 3528 MHD_DLOG (daemon,
3529 "Failed to bind to port %u: %s\n", 3529 "Failed to bind to port %u: %s\n",
3530 (unsigned int) port, 3530 (unsigned int) port,
3531 STRERROR (errno)); 3531 MHD_socket_last_strerr_ ());
3532#endif 3532#endif
3533 if (0 != MHD_socket_close_ (socket_fd)) 3533 if (0 != MHD_socket_close_ (socket_fd))
3534 MHD_PANIC ("close failed\n"); 3534 MHD_PANIC ("close failed\n");
@@ -3543,7 +3543,7 @@ MHD_start_daemon_va (unsigned int flags,
3543#if HAVE_MESSAGES 3543#if HAVE_MESSAGES
3544 MHD_DLOG (daemon, 3544 MHD_DLOG (daemon,
3545 "Failed to make listen socket non-blocking: %s\n", 3545 "Failed to make listen socket non-blocking: %s\n",
3546 STRERROR (errno)); 3546 MHD_socket_last_strerr_ ());
3547#endif 3547#endif
3548 if (0 != MHD_socket_close_ (socket_fd)) 3548 if (0 != MHD_socket_close_ (socket_fd))
3549 MHD_PANIC ("close failed\n"); 3549 MHD_PANIC ("close failed\n");
@@ -3557,7 +3557,7 @@ MHD_start_daemon_va (unsigned int flags,
3557 if (0 != (flags & MHD_USE_DEBUG)) 3557 if (0 != (flags & MHD_USE_DEBUG))
3558 MHD_DLOG (daemon, 3558 MHD_DLOG (daemon,
3559 "Failed to listen for connections: %s\n", 3559 "Failed to listen for connections: %s\n",
3560 STRERROR (errno)); 3560 MHD_socket_last_strerr_ ());
3561#endif 3561#endif
3562 if (0 != MHD_socket_close_ (socket_fd)) 3562 if (0 != MHD_socket_close_ (socket_fd))
3563 MHD_PANIC ("close failed\n"); 3563 MHD_PANIC ("close failed\n");
@@ -3635,7 +3635,7 @@ MHD_start_daemon_va (unsigned int flags,
3635#if HAVE_MESSAGES 3635#if HAVE_MESSAGES
3636 MHD_DLOG (daemon, 3636 MHD_DLOG (daemon,
3637 "Failed to create listen thread: %s\n", 3637 "Failed to create listen thread: %s\n",
3638 STRERROR (res_thread_create)); 3638 MHD_strerror_ (res_thread_create));
3639#endif 3639#endif
3640 pthread_mutex_destroy (&daemon->cleanup_connection_mutex); 3640 pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
3641 pthread_mutex_destroy (&daemon->per_ip_connection_mutex); 3641 pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
@@ -3715,7 +3715,7 @@ MHD_start_daemon_va (unsigned int flags,
3715#if HAVE_MESSAGES 3715#if HAVE_MESSAGES
3716 MHD_DLOG (daemon, 3716 MHD_DLOG (daemon,
3717 "Failed to create worker control pipe: %s\n", 3717 "Failed to create worker control pipe: %s\n",
3718 STRERROR (errno)); 3718 MHD_strerror_ (errno));
3719#endif 3719#endif
3720 goto thread_failed; 3720 goto thread_failed;
3721 } 3721 }
@@ -3764,7 +3764,7 @@ MHD_start_daemon_va (unsigned int flags,
3764#if HAVE_MESSAGES 3764#if HAVE_MESSAGES
3765 MHD_DLOG (daemon, 3765 MHD_DLOG (daemon,
3766 "Failed to create pool thread: %s\n", 3766 "Failed to create pool thread: %s\n",
3767 STRERROR (res_thread_create)); 3767 MHD_strerror_ (res_thread_create));
3768#endif 3768#endif
3769 /* Free memory for this worker; cleanup below handles 3769 /* Free memory for this worker; cleanup below handles
3770 * all previously-created workers. */ 3770 * all previously-created workers. */
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 0fa6682a..c2a0441a 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -29,6 +29,7 @@
29 29
30#include "platform.h" 30#include "platform.h"
31#include "microhttpd.h" 31#include "microhttpd.h"
32#include "platform_interface.h"
32#if HTTPS_SUPPORT 33#if HTTPS_SUPPORT
33#include <gnutls/gnutls.h> 34#include <gnutls/gnutls.h>
34#if GNUTLS_VERSION_MAJOR >= 3 35#if GNUTLS_VERSION_MAJOR >= 3
diff --git a/src/platform/platform_interface.h b/src/platform/platform_interface.h
index 6e88be50..1fc3399e 100644
--- a/src/platform/platform_interface.h
+++ b/src/platform/platform_interface.h
@@ -26,6 +26,10 @@
26#ifndef MHD_PLATFORM_INTERFACE_H 26#ifndef MHD_PLATFORM_INTERFACE_H
27#define MHD_PLATFORM_INTERFACE_H 27#define MHD_PLATFORM_INTERFACE_H
28 28
29#if defined(_WIN32) && !defined(__CYGWIN__)
30#include "w32functions.h"
31#endif
32
29/* MHD_socket_close_(fd) close any FDs (non-W32) / close only socket FDs (W32) */ 33/* MHD_socket_close_(fd) close any FDs (non-W32) / close only socket FDs (W32) */
30#if !defined(_WIN32) || defined(__CYGWIN__) 34#if !defined(_WIN32) || defined(__CYGWIN__)
31#define MHD_socket_close_(fd) close((fd)) 35#define MHD_socket_close_(fd) close((fd))
@@ -33,4 +37,33 @@
33#define MHD_socket_close_(fd) closesocket((fd)) 37#define MHD_socket_close_(fd) closesocket((fd))
34#endif 38#endif
35 39
40/* MHD_socket_errno_ is errno of last function (non-W32) / errno of last socket function (W32) */
41#if !defined(_WIN32) || defined(__CYGWIN__)
42#define MHD_socket_errno_ errno
43#else
44#define MHD_socket_errno_ MHD_W32_errno_from_winsock_()
45#endif
46
47/* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
48 * description string of last socket error (W32) */
49#if !defined(_WIN32) || defined(__CYGWIN__)
50#define MHD_socket_last_strerr_() strerror(errno)
51#else
52#define MHD_socket_last_strerr_() MHD_W32_strerror_last_winsock_()
53#endif
54
55/* MHD_strerror_ is strerror (both non-W32/W32) */
56#if !defined(_WIN32) || defined(__CYGWIN__)
57#define MHD_strerror_(errnum) strerror((errnum))
58#else
59#define MHD_strerror_(errnum) MHD_W32_strerror_((errnum))
60#endif
61
62/* MHD_set_socket_errno_ set errno to errnum (non-W32) / set socket last error to errnum (W32) */
63#if !defined(_WIN32) || defined(__CYGWIN__)
64#define MHD_set_socket_errno_(errnum) errno=(errnum)
65#else
66#define MHD_set_socket_errno_(errnum) MHD_W32_set_last_winsock_error_((errnum))
67#endif
68
36#endif // MHD_PLATFORM_INTERFACE_H 69#endif // MHD_PLATFORM_INTERFACE_H
diff --git a/src/platform/w32functions.c b/src/platform/w32functions.c
new file mode 100644
index 00000000..a0b35dec
--- /dev/null
+++ b/src/platform/w32functions.c
@@ -0,0 +1,543 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2014 Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library.
17 If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file platform/w32functions.h
22 * @brief internal functions for W32 systems
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#include "w32functions.h"
27#include <errno.h>
28#include <winsock2.h>
29#include <string.h>
30
31/**
32 * Return errno equivalent of last winsock error
33 * @return errno equivalent of last winsock error
34 */
35int MHD_W32_errno_from_winsock_(void)
36{
37 switch(WSAGetLastError())
38 {
39 case 0: return 0;
40 case WSA_INVALID_HANDLE: return EBADF;
41 case WSA_NOT_ENOUGH_MEMORY: return ENOMEM;
42 case WSA_INVALID_PARAMETER: return EINVAL;
43 case WSAEINTR: return EINTR;
44 case WSAEWOULDBLOCK: return EWOULDBLOCK;
45 case WSAEINPROGRESS: return EINPROGRESS;
46 case WSAEALREADY: return EALREADY;
47 case WSAENOTSOCK: return ENOTSOCK;
48 case WSAEDESTADDRREQ: return EDESTADDRREQ;
49 case WSAEMSGSIZE: return EMSGSIZE;
50 case WSAEPROTOTYPE: return EPROTOTYPE;
51 case WSAENOPROTOOPT: return ENOPROTOOPT;
52 case WSAEPROTONOSUPPORT: return EPROTONOSUPPORT;
53 case WSAESOCKTNOSUPPORT: return ESOCKTNOSUPPORT;
54 case WSAEOPNOTSUPP: return EOPNOTSUPP;
55 case WSAEPFNOSUPPORT: return EPFNOSUPPORT;
56 case WSAEAFNOSUPPORT: return EAFNOSUPPORT;
57 case WSAEADDRINUSE: return EADDRINUSE;
58 case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL;
59 case WSAENETDOWN: return ENETDOWN;
60 case WSAENETUNREACH: return ENETUNREACH;
61 case WSAENETRESET: return ENETRESET;
62 case WSAECONNABORTED: return ECONNABORTED;
63 case WSAECONNRESET: return ECONNRESET;
64 case WSAENOBUFS: return ENOBUFS;
65 case WSAEISCONN: return EISCONN;
66 case WSAENOTCONN: return ENOTCONN;
67 case WSAESHUTDOWN: return ESHUTDOWN;
68 case WSAETOOMANYREFS: return ETOOMANYREFS;
69 case WSAETIMEDOUT: return ETIMEDOUT;
70 case WSAECONNREFUSED: return ECONNREFUSED;
71 case WSAELOOP: return ELOOP;
72 case WSAENAMETOOLONG: return ENAMETOOLONG;
73 case WSAEHOSTDOWN: return EHOSTDOWN;
74 case WSAEHOSTUNREACH: return EHOSTUNREACH;
75 case WSAENOTEMPTY: return ENOTEMPTY;
76 case WSAEPROCLIM: return EPROCLIM;
77 case WSAEUSERS: return EUSERS;
78 case WSAEDQUOT: return EDQUOT;
79 case WSAESTALE: return ESTALE;
80 case WSAEREMOTE: return EREMOTE;
81 case WSAEINVAL: return EINVAL;
82 case WSAEFAULT: return EFAULT;
83 case WSANO_DATA: return ENODATA;
84 /* Rough equivalents */
85 case WSAEDISCON: return ECONNRESET;
86 case WSAEINVALIDPROCTABLE: return EFAULT;
87 case WSASYSNOTREADY:
88 case WSANOTINITIALISED:
89 case WSASYSCALLFAILURE: return ENOBUFS;
90 case WSAVERNOTSUPPORTED: return EOPNOTSUPP;
91 case WSAEREFUSED: return EIO;
92 }
93 return EINVAL;
94}
95
96/**
97 * Return pointer to string description of errnum error
98 * Works fine with both standard errno errnums
99 * and errnums from MHD_W32_errno_from_winsock_
100 * @param errnum the errno or value from MHD_W32_errno_from_winsock_()
101 * @return pointer to string description of error
102 */
103const char* MHD_W32_strerror_(int errnum)
104{
105 switch(errnum)
106 {
107 case 0:
108 return "No error";
109 case EWOULDBLOCK:
110 return "Operation would block";
111 case EINPROGRESS:
112 return "Connection already in progress";
113 case EALREADY:
114 return "Socket already connected";
115 case ENOTSOCK:
116 return "Socket operation on non-socket";
117 case EDESTADDRREQ:
118 return "Destination address required";
119 case EMSGSIZE:
120 return "Message too long";
121 case EPROTOTYPE:
122 return "Protocol wrong type for socket";
123 case ENOPROTOOPT:
124 return "Protocol not available";
125 case EPROTONOSUPPORT:
126 return "Unknown protocol";
127 case ESOCKTNOSUPPORT:
128 return "Socket type not supported";
129 case EOPNOTSUPP:
130 return "Operation not supported on socket";
131 case EPFNOSUPPORT:
132 return "Protocol family not supported";
133 case EAFNOSUPPORT:
134 return "Address family not supported by protocol family";
135 case EADDRINUSE:
136 return "Address already in use";
137 case EADDRNOTAVAIL:
138 return "Cannot assign requested address";
139 case ENETDOWN:
140 return "Network is down";
141 case ENETUNREACH:
142 return "Network is unreachable";
143 case ENETRESET:
144 return "Network dropped connection on reset";
145 case ECONNABORTED:
146 return "Software caused connection abort";
147 case ECONNRESET:
148 return "Connection reset by peer";
149 case ENOBUFS:
150 return "No system resources available";
151 case EISCONN:
152 return "Socket is already connected";
153 case ENOTCONN:
154 return "Socket is not connected";
155 case ESHUTDOWN:
156 return "Can't send after socket shutdown";
157 case ETOOMANYREFS:
158 return "Too many references: cannot splice";
159 case ETIMEDOUT:
160 return "Connection timed out";
161 case ECONNREFUSED:
162 return "Connection refused";
163 case ELOOP:
164 return "Cannot translate name";
165 case EHOSTDOWN:
166 return "Host is down";
167 case EHOSTUNREACH:
168 return "Host is unreachable";
169 case EPROCLIM:
170 return "Too many processes";
171 case EUSERS:
172 return "Too many users";
173 case EDQUOT:
174 return "Disk quota exceeded";
175 case ESTALE:
176 return "Stale file handle reference";
177 case EREMOTE:
178 return "Resource is remote";
179 case ENODATA:
180 return "No data available";
181 }
182 return strerror(errnum);
183}
184
185/**
186 * Return pointer to string description of last winsock error
187 * @return pointer to string description of last winsock error
188 */
189const char* MHD_W32_strerror_last_winsock_(void)
190{
191 switch (WSAGetLastError())
192 {
193 case 0:
194 return "No error";
195 case WSA_INVALID_HANDLE:
196 return "Specified event object handle is invalid";
197 case WSA_NOT_ENOUGH_MEMORY:
198 return "Insufficient memory available";
199 case WSA_INVALID_PARAMETER:
200 return "One or more parameters are invalid";
201 case WSA_OPERATION_ABORTED:
202 return "Overlapped operation aborted";
203 case WSA_IO_INCOMPLETE:
204 return "Overlapped I/O event object not in signaled state";
205 case WSA_IO_PENDING:
206 return "Overlapped operations will complete later";
207 case WSAEINTR:
208 return "Interrupted function call";
209 case WSAEBADF:
210 return "File handle is not valid";
211 case WSAEACCES:
212 return "Permission denied";
213 case WSAEFAULT:
214 return "Bad address";
215 case WSAEINVAL:
216 return "Invalid argument";
217 case WSAEMFILE:
218 return "Too many open files";
219 case WSAEWOULDBLOCK:
220 return "Resource temporarily unavailable";
221 case WSAEINPROGRESS:
222 return "Operation now in progress";
223 case WSAEALREADY:
224 return "Operation already in progress";
225 case WSAENOTSOCK:
226 return "Socket operation on nonsocket";
227 case WSAEDESTADDRREQ:
228 return "Destination address required";
229 case WSAEMSGSIZE:
230 return "Message too long";
231 case WSAEPROTOTYPE:
232 return "Protocol wrong type for socket";
233 case WSAENOPROTOOPT:
234 return "Bad protocol option";
235 case WSAEPROTONOSUPPORT:
236 return "Protocol not supported";
237 case WSAESOCKTNOSUPPORT:
238 return "Socket type not supported";
239 case WSAEOPNOTSUPP:
240 return "Operation not supported";
241 case WSAEPFNOSUPPORT:
242 return "Protocol family not supported";
243 case WSAEAFNOSUPPORT:
244 return "Address family not supported by protocol family";
245 case WSAEADDRINUSE:
246 return "Address already in use";
247 case WSAEADDRNOTAVAIL:
248 return "Cannot assign requested address";
249 case WSAENETDOWN:
250 return "Network is down";
251 case WSAENETUNREACH:
252 return "Network is unreachable";
253 case WSAENETRESET:
254 return "Network dropped connection on reset";
255 case WSAECONNABORTED:
256 return "Software caused connection abort";
257 case WSAECONNRESET:
258 return "Connection reset by peer";
259 case WSAENOBUFS:
260 return "No buffer space available";
261 case WSAEISCONN:
262 return "Socket is already connected";
263 case WSAENOTCONN:
264 return "Socket is not connected";
265 case WSAESHUTDOWN:
266 return "Cannot send after socket shutdown";
267 case WSAETOOMANYREFS:
268 return "Too many references";
269 case WSAETIMEDOUT:
270 return "Connection timed out";
271 case WSAECONNREFUSED:
272 return "Connection refused";
273 case WSAELOOP:
274 return "Cannot translate name";
275 case WSAENAMETOOLONG:
276 return "Name too long";
277 case WSAEHOSTDOWN:
278 return "Host is down";
279 case WSAEHOSTUNREACH:
280 return "No route to host";
281 case WSAENOTEMPTY:
282 return "Directory not empty";
283 case WSAEPROCLIM:
284 return "Too many processes";
285 case WSAEUSERS:
286 return "User quota exceeded";
287 case WSAEDQUOT:
288 return "Disk quota exceeded";
289 case WSAESTALE:
290 return "Stale file handle reference";
291 case WSAEREMOTE:
292 return "Item is remote";
293 case WSASYSNOTREADY:
294 return "Network subsystem is unavailable";
295 case WSAVERNOTSUPPORTED:
296 return "Winsock.dll version out of range";
297 case WSANOTINITIALISED:
298 return "Successful WSAStartup not yet performed";
299 case WSAEDISCON:
300 return "Graceful shutdown in progress";
301 case WSAENOMORE:
302 return "No more results";
303 case WSAECANCELLED:
304 return "Call has been canceled";
305 case WSAEINVALIDPROCTABLE:
306 return "Procedure call table is invalid";
307 case WSAEINVALIDPROVIDER:
308 return "Service provider is invalid";
309 case WSAEPROVIDERFAILEDINIT:
310 return "Service provider failed to initialize";
311 case WSASYSCALLFAILURE:
312 return "System call failure";
313 case WSASERVICE_NOT_FOUND:
314 return "Service not found";
315 case WSATYPE_NOT_FOUND:
316 return "Class type not found";
317 case WSA_E_NO_MORE:
318 return "No more results";
319 case WSA_E_CANCELLED:
320 return "Call was canceled";
321 case WSAEREFUSED:
322 return "Database query was refused";
323 case WSAHOST_NOT_FOUND:
324 return "Host not found";
325 case WSATRY_AGAIN:
326 return "Nonauthoritative host not found";
327 case WSANO_RECOVERY:
328 return "This is a nonrecoverable error";
329 case WSANO_DATA:
330 return "Valid name, no data record of requested type";
331 case WSA_QOS_RECEIVERS:
332 return "QoS receivers";
333 case WSA_QOS_SENDERS:
334 return "QoS senders";
335 case WSA_QOS_NO_SENDERS:
336 return "No QoS senders";
337 case WSA_QOS_NO_RECEIVERS:
338 return "QoS no receivers";
339 case WSA_QOS_REQUEST_CONFIRMED:
340 return "QoS request confirmed";
341 case WSA_QOS_ADMISSION_FAILURE:
342 return "QoS admission error";
343 case WSA_QOS_POLICY_FAILURE:
344 return "QoS policy failure";
345 case WSA_QOS_BAD_STYLE:
346 return "QoS bad style";
347 case WSA_QOS_BAD_OBJECT:
348 return "QoS bad object";
349 case WSA_QOS_TRAFFIC_CTRL_ERROR:
350 return "QoS traffic control error";
351 case WSA_QOS_GENERIC_ERROR:
352 return "QoS generic error";
353 case WSA_QOS_ESERVICETYPE:
354 return "QoS service type error";
355 case WSA_QOS_EFLOWSPEC:
356 return "QoS flowspec error";
357 case WSA_QOS_EPROVSPECBUF:
358 return "Invalid QoS provider buffer";
359 case WSA_QOS_EFILTERSTYLE:
360 return "Invalid QoS filter style";
361 case WSA_QOS_EFILTERTYPE:
362 return "Invalid QoS filter type";
363 case WSA_QOS_EFILTERCOUNT:
364 return "Incorrect QoS filter count";
365 case WSA_QOS_EOBJLENGTH:
366 return "Invalid QoS object length";
367 case WSA_QOS_EFLOWCOUNT:
368 return "Incorrect QoS flow count";
369 case WSA_QOS_EUNKOWNPSOBJ:
370 return "Unrecognized QoS object";
371 case WSA_QOS_EPOLICYOBJ:
372 return "Invalid QoS policy object";
373 case WSA_QOS_EFLOWDESC:
374 return "Invalid QoS flow descriptor";
375 case WSA_QOS_EPSFLOWSPEC:
376 return "Invalid QoS provider-specific flowspec";
377 case WSA_QOS_EPSFILTERSPEC:
378 return "Invalid QoS provider-specific filterspec";
379 case WSA_QOS_ESDMODEOBJ:
380 return "Invalid QoS shape discard mode object";
381 case WSA_QOS_ESHAPERATEOBJ:
382 return "Invalid QoS shaping rate object";
383 case WSA_QOS_RESERVED_PETYPE:
384 return "Reserved policy QoS element type";
385 }
386 return "Unknown winsock error";
387}
388
389/**
390 * Set last winsock error to equivalent of given errno value
391 * @param errnum the errno value to set
392 */
393void MHD_W32_set_last_winsock_error_(int errnum)
394{
395 switch (errnum)
396 {
397 case 0:
398 WSASetLastError(0);
399 break;
400 case EBADF:
401 WSASetLastError(WSA_INVALID_HANDLE);
402 break;
403 case ENOMEM:
404 WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
405 break;
406 case EINVAL:
407 WSASetLastError(WSA_INVALID_PARAMETER);
408 break;
409 case EINTR:
410 WSASetLastError(WSAEINTR);
411 break;
412 case EWOULDBLOCK:
413 WSASetLastError(WSAEWOULDBLOCK);
414 break;
415 case EINPROGRESS:
416 WSASetLastError(WSAEINPROGRESS);
417 break;
418 case EALREADY:
419 WSASetLastError(WSAEALREADY);
420 break;
421 case ENOTSOCK:
422 WSASetLastError(WSAENOTSOCK);
423 break;
424 case EDESTADDRREQ:
425 WSASetLastError(WSAEDESTADDRREQ);
426 break;
427 case EMSGSIZE:
428 WSASetLastError(WSAEMSGSIZE);
429 break;
430 case EPROTOTYPE:
431 WSASetLastError(WSAEPROTOTYPE);
432 break;
433 case ENOPROTOOPT:
434 WSASetLastError(WSAENOPROTOOPT);
435 break;
436 case EPROTONOSUPPORT:
437 WSASetLastError(WSAEPROTONOSUPPORT);
438 break;
439 case ESOCKTNOSUPPORT:
440 WSASetLastError(WSAESOCKTNOSUPPORT);
441 break;
442 case EOPNOTSUPP:
443 WSASetLastError(WSAEOPNOTSUPP);
444 break;
445 case EPFNOSUPPORT:
446 WSASetLastError(WSAEPFNOSUPPORT);
447 break;
448 case EAFNOSUPPORT:
449 WSASetLastError(WSAEAFNOSUPPORT);
450 break;
451 case EADDRINUSE:
452 WSASetLastError(WSAEADDRINUSE);
453 break;
454 case EADDRNOTAVAIL:
455 WSASetLastError(WSAEADDRNOTAVAIL);
456 break;
457 case ENETDOWN:
458 WSASetLastError(WSAENETDOWN);
459 break;
460 case ENETUNREACH:
461 WSASetLastError(WSAENETUNREACH);
462 break;
463 case ENETRESET:
464 WSASetLastError(WSAENETRESET);
465 break;
466 case ECONNABORTED:
467 WSASetLastError(WSAECONNABORTED);
468 break;
469 case ECONNRESET:
470 WSASetLastError(WSAECONNRESET);
471 break;
472 case ENOBUFS:
473 WSASetLastError(WSAENOBUFS);
474 break;
475 case EISCONN:
476 WSASetLastError(WSAEISCONN);
477 break;
478 case ENOTCONN:
479 WSASetLastError(WSAENOTCONN);
480 break;
481 case ESHUTDOWN:
482 WSASetLastError(WSAESHUTDOWN);
483 break;
484 case ETOOMANYREFS:
485 WSASetLastError(WSAETOOMANYREFS);
486 break;
487 case ETIMEDOUT:
488 WSASetLastError(WSAETIMEDOUT);
489 break;
490 case ECONNREFUSED:
491 WSASetLastError(WSAECONNREFUSED);
492 break;
493 case ELOOP:
494 WSASetLastError(WSAELOOP);
495 break;
496 case ENAMETOOLONG:
497 WSASetLastError(WSAENAMETOOLONG);
498 break;
499 case EHOSTDOWN:
500 WSASetLastError(WSAEHOSTDOWN);
501 break;
502 case EHOSTUNREACH:
503 WSASetLastError(WSAEHOSTUNREACH);
504 break;
505 case ENOTEMPTY:
506 WSASetLastError(WSAENOTEMPTY);
507 break;
508 case EPROCLIM:
509 WSASetLastError(WSAEPROCLIM);
510 break;
511 case EUSERS:
512 WSASetLastError(WSAEUSERS);
513 break;
514 case EDQUOT:
515 WSASetLastError(WSAEDQUOT);
516 break;
517 case ESTALE:
518 WSASetLastError(WSAESTALE);
519 break;
520 case EREMOTE:
521 WSASetLastError(WSAEREMOTE);
522 break;
523 case EFAULT:
524 WSASetLastError(WSAEFAULT);
525 break;
526 case ENODATA:
527 WSASetLastError(WSANO_DATA);
528 break;
529#if EAGAIN != EWOULDBLOCK
530 case EAGAIN:
531 WSASetLastError(WSAEWOULDBLOCK);
532 break;
533#endif
534 /* Rough equivalent */
535 case EIO:
536 WSASetLastError(WSAEREFUSED);
537 break;
538
539 default: /* Unmapped errors */
540 WSASetLastError(WSAENOBUFS);
541 break;
542 }
543}
diff --git a/src/platform/w32functions.h b/src/platform/w32functions.h
new file mode 100644
index 00000000..d780db65
--- /dev/null
+++ b/src/platform/w32functions.h
@@ -0,0 +1,176 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2014 Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library.
17 If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file platform/w32functions.h
22 * @brief internal functions for W32 systems
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#ifndef MHD_W32FUNCTIONS_H
27#define MHD_W32FUNCTIONS_H
28#ifndef _WIN32
29#error w32functions.h is designed only for W32 systems
30#endif
31
32#include <errno.h>
33#include <winsock2.h>
34#include "platform.h"
35
36#ifdef __cplusplus
37extern "C"
38{
39#endif
40
41#define MHDW32ERRBASE 3300
42
43#ifndef EWOULDBLOCK
44#define EWOULDBLOCK (MHDW32ERRBASE+1)
45#endif
46#ifndef EINPROGRESS
47#define EINPROGRESS (MHDW32ERRBASE+2)
48#endif
49#ifndef EALREADY
50#define EALREADY (MHDW32ERRBASE+3)
51#endif
52#ifndef ENOTSOCK
53#define ENOTSOCK (MHDW32ERRBASE+4)
54#endif
55#ifndef EDESTADDRREQ
56#define EDESTADDRREQ (MHDW32ERRBASE+5)
57#endif
58#ifndef EMSGSIZE
59#define EMSGSIZE (MHDW32ERRBASE+6)
60#endif
61#ifndef EPROTOTYPE
62#define EPROTOTYPE (MHDW32ERRBASE+7)
63#endif
64#ifndef ENOPROTOOPT
65#define ENOPROTOOPT (MHDW32ERRBASE+8)
66#endif
67#ifndef EPROTONOSUPPORT
68#define EPROTONOSUPPORT (MHDW32ERRBASE+9)
69#endif
70#ifndef EOPNOTSUPP
71#define EOPNOTSUPP (MHDW32ERRBASE+10)
72#endif
73#ifndef EAFNOSUPPORT
74#define EAFNOSUPPORT (MHDW32ERRBASE+11)
75#endif
76#ifndef EADDRINUSE
77#define EADDRINUSE (MHDW32ERRBASE+12)
78#endif
79#ifndef EADDRNOTAVAIL
80#define EADDRNOTAVAIL (MHDW32ERRBASE+13)
81#endif
82#ifndef ENETDOWN
83#define ENETDOWN (MHDW32ERRBASE+14)
84#endif
85#ifndef ENETUNREACH
86#define ENETUNREACH (MHDW32ERRBASE+15)
87#endif
88#ifndef ENETRESET
89#define ENETRESET (MHDW32ERRBASE+16)
90#endif
91#ifndef ECONNABORTED
92#define ECONNABORTED (MHDW32ERRBASE+17)
93#endif
94#ifndef ECONNRESET
95#define ECONNRESET (MHDW32ERRBASE+18)
96#endif
97#ifndef ENOBUFS
98#define ENOBUFS (MHDW32ERRBASE+19)
99#endif
100#ifndef EISCONN
101#define EISCONN (MHDW32ERRBASE+20)
102#endif
103#ifndef ENOTCONN
104#define ENOTCONN (MHDW32ERRBASE+21)
105#endif
106#ifndef ETOOMANYREFS
107#define ETOOMANYREFS (MHDW32ERRBASE+22)
108#endif
109#ifndef ECONNREFUSED
110#define ECONNREFUSED (MHDW32ERRBASE+23)
111#endif
112#ifndef ELOOP
113#define ELOOP (MHDW32ERRBASE+24)
114#endif
115#ifndef EHOSTDOWN
116#define EHOSTDOWN (MHDW32ERRBASE+25)
117#endif
118#ifndef EHOSTUNREACH
119#define EHOSTUNREACH (MHDW32ERRBASE+26)
120#endif
121#ifndef EPROCLIM
122#define EPROCLIM (MHDW32ERRBASE+27)
123#endif
124#ifndef EUSERS
125#define EUSERS (MHDW32ERRBASE+28)
126#endif
127#ifndef EDQUOT
128#define EDQUOT (MHDW32ERRBASE+29)
129#endif
130#ifndef ESTALE
131#define ESTALE (MHDW32ERRBASE+30)
132#endif
133#ifndef EREMOTE
134#define EREMOTE (MHDW32ERRBASE+31)
135#endif
136#ifndef ESOCKTNOSUPPORT
137#define ESOCKTNOSUPPORT (MHDW32ERRBASE+32)
138#endif
139#ifndef EPFNOSUPPORT
140#define EPFNOSUPPORT (MHDW32ERRBASE+33)
141#endif
142#ifndef ESHUTDOWN
143#define ESHUTDOWN (MHDW32ERRBASE+34)
144#endif
145#ifndef ENODATA
146#define ENODATA (MHDW32ERRBASE+35)
147#endif
148
149/**
150 * Return errno equivalent of last winsock error
151 * @return errno equivalent of last winsock error
152 */
153int MHD_W32_errno_from_winsock_(void);
154/**
155 * Return pointer to string description of errnum error
156 * Works fine with both standard errno errnums
157 * and errnums from MHD_W32_errno_from_winsock_
158 * @param errnum the errno or value from MHD_W32_errno_from_winsock_()
159 * @return pointer to string description of error
160 */
161const char* MHD_W32_strerror_(int errnum);
162/**
163 * Return pointer to string description of last winsock error
164 * @return pointer to string description of last winsock error
165 */
166const char* MHD_W32_strerror_last_winsock_(void);
167/**
168 * Set last winsock error to equivalent of given errno value
169 * @param errnum the errno value to set
170 */
171void MHD_W32_set_last_winsock_error_(int errnum);
172
173#ifdef __cplusplus
174}
175#endif
176#endif //MHD_W32FUNCTIONS_H
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 7ec4ff68..33e95d36 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -137,7 +137,12 @@ test_digestauth_with_arguments_LDADD = \
137 @LIBCURL@ @LIBGCRYPT_LIBS@ 137 @LIBCURL@ @LIBGCRYPT_LIBS@
138 138
139test_get_sendfile_SOURCES = \ 139test_get_sendfile_SOURCES = \
140 test_get_sendfile.c 140 test_get_sendfile.c \
141 ../platform/platform_interface.h
142if HAVE_W32
143test_get_sendfile_SOURCES += \
144 ../platform/w32functions.h ../platform/w32functions.c
145endif
141test_get_sendfile_LDADD = \ 146test_get_sendfile_LDADD = \
142 $(top_builddir)/src/microhttpd/libmicrohttpd.la \ 147 $(top_builddir)/src/microhttpd/libmicrohttpd.la \
143 @LIBCURL@ 148 @LIBCURL@
@@ -215,6 +220,10 @@ test_get11_LDADD = \
215 220
216test_get_sendfile11_SOURCES = \ 221test_get_sendfile11_SOURCES = \
217 test_get_sendfile.c 222 test_get_sendfile.c
223if HAVE_W32
224test_get_sendfile11_SOURCES += \
225 ../platform/w32functions.h ../platform/w32functions.c
226endif
218test_get_sendfile11_LDADD = \ 227test_get_sendfile11_LDADD = \
219 $(top_builddir)/src/microhttpd/libmicrohttpd.la \ 228 $(top_builddir)/src/microhttpd/libmicrohttpd.la \
220 @LIBCURL@ 229 @LIBCURL@
diff --git a/src/testcurl/test_get_sendfile.c b/src/testcurl/test_get_sendfile.c
index 7f85458c..d073fee3 100644
--- a/src/testcurl/test_get_sendfile.c
+++ b/src/testcurl/test_get_sendfile.c
@@ -26,6 +26,7 @@
26 26
27#include "MHD_config.h" 27#include "MHD_config.h"
28#include "platform.h" 28#include "platform.h"
29#include "platform_interface.h"
29#include <curl/curl.h> 30#include <curl/curl.h>
30#include <microhttpd.h> 31#include <microhttpd.h>
31#include <stdlib.h> 32#include <stdlib.h>
@@ -93,7 +94,7 @@ ahc_echo (void *cls,
93 { 94 {
94 fprintf (stderr, "Failed to open `%s': %s\n", 95 fprintf (stderr, "Failed to open `%s': %s\n",
95 sourcefile, 96 sourcefile,
96 STRERROR (errno)); 97 MHD_strerror_ (errno));
97 exit (1); 98 exit (1);
98 } 99 }
99 response = MHD_create_response_from_fd (strlen (TESTSTR), fd); 100 response = MHD_create_response_from_fd (strlen (TESTSTR), fd);