W32 testsuite results

LRN lrn1986 at gmail.com
Tue Apr 5 14:27:16 CEST 2011

On 05.04.2011 11:52, Nikos Mavrogiannopoulos wrote:
> On 04/04/2011 06:01 PM, LRN wrote:
>> On 04.04.2011 18:15, Nikos Mavrogiannopoulos wrote:
>>> On 04/04/2011 03:04 AM, LRN wrote:
>>>> Does anyone have testsuite (make -k check) results for gnutls-2.12.1 on
>>>> W32 (i would prefer native W32, but the ones from Wine are better than
>>>> nothing at all)? Built against libgcrypt.
>>>> I'm building gnutls myself (with some minor patches) and i'm not sure
>>>> whether my mixed testsuite results are expected (known bugs or unported
>>>> features) or not (i broke something).
>>> Not me. Which tests failed? Do gnutls-cli and gnutls-serv operate?
>> I've also submitted a bug report about mini.exe (see the bug tracker),
>> because its cause seemed obvious to me (writes/reads to/from
>> fd==0xffffffff).
> This shouldn't be a problem. The mini-* programs use fd==0xfffffff
> because they emulate the communication and don't really use an fd.
I think i've found the problem. The code in client_pull() in mini.c 
calls gnutls_transport_set_global_errno (EAGAIN); to tell gnutls library 
code that the pull operation should be postponed. However, gnutls 
library code in _gnutls_read() in gnutls_buffers.c:306 calls int err = 
get_errno (session); to obain errno, which, in turn, returns 
session->internals.errno_func (session->internals.transport_recv_ptr);, 
which is the same as system_errno(session->internals.transport_recv_ptr) 
at system.c:55, which simply calls WSAGetLastError(), switch'es over its 
value and sets errno.
That is, the problem is in the fact that on Windows gnutls assumes that 
underlying read() implementation is incapable of setting errno and is, 
in fact, a socket (since gnutls uses WSAGetLastError()).
Possible fixes:
A) Fix gnutls_transport_set_global_errno() to call SetLastError() (note 
that there's no difference between WSAGLE and GLE, unless you're writing 
for WinSock 1.x, which is crazy, because WinSock 2.x has been shipped 
with NT since NT 4.0). And maybe set errno too, just to be safe.
B) Fix system_errno() to also check errno itself and use it instead of 
the result of GLE if errno is not 0. This way both WinAPI and CRT I/O 
functions can be used as read() implementation, and system_errno would 
work for both (although errno bleeding from previous calls could, in 
theory, cause false negatives).
C) Call SetLastError(0) more often. In this particular case 
WSAGetLastError() returns error 3, which is ERROR_PATH_NOT_FOUND, and is 
likely not related to this particular problem - it is probably just a 
leftover from some earlier WinAPI call. SetLastError(0) should clean 
that (OTOH that wouldn't fix this particular problem, since 
WSAGetLastError() will just return 0, and that would STILL result in 
system_error setting errno to EIO - by the way, that's a bit extreme, it 
should set errno to 0 if GLE is 0; consider getting yourself a better 
GLE-handling routine, generrmap.c from Python or win32error.c from 
PostgreSQL would be a good start).

P.S. All fixes are theoretical, i have not tried to implement any of 
that yet.

More information about the Gnutls-devel mailing list