bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Error handling in Win32 + gnulib


From: Richard W.M. Jones
Subject: Error handling in Win32 + gnulib
Date: Fri, 27 Nov 2009 15:57:13 +0000
User-agent: Mutt/1.5.18 (2008-05-17)

I'm confused by errno and error handling in gnulib, and what the
strategy for this is supposed to be, versus how it seems to work now.

Win32 has two methods to return an error code from a syscall:
  DWORD WSAGetLastError(void);  // for all socket functions
  DWORD GetLastError();         // for all other system calls

Win32 itself doesn't use or define a variable called 'errno', but
gnulib does provide this variable when linked to Win32 programs.

Unfortunately gnulib also sets errno, in a lot of places.

Oh yeah, also error codes aren't compatible with each other -- I'll
come to that later.

This leads to some quite schizophrenic error handling in my code.  I
basically have four cases I have to consider:

(a) A call to a Winsock socket function that gnulib has replaced:
Gnulib calls set_winsock_errno to map the WSAGetLastError into an
errno value.  So I can check errno or (with the latest version of
gnulib) WSAGetLastError.

(b) A call to a Winsock socket function that gnulib hasn't replaced:
errno won't have any meaningful value and I must call WSAGetLastError.

(c) A call to a non-socket Win32 function that gnulib has replaced: I
have to go and check Gnulib to see if it sets errno (some do, some
don't, some do only along some paths).  I need to then consider errno
and/or GetLastError.  I have to keep checking this with every revision
of Gnulib because it might change.

(d) A call to a non-socket Win32 function that gnulib hasn't replaced:
I only need to check GetLastError.

In addition, it turns out that error codes aren't compatible.
Although Gnulib tries to define its own error numbers which are
compatible with Win32 ones (eg. EINPROGRESS == 10036 ==
WSAEINPROGRESS), it also uses some from the MinGW header files which
are just plain wrong (eg. ENOMEM == 12 == ERROR_INVALID_ACCESS, MinGW
gets this wrong, it should be ENOMEM 14 == ERROR_OUTOFMEMORY).

So code as in the replacement malloc which sets errno = ENOMEM is not
just hard to use because of the factors above, it's also setting errno
to an incorrect value.

Of course I also want my code to primarily work on Unix too.

Before I launch into what I think Gnulib should be doing, first of all
is there some strategy for errno / error handling which I'm missing?
Has this been discussed before?  Am I using errno / error handling
incorrectly?

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine.  Supports Linux and Windows.
http://et.redhat.com/~rjones/virt-df/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]