aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-08-23 20:13:10 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-08-23 20:13:10 +0000
commit515c50a1fa2706b2d0cd9687c381662e39b30be8 (patch)
treef1b12a1a332c10673b413f8d2e74882212176af0
parenta3fc78c87acc9a411959115c071f60adf54a2e11 (diff)
downloadlibmicrohttpd-515c50a1fa2706b2d0cd9687c381662e39b30be8.tar.gz
libmicrohttpd-515c50a1fa2706b2d0cd9687c381662e39b30be8.zip
mhd_sockets: better sockets errors abstraction, improved performance on W32
-rw-r--r--src/microhttpd/connection.c22
-rw-r--r--src/microhttpd/daemon.c77
-rw-r--r--src/microhttpd/mhd_compat.h6
-rw-r--r--src/microhttpd/mhd_sockets.c318
-rw-r--r--src/microhttpd/mhd_sockets.h434
5 files changed, 339 insertions, 518 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 2c799d16..7c0ce674 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1855,10 +1855,10 @@ do_read (struct MHD_Connection *connection)
1855 connection->read_buffer_offset); 1855 connection->read_buffer_offset);
1856 if (bytes_read < 0) 1856 if (bytes_read < 0)
1857 { 1857 {
1858 const int err = MHD_socket_errno_; 1858 const int err = MHD_socket_get_error_ ();
1859 if ((EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err)) 1859 if (MHD_SCKT_ERR_IS_EINTR_ (err) || MHD_SCKT_ERR_IS_EAGAIN_ (err))
1860 return MHD_NO; 1860 return MHD_NO;
1861 if (ECONNRESET == err) 1861 if (MHD_SCKT_ERR_IS_REMOTE_DISCNN_ (err))
1862 { 1862 {
1863 CONNECTION_CLOSE_ERROR (connection, NULL); 1863 CONNECTION_CLOSE_ERROR (connection, NULL);
1864 return MHD_NO; 1864 return MHD_NO;
@@ -1902,8 +1902,8 @@ do_write (struct MHD_Connection *connection)
1902 1902
1903 if (ret < 0) 1903 if (ret < 0)
1904 { 1904 {
1905 const int err = MHD_socket_errno_; 1905 const int err = MHD_socket_get_error_ ();
1906 if ((EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err)) 1906 if (MHD_SCKT_ERR_IS_EINTR_ (err) || MHD_SCKT_ERR_IS_EAGAIN_ (err))
1907 return MHD_NO; 1907 return MHD_NO;
1908 CONNECTION_CLOSE_ERROR (connection, NULL); 1908 CONNECTION_CLOSE_ERROR (connection, NULL);
1909 return MHD_YES; 1909 return MHD_YES;
@@ -2276,13 +2276,13 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2276 connection->continue_message_write_offset); 2276 connection->continue_message_write_offset);
2277 if (ret < 0) 2277 if (ret < 0)
2278 { 2278 {
2279 const int err = MHD_socket_errno_; 2279 const int err = MHD_socket_get_error_ ();
2280 if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err)) 2280 if (MHD_SCKT_ERR_IS_EINTR_ (err) || MHD_SCKT_ERR_IS_EAGAIN_ (err))
2281 break; 2281 break;
2282#ifdef HAVE_MESSAGES 2282#ifdef HAVE_MESSAGES
2283 MHD_DLOG (connection->daemon, 2283 MHD_DLOG (connection->daemon,
2284 "Failed to send data: %s\n", 2284 "Failed to send data: %s\n",
2285 MHD_socket_last_strerr_ ()); 2285 MHD_socket_strerr_ (err));
2286#endif 2286#endif
2287 CONNECTION_CLOSE_ERROR (connection, NULL); 2287 CONNECTION_CLOSE_ERROR (connection, NULL);
2288 return MHD_YES; 2288 return MHD_YES;
@@ -2330,7 +2330,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2330 [(size_t)data_write_offset], 2330 [(size_t)data_write_offset],
2331 response->data_size - 2331 response->data_size -
2332 (size_t)data_write_offset); 2332 (size_t)data_write_offset);
2333 err = MHD_socket_errno_; 2333 err = MHD_socket_get_error_ ();
2334#if DEBUG_SEND_DATA 2334#if DEBUG_SEND_DATA
2335 if (ret > 0) 2335 if (ret > 0)
2336 fprintf (stderr, 2336 fprintf (stderr,
@@ -2344,12 +2344,12 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2344 (void) MHD_mutex_unlock_ (&response->mutex); 2344 (void) MHD_mutex_unlock_ (&response->mutex);
2345 if (ret < 0) 2345 if (ret < 0)
2346 { 2346 {
2347 if ((err == EINTR) || (err == EAGAIN) || (EWOULDBLOCK == err)) 2347 if (MHD_SCKT_ERR_IS_EINTR_ (err) || MHD_SCKT_ERR_IS_EAGAIN_ (err))
2348 return MHD_YES; 2348 return MHD_YES;
2349#ifdef HAVE_MESSAGES 2349#ifdef HAVE_MESSAGES
2350 MHD_DLOG (connection->daemon, 2350 MHD_DLOG (connection->daemon,
2351 "Failed to send data: %s\n", 2351 "Failed to send data: %s\n",
2352 MHD_socket_last_strerr_ ()); 2352 MHD_socket_strerr_ (err));
2353#endif 2353#endif
2354 CONNECTION_CLOSE_ERROR (connection, NULL); 2354 CONNECTION_CLOSE_ERROR (connection, NULL);
2355 return MHD_YES; 2355 return MHD_YES;
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 7a784daf..68491938 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -457,7 +457,7 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
457 if ( (GNUTLS_E_AGAIN == res) || 457 if ( (GNUTLS_E_AGAIN == res) ||
458 (GNUTLS_E_INTERRUPTED == res) ) 458 (GNUTLS_E_INTERRUPTED == res) )
459 { 459 {
460 MHD_set_socket_errno_ (EINTR); 460 MHD_socket_set_error_ (MHD_SCKT_EINTR_);
461#if EPOLL_SUPPORT 461#if EPOLL_SUPPORT
462 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 462 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
463#endif 463#endif
@@ -468,7 +468,7 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
468 /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication 468 /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
469 disrupted); set errno to something caller will interpret 469 disrupted); set errno to something caller will interpret
470 correctly as a hard error */ 470 correctly as a hard error */
471 MHD_set_socket_errno_ (ECONNRESET); 471 MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_);
472 return res; 472 return res;
473 } 473 }
474 if ((size_t)res == i) 474 if ((size_t)res == i)
@@ -498,7 +498,7 @@ send_tls_adapter (struct MHD_Connection *connection,
498 if ( (GNUTLS_E_AGAIN == res) || 498 if ( (GNUTLS_E_AGAIN == res) ||
499 (GNUTLS_E_INTERRUPTED == res) ) 499 (GNUTLS_E_INTERRUPTED == res) )
500 { 500 {
501 MHD_set_socket_errno_ (EINTR); 501 MHD_socket_set_error_ (MHD_SCKT_EINTR_);
502#if EPOLL_SUPPORT 502#if EPOLL_SUPPORT
503 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 503 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
504#endif 504#endif
@@ -510,7 +510,7 @@ send_tls_adapter (struct MHD_Connection *connection,
510 really understand the error (not listed in GnuTLS 510 really understand the error (not listed in GnuTLS
511 documentation explicitly), we set 'errno' to something that 511 documentation explicitly), we set 'errno' to something that
512 will cause the connection to fail. */ 512 will cause the connection to fail. */
513 MHD_set_socket_errno_ (ECONNRESET); 513 MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_);
514 return -1; 514 return -1;
515 } 515 }
516 return res; 516 return res;
@@ -971,13 +971,14 @@ MHD_handle_connection (void *data)
971 num_ready = MHD_SYS_select_ (maxsock + 1, &rs, &ws, NULL, tvp); 971 num_ready = MHD_SYS_select_ (maxsock + 1, &rs, &ws, NULL, tvp);
972 if (num_ready < 0) 972 if (num_ready < 0)
973 { 973 {
974 if (EINTR == MHD_socket_errno_) 974 const int err = MHD_socket_get_error_();
975 if (MHD_SCKT_ERR_IS_EINTR_(err))
975 continue; 976 continue;
976#ifdef HAVE_MESSAGES 977#ifdef HAVE_MESSAGES
977 MHD_DLOG (con->daemon, 978 MHD_DLOG (con->daemon,
978 "Error during select (%d): `%s'\n", 979 "Error during select (%d): `%s'\n",
979 MHD_socket_errno_, 980 err,
980 MHD_socket_last_strerr_ ()); 981 MHD_socket_strerr_ (err));
981#endif 982#endif
982 break; 983 break;
983 } 984 }
@@ -1039,7 +1040,7 @@ MHD_handle_connection (void *data)
1039#endif 1040#endif
1040 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) 1041 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
1041 { 1042 {
1042 if (EINTR == MHD_socket_errno_) 1043 if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_))
1043 continue; 1044 continue;
1044#ifdef HAVE_MESSAGES 1045#ifdef HAVE_MESSAGES
1045 MHD_DLOG (con->daemon, 1046 MHD_DLOG (con->daemon,
@@ -1117,7 +1118,7 @@ recv_param_adapter (struct MHD_Connection *connection,
1117 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 1118 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
1118 (MHD_CONNECTION_CLOSED == connection->state) ) 1119 (MHD_CONNECTION_CLOSED == connection->state) )
1119 { 1120 {
1120 MHD_set_socket_errno_ (ENOTCONN); 1121 MHD_socket_set_error_ (MHD_SCKT_ENOTCONN_);
1121 return -1; 1122 return -1;
1122 } 1123 }
1123#ifdef MHD_POSIX_SOCKETS 1124#ifdef MHD_POSIX_SOCKETS
@@ -1133,7 +1134,7 @@ recv_param_adapter (struct MHD_Connection *connection,
1133 (_MHD_socket_funcs_size) i, 1134 (_MHD_socket_funcs_size) i,
1134 MSG_NOSIGNAL); 1135 MSG_NOSIGNAL);
1135#if EPOLL_SUPPORT 1136#if EPOLL_SUPPORT
1136 if ( (0 > ret) && (EAGAIN == MHD_socket_errno_) ) 1137 if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())) )
1137 { 1138 {
1138 /* Got EAGAIN --- no longer read-ready */ 1139 /* Got EAGAIN --- no longer read-ready */
1139 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; 1140 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
@@ -1157,6 +1158,7 @@ send_param_adapter (struct MHD_Connection *connection,
1157 size_t i) 1158 size_t i)
1158{ 1159{
1159 ssize_t ret; 1160 ssize_t ret;
1161 int err;
1160#if LINUX 1162#if LINUX
1161 MHD_socket fd; 1163 MHD_socket fd;
1162#endif 1164#endif
@@ -1164,7 +1166,7 @@ send_param_adapter (struct MHD_Connection *connection,
1164 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 1166 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
1165 (MHD_CONNECTION_CLOSED == connection->state) ) 1167 (MHD_CONNECTION_CLOSED == connection->state) )
1166 { 1168 {
1167 MHD_set_socket_errno_ (ENOTCONN); 1169 MHD_socket_set_error_ (MHD_SCKT_ENOTCONN_);
1168 return -1; 1170 return -1;
1169 } 1171 }
1170#ifdef MHD_POSIX_SOCKETS 1172#ifdef MHD_POSIX_SOCKETS
@@ -1189,7 +1191,6 @@ send_param_adapter (struct MHD_Connection *connection,
1189 /* can use sendfile */ 1191 /* can use sendfile */
1190 uint64_t left; 1192 uint64_t left;
1191 uint64_t offsetu64; 1193 uint64_t offsetu64;
1192 int err;
1193#ifndef HAVE_SENDFILE64 1194#ifndef HAVE_SENDFILE64
1194 off_t offset; 1195 off_t offset;
1195#else /* HAVE_SENDFILE64 */ 1196#else /* HAVE_SENDFILE64 */
@@ -1198,7 +1199,7 @@ send_param_adapter (struct MHD_Connection *connection,
1198 offsetu64 = connection->response_write_position + connection->response->fd_off; 1199 offsetu64 = connection->response_write_position + connection->response->fd_off;
1199 left = connection->response->total_size - connection->response_write_position; 1200 left = connection->response->total_size - connection->response_write_position;
1200 ret = 0; 1201 ret = 0;
1201 MHD_set_socket_errno_(ENOMEM); 1202 MHD_socket_set_error_to_ENOMEM ();
1202#ifndef HAVE_SENDFILE64 1203#ifndef HAVE_SENDFILE64
1203 offset = (off_t) offsetu64; 1204 offset = (off_t) offsetu64;
1204 if ( (offsetu64 <= (uint64_t) OFF_T_MAX) && 1205 if ( (offsetu64 <= (uint64_t) OFF_T_MAX) &&
@@ -1212,17 +1213,17 @@ send_param_adapter (struct MHD_Connection *connection,
1212 /* write successful */ 1213 /* write successful */
1213 return ret; 1214 return ret;
1214 } 1215 }
1215 err = MHD_socket_errno_; 1216 err = MHD_socket_get_error_();
1216#if EPOLL_SUPPORT 1217#if EPOLL_SUPPORT
1217 if ( (0 > ret) && (EAGAIN == err) ) 1218 if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_(err)) )
1218 { 1219 {
1219 /* EAGAIN --- no longer write-ready */ 1220 /* EAGAIN --- no longer write-ready */
1220 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 1221 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
1221 } 1222 }
1222#endif 1223#endif
1223 if ( (EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err) ) 1224 if (MHD_SCKT_ERR_IS_EINTR_ (err) || MHD_SCKT_ERR_IS_EAGAIN_ (err))
1224 return 0; 1225 return 0;
1225 if (EBADF == err) 1226 if (MHD_SCKT_ERR_IS_(err, MHD_SCKT_EBADF_))
1226 return -1; 1227 return -1;
1227 /* sendfile() failed with EINVAL if mmap()-like operations are not 1228 /* sendfile() failed with EINVAL if mmap()-like operations are not
1228 supported for FD or other 'unusual' errors occurred, so we should try 1229 supported for FD or other 'unusual' errors occurred, so we should try
@@ -1232,8 +1233,9 @@ send_param_adapter (struct MHD_Connection *connection,
1232 } 1233 }
1233#endif 1234#endif
1234 ret = (ssize_t) send (connection->socket_fd, other, (_MHD_socket_funcs_size)i, MSG_NOSIGNAL); 1235 ret = (ssize_t) send (connection->socket_fd, other, (_MHD_socket_funcs_size)i, MSG_NOSIGNAL);
1236 err = MHD_socket_get_error_();
1235#if EPOLL_SUPPORT 1237#if EPOLL_SUPPORT
1236 if ( (0 > ret) && (EAGAIN == MHD_socket_errno_) ) 1238 if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_(err)) )
1237 { 1239 {
1238 /* EAGAIN --- no longer write-ready */ 1240 /* EAGAIN --- no longer write-ready */
1239 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 1241 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
@@ -1242,8 +1244,8 @@ send_param_adapter (struct MHD_Connection *connection,
1242 /* Handle broken kernel / libc, returning -1 but not setting errno; 1244 /* Handle broken kernel / libc, returning -1 but not setting errno;
1243 kill connection as that should be safe; reported on mailinglist here: 1245 kill connection as that should be safe; reported on mailinglist here:
1244 http://lists.gnu.org/archive/html/libmicrohttpd/2014-10/msg00023.html */ 1246 http://lists.gnu.org/archive/html/libmicrohttpd/2014-10/msg00023.html */
1245 if ( (0 > ret) && (0 == MHD_socket_errno_) ) 1247 if ( (0 > ret) && (0 == err) )
1246 MHD_set_socket_errno_(ECONNRESET); 1248 MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_);
1247 return ret; 1249 return ret;
1248} 1250}
1249 1251
@@ -1970,16 +1972,18 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1970#endif /* ! USE_ACCEPT4 */ 1972#endif /* ! USE_ACCEPT4 */
1971 if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0)) 1973 if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0))
1972 { 1974 {
1973 const int err = MHD_socket_errno_; 1975 const int err = MHD_socket_get_error_ ();
1974 /* This could be a common occurance with multiple worker threads */ 1976 /* This could be a common occurance with multiple worker threads */
1975 if ( (EINVAL == err) && 1977 if ( (MHD_SCKT_ERR_IS_ (err, MHD_SCKT_EINVAL_)) &&
1976 (MHD_INVALID_SOCKET == daemon->socket_fd) ) 1978 (MHD_INVALID_SOCKET == daemon->socket_fd) )
1977 return MHD_NO; /* can happen during shutdown */ 1979 return MHD_NO; /* can happen during shutdown */
1980 if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err))
1981 return MHD_NO; /* do not print error if client just disconnected early */
1978#ifdef HAVE_MESSAGES 1982#ifdef HAVE_MESSAGES
1979 if ((EAGAIN != err) && (EWOULDBLOCK != err)) 1983 if ( !MHD_SCKT_ERR_IS_EAGAIN_ (err) )
1980 MHD_DLOG (daemon, 1984 MHD_DLOG (daemon,
1981 "Error accepting connection: %s\n", 1985 "Error accepting connection: %s\n",
1982 MHD_socket_last_strerr_ ()); 1986 MHD_socket_strerr_(err));
1983#endif 1987#endif
1984 if (MHD_INVALID_SOCKET != s) 1988 if (MHD_INVALID_SOCKET != s)
1985 { 1989 {
@@ -1987,10 +1991,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1987 MHD_PANIC ("close failed\n"); 1991 MHD_PANIC ("close failed\n");
1988 /* just in case */ 1992 /* just in case */
1989 } 1993 }
1990 if ( (EMFILE == err) || 1994 if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
1991 (ENFILE == err) ||
1992 (ENOMEM == err) ||
1993 (ENOBUFS == err) )
1994 { 1995 {
1995 /* system/process out of resources */ 1996 /* system/process out of resources */
1996 if (0 == daemon->connections) 1997 if (0 == daemon->connections)
@@ -2430,12 +2431,13 @@ MHD_select (struct MHD_Daemon *daemon,
2430 return MHD_NO; 2431 return MHD_NO;
2431 if (num_ready < 0) 2432 if (num_ready < 0)
2432 { 2433 {
2433 if (EINTR == MHD_socket_errno_) 2434 const int err = MHD_socket_get_error_ ();
2435 if (MHD_SCKT_ERR_IS_EINTR_(err))
2434 return (MHD_NO == err_state) ? MHD_YES : MHD_NO; 2436 return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
2435#ifdef HAVE_MESSAGES 2437#ifdef HAVE_MESSAGES
2436 MHD_DLOG (daemon, 2438 MHD_DLOG (daemon,
2437 "select failed: %s\n", 2439 "select failed: %s\n",
2438 MHD_socket_last_strerr_ ()); 2440 MHD_socket_strerr_ (err));
2439#endif 2441#endif
2440 return MHD_NO; 2442 return MHD_NO;
2441 } 2443 }
@@ -2551,7 +2553,8 @@ MHD_poll_all (struct MHD_Daemon *daemon,
2551 } 2553 }
2552 if (MHD_sys_poll_(p, poll_server + num_connections, timeout) < 0) 2554 if (MHD_sys_poll_(p, poll_server + num_connections, timeout) < 0)
2553 { 2555 {
2554 if (EINTR == MHD_socket_errno_) 2556 const int err = MHD_socket_get_error_ ();
2557 if (MHD_SCKT_ERR_IS_EINTR_ (err))
2555 { 2558 {
2556 free(p); 2559 free(p);
2557 return MHD_YES; 2560 return MHD_YES;
@@ -2559,7 +2562,7 @@ MHD_poll_all (struct MHD_Daemon *daemon,
2559#ifdef HAVE_MESSAGES 2562#ifdef HAVE_MESSAGES
2560 MHD_DLOG (daemon, 2563 MHD_DLOG (daemon,
2561 "poll failed: %s\n", 2564 "poll failed: %s\n",
2562 MHD_socket_last_strerr_ ()); 2565 MHD_socket_strerr_ (err));
2563#endif 2566#endif
2564 free(p); 2567 free(p);
2565 return MHD_NO; 2568 return MHD_NO;
@@ -2645,12 +2648,13 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
2645 return MHD_YES; 2648 return MHD_YES;
2646 if (MHD_sys_poll_(p, poll_count, timeout) < 0) 2649 if (MHD_sys_poll_(p, poll_count, timeout) < 0)
2647 { 2650 {
2648 if (EINTR == MHD_socket_errno_) 2651 const int err = MHD_socket_get_error_ ();
2652 if (MHD_SCKT_ERR_IS_EINTR_ (err))
2649 return MHD_YES; 2653 return MHD_YES;
2650#ifdef HAVE_MESSAGES 2654#ifdef HAVE_MESSAGES
2651 MHD_DLOG (daemon, 2655 MHD_DLOG (daemon,
2652 "poll failed: %s\n", 2656 "poll failed: %s\n",
2653 MHD_socket_last_strerr_ ()); 2657 MHD_socket_strerr_ (err));
2654#endif 2658#endif
2655 return MHD_NO; 2659 return MHD_NO;
2656 } 2660 }
@@ -2790,12 +2794,13 @@ MHD_epoll (struct MHD_Daemon *daemon,
2790 events, MAX_EVENTS, timeout_ms); 2794 events, MAX_EVENTS, timeout_ms);
2791 if (-1 == num_events) 2795 if (-1 == num_events)
2792 { 2796 {
2793 if (EINTR == MHD_socket_errno_) 2797 const int err = MHD_socket_get_error_ ();
2798 if (MHD_SCKT_ERR_IS_EINTR_ (err))
2794 return MHD_YES; 2799 return MHD_YES;
2795#ifdef HAVE_MESSAGES 2800#ifdef HAVE_MESSAGES
2796 MHD_DLOG (daemon, 2801 MHD_DLOG (daemon,
2797 "Call to epoll_wait failed: %s\n", 2802 "Call to epoll_wait failed: %s\n",
2798 MHD_socket_last_strerr_ ()); 2803 MHD_socket_strerr_ (err));
2799#endif 2804#endif
2800 return MHD_NO; 2805 return MHD_NO;
2801 } 2806 }
diff --git a/src/microhttpd/mhd_compat.h b/src/microhttpd/mhd_compat.h
index 3f88055f..19ebac5f 100644
--- a/src/microhttpd/mhd_compat.h
+++ b/src/microhttpd/mhd_compat.h
@@ -36,6 +36,12 @@
36 36
37#include "mhd_options.h" 37#include "mhd_options.h"
38#include <stdlib.h> 38#include <stdlib.h>
39#ifdef HAVE_STRING_H /* for strerror() */
40#include <string.h>
41#endif /* HAVE_STRING_H */
42
43 /* MHD_strerror_ is strerror */
44#define MHD_strerror_(errnum) strerror((errnum))
39 45
40/* Platform-independent snprintf name */ 46/* Platform-independent snprintf name */
41#if defined(HAVE_SNPRINTF) 47#if defined(HAVE_SNPRINTF)
diff --git a/src/microhttpd/mhd_sockets.c b/src/microhttpd/mhd_sockets.c
index 4214108e..643ed849 100644
--- a/src/microhttpd/mhd_sockets.c
+++ b/src/microhttpd/mhd_sockets.c
@@ -29,166 +29,13 @@
29#ifdef MHD_WINSOCK_SOCKETS 29#ifdef MHD_WINSOCK_SOCKETS
30 30
31/** 31/**
32 * Return errno equivalent of last winsock error 32 * Return pointer to string description of specified WinSock error
33 * @return errno equivalent of last winsock error 33 * @param err the WinSock error code.
34 * @return pointer to string description of specified WinSock error.
34 */ 35 */
35int MHD_W32_errno_from_winsock_(void) 36const char* MHD_W32_strerror_winsock_(int err)
36{ 37{
37 switch(WSAGetLastError()) 38 switch (err)
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 { 39 {
193 case 0: 40 case 0:
194 return "No error"; 41 return "No error";
@@ -386,160 +233,5 @@ const char* MHD_W32_strerror_last_winsock_(void)
386 return "Unknown winsock error"; 233 return "Unknown winsock error";
387} 234}
388 235
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}
544 236
545#endif /* MHD_WINSOCK_SOCKETS */ 237#endif /* MHD_WINSOCK_SOCKETS */
diff --git a/src/microhttpd/mhd_sockets.h b/src/microhttpd/mhd_sockets.h
index 3a3e4b85..b38a5d55 100644
--- a/src/microhttpd/mhd_sockets.h
+++ b/src/microhttpd/mhd_sockets.h
@@ -204,38 +204,6 @@
204# define MHD_socket_close_(fd) closesocket((fd)) 204# define MHD_socket_close_(fd) closesocket((fd))
205#endif 205#endif
206 206
207/**
208 * MHD_socket_errno_ is errno of last function (non-W32) / errno of
209 * last socket function (W32)
210 */
211#if !defined(MHD_WINSOCK_SOCKETS)
212# define MHD_socket_errno_ errno
213#else
214# define MHD_socket_errno_ MHD_W32_errno_from_winsock_()
215#endif
216
217 /* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
218 * description string of last socket error (W32) */
219#if !defined(MHD_WINSOCK_SOCKETS)
220# define MHD_socket_last_strerr_() strerror(errno)
221#else
222# define MHD_socket_last_strerr_() MHD_W32_strerror_last_winsock_()
223#endif
224
225 /* MHD_strerror_ is strerror (both non-W32/W32) */
226#if !defined(MHD_WINSOCK_SOCKETS)
227# define MHD_strerror_(errnum) strerror((errnum))
228#else
229# define MHD_strerror_(errnum) MHD_W32_strerror_((errnum))
230#endif
231
232 /* MHD_set_socket_errno_ set errno to errnum (non-W32) / set socket last error to errnum (W32) */
233#if !defined(MHD_WINSOCK_SOCKETS)
234# define MHD_set_socket_errno_(errnum) errno=(errnum)
235#else
236# define MHD_set_socket_errno_(errnum) MHD_W32_set_last_winsock_error_((errnum))
237#endif
238
239 /* MHD_SYS_select_ is wrapper macro for system select() function */ 207 /* MHD_SYS_select_ is wrapper macro for system select() function */
240#if !defined(MHD_WINSOCK_SOCKETS) 208#if !defined(MHD_WINSOCK_SOCKETS)
241# define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t)) 209# define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t))
@@ -257,150 +225,300 @@
257# endif /* MHD_WINSOCK_SOCKETS */ 225# endif /* MHD_WINSOCK_SOCKETS */
258#endif /* HAVE_POLL */ 226#endif /* HAVE_POLL */
259 227
228#define MHD_SCKT_MISSING_ERR_CODE_ 31450
229
230#if defined(MHD_POSIX_SOCKETS)
231# if defined(EAGAIN)
232# define MHD_SCKT_EAGAIN_ EAGAIN
233# elif defined(EWOULDBLOCK)
234# define MHD_SCKT_EAGAIN_ EWOULDBLOCK
235# else /* !EAGAIN && !EWOULDBLOCK */
236# define MHD_SCKT_EAGAIN_ MHD_SCKT_MISSING_ERR_CODE_
237# endif /* !EAGAIN && !EWOULDBLOCK */
238# if defined(EWOULDBLOCK)
239# define MHD_SCKT_EWOULDBLOCK_ EWOULDBLOCK
240# elif defined(EAGAIN)
241# define MHD_SCKT_EWOULDBLOCK_ EAGAIN
242# else /* !EWOULDBLOCK && !EAGAIN */
243# define MHD_SCKT_EWOULDBLOCK_ MHD_SCKT_MISSING_ERR_CODE_
244# endif /* !EWOULDBLOCK && !EAGAIN */
245# ifdef EINTR
246# define MHD_SCKT_EINTR_ EINTR
247# else /* ! EINTR */
248# define MHD_SCKT_EINTR_ MHD_SCKT_MISSING_ERR_CODE_
249# endif /* ! EINTR */
250# ifdef ECONNRESET
251# define MHD_SCKT_ECONNRESET_ ECONNRESET
252# else /* ! ECONNRESET */
253# define MHD_SCKT_ECONNRESET_ MHD_SCKT_MISSING_ERR_CODE_
254# endif /* ! ECONNRESET */
255# ifdef ECONNABORTED
256# define MHD_SCKT_ECONNABORTED_ ECONNABORTED
257# else /* ! ECONNABORTED */
258# define MHD_SCKT_ECONNABORTED_ MHD_SCKT_MISSING_ERR_CODE_
259# endif /* ! ECONNABORTED */
260# ifdef ENOTCONN
261# define MHD_SCKT_ENOTCONN_ ENOTCONN
262# else /* ! ENOTCONN */
263# define MHD_SCKT_ENOTCONN_ MHD_SCKT_MISSING_ERR_CODE_
264# endif /* ! ENOTCONN */
265# ifdef EMFILE
266# define MHD_SCKT_EMFILE_ EMFILE
267# else /* ! EMFILE */
268# define MHD_SCKT_EMFILE_ MHD_SCKT_MISSING_ERR_CODE_
269# endif /* ! EMFILE */
270# ifdef ENFILE
271# define MHD_SCKT_ENFILE_ ENFILE
272# else /* ! ENFILE */
273# define MHD_SCKT_ENFILE_ MHD_SCKT_MISSING_ERR_CODE_
274# endif /* ! ENFILE */
275# ifdef ENOMEM
276# define MHD_SCKT_ENOMEM_ ENOMEM
277# else /* ! ENOMEM */
278# define MHD_SCKT_ENOMEM_ MHD_SCKT_MISSING_ERR_CODE_
279# endif /* ! ENOMEM */
280# ifdef ENOBUFS
281# define MHD_SCKT_ENOBUFS_ ENOBUFS
282# else /* ! ENOBUFS */
283# define MHD_SCKT_ENOBUFS_ MHD_SCKT_MISSING_ERR_CODE_
284# endif /* ! ENOBUFS */
285# ifdef EBADF
286# define MHD_SCKT_EBADF_ EBADF
287# else /* ! EBADF */
288# define MHD_SCKT_EBADF_ MHD_SCKT_MISSING_ERR_CODE_
289# endif /* ! EBADF */
290# ifdef ENOTSOCK
291# define MHD_SCKT_ENOTSOCK_ ENOTSOCK
292# else /* ! ENOTSOCK */
293# define MHD_SCKT_ENOTSOCK_ MHD_SCKT_MISSING_ERR_CODE_
294# endif /* ! ENOTSOCK */
295# ifdef EINVAL
296# define MHD_SCKT_EINVAL_ EINVAL
297# else /* ! EINVAL */
298# define MHD_SCKT_EINVAL_ MHD_SCKT_MISSING_ERR_CODE_
299# endif /* ! EINVAL */
300# ifdef EFAULT
301# define MHD_SCKT_EFAUL_ EFAULT
302# else /* ! EFAULT */
303# define MHD_SCKT_EFAUL_ MHD_SCKT_MISSING_ERR_CODE_
304# endif /* ! EFAULT */
305# ifdef ENOSYS
306# define MHD_SCKT_ENOSYS_ ENOSYS
307# else /* ! ENOSYS */
308# define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_
309# endif /* ! ENOSYS */
310# ifdef ENOTSUP
311# define MHD_SCKT_ENOTSUP_ ENOTSUP
312# else /* ! ENOTSUP */
313# define MHD_SCKT_ENOTSUP_ MHD_SCKT_MISSING_ERR_CODE_
314# endif /* ! ENOTSUP */
315# ifdef EOPNOTSUPP
316# define MHD_SCKT_EOPNOTSUPP_ EOPNOTSUPP
317# else /* ! EOPNOTSUPP */
318# define MHD_SCKT_EOPNOTSUPP_ MHD_SCKT_MISSING_ERR_CODE_
319# endif /* ! EOPNOTSUPP */
320# ifdef EACCES
321# define MHD_SCKT_EACCESS_ EACCES
322# else /* ! EACCES */
323# define MHD_SCKT_EACCESS_ MHD_SCKT_MISSING_ERR_CODE_
324# endif /* ! EACCES */
325# ifdef ENETDOWN
326# define MHD_SCKT_ENETDOWN_ ENETDOWN
327# else /* ! ENETDOWN */
328# define MHD_SCKT_ENETDOWN_ MHD_SCKT_MISSING_ERR_CODE_
329# endif /* ! ENETDOWN */
330#elif defined(MHD_WINSOCK_SOCKETS)
331# define MHD_SCKT_EAGAIN_ WSAEWOULDBLOCK
332# define MHD_SCKT_EWOULDBLOCK_ WSAEWOULDBLOCK
333# define MHD_SCKT_EINTR_ WSAEINTR
334# define MHD_SCKT_ECONNRESET_ WSAECONNRESET
335# define MHD_SCKT_ECONNABORTED_ WSAECONNABORTED
336# define MHD_SCKT_ENOTCONN_ WSAENOTCONN
337# define MHD_SCKT_EMFILE_ WSAEMFILE
338# define MHD_SCKT_ENFILE_ MHD_SCKT_MISSING_ERR_CODE_
339# define MHD_SCKT_ENOMEM_ MHD_SCKT_MISSING_ERR_CODE_
340# define MHD_SCKT_ENOBUFS_ WSAENOBUFS
341# define MHD_SCKT_EBADF_ WSAEBADF
342# define MHD_SCKT_ENOTSOCK_ WSAENOTSOCK
343# define MHD_SCKT_EINVAL_ WSAEINVAL
344# define MHD_SCKT_EFAUL_ WSAEFAULT
345# define MHD_SCKT_ENOSYS_ MHD_SCKT_MISSING_ERR_CODE_
346# define MHD_SCKT_ENOTSUP_ MHD_SCKT_MISSING_ERR_CODE_
347# define MHD_SCKT_EOPNOTSUPP_ WSAEOPNOTSUPP
348# define MHD_SCKT_EACCESS_ WSAEACCES
349# define MHD_SCKT_ENETDOWN_ WSAENETDOWN
350#endif
351
352/**
353 * MHD_socket_error_ return system native error code for last socket error.
354 * @return system error code for last socket error.
355 */
356#if defined(MHD_POSIX_SOCKETS)
357# define MHD_socket_get_error_() (errno)
358#elif defined(MHD_WINSOCK_SOCKETS)
359# define MHD_socket_get_error_() WSAGetLastError()
360#endif
260 361
261#ifdef MHD_WINSOCK_SOCKETS 362#ifdef MHD_WINSOCK_SOCKETS
363 /* POSIX-W32 sockets compatibility functions */
262 364
263/* POSIX-W32 compatibility functions and macros */ 365/**
366 * Return pointer to string description of specified WinSock error
367 * @param err the WinSock error code.
368 * @return pointer to string description of specified WinSock error.
369 */
370 const char* MHD_W32_strerror_winsock_(int err);
371#endif /* MHD_WINSOCK_SOCKETS */
264 372
265# define MHDW32ERRBASE 3300 373/* MHD_socket_last_strerr_ is description string of specified socket error code */
374#if defined(MHD_POSIX_SOCKETS)
375# define MHD_socket_strerr_(err) strerror((err))
376#elif defined(MHD_WINSOCK_SOCKETS)
377# define MHD_socket_strerr_(err) MHD_W32_strerror_winsock_((err))
378#endif
266 379
267# ifndef EWOULDBLOCK 380/* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
268# define EWOULDBLOCK (MHDW32ERRBASE+1) 381 * description string of last socket error (W32) */
269# endif 382#define MHD_socket_last_strerr_() MHD_socket_strerr_(MHD_socket_get_error_())
270# ifndef EINPROGRESS
271# define EINPROGRESS (MHDW32ERRBASE+2)
272# endif
273# ifndef EALREADY
274# define EALREADY (MHDW32ERRBASE+3)
275# endif
276# ifndef ENOTSOCK
277# define ENOTSOCK (MHDW32ERRBASE+4)
278# endif
279# ifndef EDESTADDRREQ
280# define EDESTADDRREQ (MHDW32ERRBASE+5)
281# endif
282# ifndef EMSGSIZE
283# define EMSGSIZE (MHDW32ERRBASE+6)
284# endif
285# ifndef EPROTOTYPE
286# define EPROTOTYPE (MHDW32ERRBASE+7)
287# endif
288# ifndef ENOPROTOOPT
289# define ENOPROTOOPT (MHDW32ERRBASE+8)
290# endif
291# ifndef EPROTONOSUPPORT
292# define EPROTONOSUPPORT (MHDW32ERRBASE+9)
293# endif
294# ifndef EOPNOTSUPP
295# define EOPNOTSUPP (MHDW32ERRBASE+10)
296# endif
297# ifndef EAFNOSUPPORT
298# define EAFNOSUPPORT (MHDW32ERRBASE+11)
299# endif
300# ifndef EADDRINUSE
301# define EADDRINUSE (MHDW32ERRBASE+12)
302# endif
303# ifndef EADDRNOTAVAIL
304# define EADDRNOTAVAIL (MHDW32ERRBASE+13)
305# endif
306# ifndef ENETDOWN
307# define ENETDOWN (MHDW32ERRBASE+14)
308# endif
309# ifndef ENETUNREACH
310# define ENETUNREACH (MHDW32ERRBASE+15)
311# endif
312# ifndef ENETRESET
313# define ENETRESET (MHDW32ERRBASE+16)
314# endif
315# ifndef ECONNABORTED
316# define ECONNABORTED (MHDW32ERRBASE+17)
317# endif
318# ifndef ECONNRESET
319# define ECONNRESET (MHDW32ERRBASE+18)
320# endif
321# ifndef ENOBUFS
322# define ENOBUFS (MHDW32ERRBASE+19)
323# endif
324# ifndef EISCONN
325# define EISCONN (MHDW32ERRBASE+20)
326# endif
327# ifndef ENOTCONN
328# define ENOTCONN (MHDW32ERRBASE+21)
329# endif
330# ifndef ETOOMANYREFS
331# define ETOOMANYREFS (MHDW32ERRBASE+22)
332# endif
333# ifndef ECONNREFUSED
334# define ECONNREFUSED (MHDW32ERRBASE+23)
335# endif
336# ifndef ELOOP
337# define ELOOP (MHDW32ERRBASE+24)
338# endif
339# ifndef EHOSTDOWN
340# define EHOSTDOWN (MHDW32ERRBASE+25)
341# endif
342# ifndef EHOSTUNREACH
343# define EHOSTUNREACH (MHDW32ERRBASE+26)
344# endif
345# ifndef EPROCLIM
346# define EPROCLIM (MHDW32ERRBASE+27)
347# endif
348# ifndef EUSERS
349# define EUSERS (MHDW32ERRBASE+28)
350# endif
351# ifndef EDQUOT
352# define EDQUOT (MHDW32ERRBASE+29)
353# endif
354# ifndef ESTALE
355# define ESTALE (MHDW32ERRBASE+30)
356# endif
357# ifndef EREMOTE
358# define EREMOTE (MHDW32ERRBASE+31)
359# endif
360# ifndef ESOCKTNOSUPPORT
361# define ESOCKTNOSUPPORT (MHDW32ERRBASE+32)
362# endif
363# ifndef EPFNOSUPPORT
364# define EPFNOSUPPORT (MHDW32ERRBASE+33)
365# endif
366# ifndef ESHUTDOWN
367# define ESHUTDOWN (MHDW32ERRBASE+34)
368# endif
369# ifndef ENODATA
370# define ENODATA (MHDW32ERRBASE+35)
371# endif
372# ifndef ETIMEDOUT
373# define ETIMEDOUT (MHDW32ERRBASE+36)
374# endif
375 383
376/** 384/**
377 * Return errno equivalent of last winsock error 385 * MHD_socket_fset_error_() set socket system native error code.
378 * @return errno equivalent of last winsock error
379 */ 386 */
380 int MHD_W32_errno_from_winsock_(void); 387#if defined(MHD_POSIX_SOCKETS)
388# define MHD_socket_fset_error_(err) (errno = (err))
389#elif defined(MHD_WINSOCK_SOCKETS)
390# define MHD_socket_fset_error_(err) (WSASetLastError((err)))
391#endif
381 392
382/** 393/**
383 * Return pointer to string description of errnum error 394 * MHD_socket_try_set_error_() set socket system native error code if
384 * Works fine with both standard errno errnums 395 * specified code is defined on system.
385 * and errnums from MHD_W32_errno_from_winsock_ 396 * @return non-zero if specified @a err code is defined on system
386 * @param errnum the errno or value from MHD_W32_errno_from_winsock_() 397 * and error was set;
387 * @return pointer to string description of error 398 * zero if specified @a err code is not defined on system
399 * and error was not set.
388 */ 400 */
389 const char* MHD_W32_strerror_(int errnum); 401#define MHD_socket_try_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ != (err)) ? \
402 (MHD_socket_fset_error_((err)), !0) : 0 )
390 403
391/** 404/**
392 * Return pointer to string description of last winsock error 405 * MHD_socket_set_error_() set socket system native error code to
393 * @return pointer to string description of last winsock error 406 * specified code or replacement code if specified code is not
407 * defined on system.
394 */ 408 */
395 const char* MHD_W32_strerror_last_winsock_(void); 409#if defined(MHD_POSIX_SOCKETS)
410# if defined(ENOSYS)
411# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
412 (errno = ENOSYS) : (errno = (err)) )
413# elif defined(EOPNOTSUPP)
414# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
415 (errno = EOPNOTSUPP) : (errno = (err)) )
416# elif defined (EFAULT)
417# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
418 (errno = EFAULT) : (errno = (err)) )
419# elif defined (EINVAL)
420# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
421 (errno = EINVAL) : (errno = (err)) )
422# else /* !EOPNOTSUPP && !EFAULT && !EINVAL */
423# warning No suitable replacement for missing socket error code is found. Edit this file and add replacement code which is defined on system.
424# define MHD_socket_set_error_(err) (errno = (err))
425# endif /* !EOPNOTSUPP && !EFAULT && !EINVAL*/
426#elif defined(MHD_WINSOCK_SOCKETS)
427# define MHD_socket_set_error_(err) ( (MHD_SCKT_MISSING_ERR_CODE_ == (err)) ? \
428 (WSASetLastError((WSAEOPNOTSUPP))) : \
429 (WSASetLastError((err))) )
430#endif
396 431
397/** 432/**
398 * Set last winsock error to equivalent of given errno value 433 * Check whether given socket error is equal to specified system
399 * @param errnum the errno value to set 434 * native MHD_SCKT_E*_ code.
435 * If platform don't have specific error code, result is
436 * always boolean false.
437 * @return boolean true if @a code is real error code and
438 * @a err equals to MHD_SCKT_E*_ @a code;
439 * boolean false otherwise
400 */ 440 */
401 void MHD_W32_set_last_winsock_error_(int errnum); 441#define MHD_SCKT_ERR_IS_(err,code) ( (MHD_SCKT_MISSING_ERR_CODE_ != (code)) && \
442 ((code) == (err)) )
402 443
444/**
445 * Check whether last socket error is equal to specified system
446 * native MHD_SCKT_E*_ code.
447 * If platform don't have specific error code, result is
448 * always boolean false.
449 * @return boolean true if @a code is real error code and
450 * last socket error equals to MHD_SCKT_E*_ @a code;
451 * boolean false otherwise
452 */
453#define MHD_SCKT_LAST_ERR_IS_(code) MHD_SCKT_ERR_IS_(MHD_socket_get_error_() ,(code))
403 454
404#endif /* MHD_WINSOCK_SOCKETS */ 455/* Specific error code checks */
456
457/**
458 * Check whether given socket error is equal to system's
459 * socket error codes for EINTR.
460 * @return boolean true if @a err is equal to sockets' EINTR code;
461 * boolean false otherwise.
462 */
463#define MHD_SCKT_ERR_IS_EINTR_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EINTR_)
464
465/**
466 * Check whether given socket error is equal to system's
467 * socket error codes for EAGAIN or EWOULDBLOCK.
468 * @return boolean true if @a err is equal to sockets' EAGAIN or EWOULDBLOCK codes;
469 * boolean false otherwise.
470 */
471#if MHD_SCKT_EAGAIN_ == MHD_SCKT_EWOULDBLOCK_
472# define MHD_SCKT_ERR_IS_EAGAIN_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_)
473#else /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
474# define MHD_SCKT_ERR_IS_EAGAIN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EAGAIN_) || \
475 MHD_SCKT_ERR_IS_((err),MHD_SCKT_EWOULDBLOCK_) )
476#endif /* MHD_SCKT_EAGAIN_ != MHD_SCKT_EWOULDBLOCK_ */
477
478/**
479 * Check whether given socket error is any kind of "low resource" error.
480 * @return boolean true if @a err is any kind of "low resource" error,
481 * boolean false otherwise.
482 */
483#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_EMFILE_) || \
484 MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENFILE_) || \
485 MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOMEM_) || \
486 MHD_SCKT_ERR_IS_((err),MHD_SCKT_ENOBUFS_) )
487
488/**
489 * Check whether is given socket error is type of "incoming connection
490 * was disconnected before 'accept()' is called".
491 * @return boolean true is @a err match described socket error code,
492 * boolean false otherwise.
493 */
494#if defined(MHD_POSIX_SOCKETS)
495# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_)
496#elif defined(MHD_WINSOCK_SOCKETS)
497# define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err) MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_)
498#endif
499
500/**
501 * Check whether is given socket error is type of "connection was terminated
502 * by remote side".
503 * @return boolean true is @a err match described socket error code,
504 * boolean false otherwise.
505 */
506#define MHD_SCKT_ERR_IS_REMOTE_DISCNN_(err) ( MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNRESET_) || \
507 MHD_SCKT_ERR_IS_((err),MHD_SCKT_ECONNABORTED_))
508
509/* Specific error code set */
510
511/**
512 * Set socket's error code to ENOMEM or equivalent if ENOMEM is not
513 * available on platform.
514 */
515#if MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOMEM_
516# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_)
517#elif MHD_SCKT_MISSING_ERR_CODE_ != MHD_SCKT_ENOBUFS_
518# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOBUFS_)
519#else
520# warning No suitable replacement for ENOMEM error codes is found. Edit this file and add replacement code which is defined on system.
521# define MHD_socket_set_error_to_ENOMEM() MHD_socket_set_error_(MHD_SCKT_ENOMEM_)
522#endif
405 523
406#endif /* ! MHD_SOCKETS_H */ 524#endif /* ! MHD_SOCKETS_H */