From 13d537e40451c1c112b3c565ce0de7adfd8e41cc Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 20 Nov 2010 05:00:12 +0100 Subject: gtls: define and use gtls_EAGAIN, gtls_EINTR and gtls_EIO. Winsock builds clobber some errno.h defines in setup_once. --- lib/gtls.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/lib/gtls.c b/lib/gtls.c index 93bb91de6..845dbbb12 100644 --- a/lib/gtls.c +++ b/lib/gtls.c @@ -78,6 +78,7 @@ static void tls_log_func(int level, const char *str) } #endif static bool gtls_inited = FALSE; + /* * Custom push and pull callback functions used by GNU TLS to read and write * to the socket. These functions are simple wrappers to send() and recv() @@ -86,28 +87,32 @@ static bool gtls_inited = FALSE; * us to get specific about the fourth "flags" argument, and to use arbitrary * private data with gnutls_transport_set_ptr if we wish. * - * On Windows translate WSAGetLastError() to errno values as GNU TLS does it - * internally too. This is necessary because send() and recv() on Windows - * don't set errno when they fail but GNU TLS expects a proper errno value. - * - * Use gnutls_transport_set_global_errno() like the GNU TLS documentation - * suggests to avoid problems with different errno variables when GNU TLS and - * curl are linked to different versions of msvcrt.dll. + * When these custom push and pull callbacks fail, GNU TLS checks its own + * session-specific error variable, and when not set also its own global + * errno variable, in order to take appropriate action. GNU TLS does not + * require that the transport is actually a socket. This implies that for + * Windows builds these callbacks should ideally set the session-specific + * error variable using function gnutls_transport_set_errno or as a last + * resort global errno variable using gnutls_transport_set_global_errno, + * with a transport agnostic error value. This implies that some winsock + * error translation must take place in these callbacks. */ + #ifdef USE_WINSOCK -static void translate_wsa_to_errno(void) +# define gtls_EINTR 4 +# define gtls_EIO 5 +# define gtls_EAGAIN 11 +static int gtls_mapped_sockerrno(void) { - switch(WSAGetLastError()) { + switch(SOCKERRNO) { case WSAEWOULDBLOCK: - gnutls_transport_set_global_errno(EAGAIN); - break; + return gtls_EAGAIN; case WSAEINTR: - gnutls_transport_set_global_errno(EINTR); - break; + return gtls_EINTR; default: - gnutls_transport_set_global_errno(EIO); break; } + return gtls_EIO; } #endif @@ -115,9 +120,8 @@ static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len) { ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len); #ifdef USE_WINSOCK - if(ret < 0) { - translate_wsa_to_errno(); - } + if(ret < 0) + gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); #endif return ret; } @@ -126,9 +130,8 @@ static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len) { ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len); #ifdef USE_WINSOCK - if(ret < 0) { - translate_wsa_to_errno(); - } + if(ret < 0) + gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); #endif return ret; } -- cgit v1.2.3