bug-gnulib
[Top][All Lists]
Advanced

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

Re: Error handling in Win32 + gnulib


From: Richard W.M. Jones
Subject: Re: Error handling in Win32 + gnulib
Date: Mon, 30 Nov 2009 09:16:04 +0000
User-agent: Mutt/1.5.18 (2008-05-17)

It's not been stated in so many words, but from what I gather the
policy on errors in Gnulib is as follows.

| Software using gnulib should use errno exclusively, along with
| standard Unix functions such as perror, strerror, etc., which Gnulib
| may replace as necessary so these functions work correctly on
| platforms that lack them (ie. Win32).  All Gnulib POSIX replacement
| functions will set errno in the case of error according to POSIX
| requirements, even on underlying platforms that don't do this
| (ie. Win32).

If what I've written above isn't accurate, please correct me because
this is the most important bit of this email.  Any deviation from the
policy above would be a bug.

Bruno Haible wrote:
> Richard W.M. Jones wrote:
> > 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).
> 
> The error values returned by GetLastError() and those stored in errno
> are in different enumerations or "namespaces". There is no relation
> between them. One is a 'DWORD', the other one is an 'int'. You are
> responsible, after getting a value 12 from GetLastError(), for interpreting
> it as ERROR_INVALID_ACCESS, and if you get a value 12 from errno, for
> interpreting it as ENOMEM.

My first reading of the comments in the MinGW <errno.h> file was that
MinGW was trying to maintain some sort of binary compatibility between
its declared errno numbers and Windows errors, and indeed some of them
are similar, but I inspected in detail the first 100 error numbers
this morning and in fact there is no compatibility between the two
lists.  They are, as you say, truly in separate spaces.

My take from this is that we need a 'set_errno' function which is
equivalent to 'set_winsock_errno' and is used for all non-socket
functions.  It would do:

  void
  set_errno (void)
  {
    DWORD err = GetLastError ();
    switch (err) {
      case ERROR_INVALID_ACCESS:
        errno = EFAULT;
        break;
      case ERROR_OUTOFMEMORY:
        errno = ENOMEM;
        break;
      /* etc for another 1000 or so errors */
    }
  }

'set_errno' should be called on the error path in most Gnulib
replacement functions, where the underlying function that Gnulib is
calling could be a Win32 function.

Tedious but I can contribute something for this if everyone agrees
that this is the right way to do this.

Paolo Bonzini wrote:
> Richard W.M. Jones wrote:
> > (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.
> 
> These are bugs, please report them.

It seems there are going to be quite a lot ...

Unfortunately I was never able to get anyone at Red Hat to sign a
copyright assignment license for me for gnulib, or to get the FSF to
agree that I didn't need one because I work for Red Hat.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw




reply via email to

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