[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