[gnutls-dev] Re: Gnutls4win: Problem with custom push/pull functions, errno and Visual Studio (Workaround included)

Simon Josefsson jas at extundo.com
Tue Nov 7 11:30:24 CET 2006


Simon Josefsson <jas at extundo.com> writes:

> Btw, it seems others have run into other errno problems in push/pull
> functions, see:
> http://darcs.0x539.de/trac/obby/cgi-bin/trac.cgi/browser/net6/src/encrypt.cpp
> I think we should use WSAGetLastError to set errno ourselves, but I'll
> post the patch for this separately.

Here is the patch, I have installed it.

/Simon

** When calling `recv' or `send' Windows errors are handled properly.
The Windows recv/send functions doesn't use errno, and GnuTLS now use
WSAGetLastError to access the error condition instead.

Index: gnutls_buffers.c
===================================================================
RCS file: /cvs/gnutls/gnutls/lib/gnutls_buffers.c,v
retrieving revision 2.129
retrieving revision 2.131
diff -u -p -u -w -r2.129 -r2.131
--- gnutls_buffers.c	7 Nov 2006 10:13:57 -0000	2.129
+++ gnutls_buffers.c	7 Nov 2006 10:26:17 -0000	2.131
@@ -319,8 +319,31 @@ _gnutls_read (gnutls_session_t session, 
       session->internals.errnum = 0;
 
       if (session->internals._gnutls_pull_func == NULL)
+	{
 	i = recv (GNUTLS_POINTER_TO_INT(fd), &ptr[sizeOfPtr - left],
 		  left, flags);
+#if HAVE_WINSOCK
+	  if (i < 0)
+	    {
+	      int tmperr = WSAGetLastError();
+	      switch (tmperr)
+		{
+		case WSAEWOULDBLOCK:
+		  session->internals.errnum = EAGAIN;
+		  break;
+
+		case WSAEINTR:
+		  session->internals.errnum = EINTR;
+		  break;
+
+		default:
+		  session->internals.errnum = EIO;
+		  break;
+		}
+	      WSASetLastError(tmperr);
+	    }
+#endif
+	}
       else
 	i = session->internals._gnutls_pull_func (fd,
 						  &ptr[sizeOfPtr -
@@ -761,7 +784,29 @@ _gnutls_io_write_buffered (gnutls_sessio
       session->internals.errnum = 0;
 
       if (session->internals._gnutls_push_func == NULL)
+	{
 	i = send (GNUTLS_POINTER_TO_INT(fd), &ptr[n - left], left, 0);
+#if HAVE_WINSOCK
+	  if (i < 0)
+	    {
+	      int tmperr = WSAGetLastError();
+	      switch (tmperr)
+		{
+		case WSAEWOULDBLOCK:
+		  session->internals.errnum = EAGAIN;
+		  break;
+
+		case WSAEINTR:
+		  session->internals.errnum = EINTR;
+		  break;
+
+		default:
+		  session->internals.errnum = EIO;
+		  break;
+		}
+	      WSASetLastError(tmperr);
+	    }
+#endif
       else
 	i = session->internals._gnutls_push_func (fd, &ptr[n - left], left);
 



More information about the Gnutls-dev mailing list