You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Jeff Trawick <tr...@bellsouth.net> on 2000/03/30 04:11:22 UTC

ap_status_t for Win32

Paraphrase of text in the GetLastError() documentation:

  GetLastError() returns 32-bit error codes with bit 29 off.
  Application-defined error codes should turn bit 29 on. 

It seems that we don't need more than 32 bits for Windows...
If we turn on bit 29 for non-OS-specific errors, we won't
collide with any Windows errors.

Other than Windows errors, the other types of errors we must support
on Windows are:

. errnos set by C run-time library
. portable APR error codes like APR_ENOPOOL and status codes like
  APR_EOF 
. error codes from other libraries such as those from libtool

For Windows, this implementation of Bill Rowe's desired
classification/manipulation macros would seem to work:

/* use bits 31-30 to indicate which type of non-Windows error it
   is; bit 29 is on for any non-Windows errors */

#define APR_ERRORTYPE_MASK  0xE0000000

#define APR_ERRORTYPE_OS    0x00000000
#define APR_ERRORTYPE_ERRNO 0x20000000
#define APR_ERRORTYPE_APR   0xA0000000
(room for two more types with this value of APR_ERRORTYPE_MASK; we can
always steal more lower-order bits in the future)

#define APR_STATUS_IS_OS(s) \
        (((s) & APR_ERRORTYPE_MASK) == APR_ERRORTYPE_OS)

#define APR_STATUS_IS_ERRNO(s) \
        (((s)&APR_ERRORTYPE_MASK) == APR_ERRORTYPE_ERRNO)

#define APR_STATUS_OF_ERRNO(e) \
        ((e) APR_ERRORTYPE_ERRNO)

#define APR_ERRNO_OF_STATUS(s) \
        ((s) &~APR_ERRORTYPE_ERRNO)

(similar gorp for other types of error values)

UNIX is similar, though there is no requirement for bit 29 and no
separate OS error, since OS errors are errnos.  APR_STATUS_IS_OS()
would always return 0 (false).

The implementation of ap_strerror() could be very similar to the one I
posted this morning, but the test macros would be used instead of
looking at the range of the value.  The routine to describe an OS
error would be in an OS-specific file, but most of ap_strerror() is
portable.  The bulk of it is in the service routines which describe
the portable APR error/status codes.

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

RE: ap_status_t for Win32

Posted by "William A. Rowe, Jr." <wr...@lnd.com>.
> Only one small part of ap_strerror() is not portable: the mechanism
> for retrieving the description of an OS-specific error.
> 
> Summary of portability:
> 
>   portable parts of the ap_strerror()
> 
>   . code to identify that error is errno
>   . code to grab description for an errno
>   . code to identify that error is APR error/status code
>   . code to grab description for an APR error/status code

Correct, all portable.

>   . code to identify that error is OS-specific error code

Not portable, but what if you do this in apr_win.h (and on
those platforms that need it, in their apr.h autoconf target):

#define HAVE_OSERROR

and in apr_error.h:

#ifdef HAVE_OSERROR
ap_status_t ap_str_oserror(ap_status_t erno, char * errmsg [...]);
#endif

and in lib/apr_strerror.c - add to ap_strerror()

#ifdef HAVE_OSERROR
    else if (APR_IS_OSERROR(erno)
    {
        stat = ap_str_oserror(erno, msg, [...]);
        if (stat)
             ap_strcat(msg, "Unknown system error ", ernostr [...])
    }
#endif

and in misc/os/errors.c declare ap_str_oserror().

that's some real rough metacode, but it is cross platform.  I believe
noone wants to see the laundry list if #if OS in our xplat apr!

>   . code to handle other types of error codes

Portable?  This should return an error code itself that no 
message was available.
 
>   non-portable parts of ap_strerror()
> 
>   . code to grab description for an OS-specific error code
> 
> Clearly, ap_strerror() is largely (85%?) portable.  It just needs a
> service routine implemented for each platform to retrieve the
> description for an OS-specific error code.

Sold.
 
> The implementations of the macros to manipulate ap_status_t are
> definitely unique to each OS, but that is outside of the scope of
> ap_strerror(). 

Right, I believe apr.h or apr_config.h is the right place for that.

> -- 
> Jeff Trawick | trawick@ibm.net | PGP public key at web site:
>      http://www.geocities.com/SiliconValley/Park/9289/
>           Born in Roswell... married an alien...
> 

Re: ap_status_t for Win32

Posted by Jeff Trawick <tr...@bellsouth.net>.
Thanks for the clarification... will-do...

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: ap_status_t for Win32

Posted by rb...@apache.org.

> On Windows, ap_status_t sometimes contains GetLastError() values and
> sometimes contains errno values and sometimes contains APR-specific
> error codes (and maybe sometimes contains other types of error codes).
> (1) This means that the application is not currently able to get a
> description of the error for presentation to the user.  (2) It also means
> that the application is not able to compare it with particular error
> codes that it has logic to handle.

Yes, Windows is broken.  Sometime is returns errno, sometimes it returns
GetLastError values.  I posted where that needs to be fixed.  And, every
single time this needs to be fixed, there is already a TODO in the code.

> Example of the first problem: Currently, the text description returned
> by strerror() to ap_log_error() is almost always bogus on Windows because
> most errors passed around on Windows are from GetLastError().  We
> might as well put #ifndef WIN32 around the logic to describe the
> error, unless the use of ap_status_t is straightened out and
> ap_strerror() is subsequently implemented (it can't be implemented
> until it has a way to interpret ap_status_t).

That #ifdef was there, we took it out in ap_log_error().  Implement
ap_strerror, because currently all ap_strerror does is call strerror.  The
fault lies in this being an incomplete implementation, not a faulty
design.  Go read the design that happened on new-httpd when this stuff was
originally committed.

> Example of the second problem: Suppose an application calls
> ap_do_something_cool(), which returns the number 99 in the ap_status_t
> result.  In most places, the application just cares whether or not the
> result is APR_SUCCESS, but in this case, the application needs to know
> exactly what error occurred -- APR_EOF?  ENOSPC?
> ERROR_SERVER_NOT_RESPONDING? -- so that it can implement a specific
> recovery strategy.

For APR status or APR error codes, these values are specified in a header
file with both a name and a value.  For OS specific errors, we will need
to implement a function ap_canonical_error, which converts a SMALL subset
of error values to the Unix errno definition.

> Maybe I can't understand it because I see another philosophy being
> used in APR today and I assumed that it was basically correct.  

The windows port has never been finished in this regard.  The correct
implementation was discussed on new-httpd.

> Should I go delete all the APR_ constants in apr_errno.h, change all
> APR code to use only OS-specific error codes (that's errno on UNIX and
> GetLastError()-type error codes on Windows)?

Don't delete any defintions.  Go into apr_errno, and re-define all of the
APR_FOO macros for use on windows.  This should work just fine.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: ap_status_t for Win32

Posted by Jeff Trawick <tr...@bellsouth.net>.
> What is the problem that Windows is actually having?  I still haven't seen
> a description of the actual problem we are trying to solve here.

On Windows, ap_status_t sometimes contains GetLastError() values and
sometimes contains errno values and sometimes contains APR-specific
error codes (and maybe sometimes contains other types of error codes).
(1) This means that the application is not currently able to get a
description of the error for presentation to the user.  (2) It also means
that the application is not able to compare it with particular error
codes that it has logic to handle.

Example of the first problem: Currently, the text description returned
by strerror() to ap_log_error() is almost always bogus on Windows because
most errors passed around on Windows are from GetLastError().  We
might as well put #ifndef WIN32 around the logic to describe the
error, unless the use of ap_status_t is straightened out and
ap_strerror() is subsequently implemented (it can't be implemented
until it has a way to interpret ap_status_t).

Example of the second problem: Suppose an application calls
ap_do_something_cool(), which returns the number 99 in the ap_status_t
result.  In most places, the application just cares whether or not the
result is APR_SUCCESS, but in this case, the application needs to know
exactly what error occurred -- APR_EOF?  ENOSPC?
ERROR_SERVER_NOT_RESPONDING? -- so that it can implement a specific
recovery strategy.

> This is what nobody seems to understand, ALL error codes should be
> OS-specific.  If they aren't currently, that's a bug, scratch the itch by
> fixing the bug, not working around it.

Maybe I can't understand it because I see another philosophy being
used in APR today and I assumed that it was basically correct.  

I'm trainable (I promise!) and I appreciate your attention to this.

Please understand that to me the existing APR implementation is
screaming "sometimes we need to return OS-specific error codes and
sometimes we need to return APR-specific error codes."  I didn't make
this up.  Jeff Trawick didn't come along after all the hard work was
done and suggest out of the blue that APR should work this way.
Instead, that is what you and others have actually implemented. 

Should I go delete all the APR_ constants in apr_errno.h, change all
APR code to use only OS-specific error codes (that's errno on UNIX and
GetLastError()-type error codes on Windows)?

Thanks for your time,

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

RE: ap_status_t for Win32

Posted by rb...@apache.org.
> > definitions that tell the OS where to place it's own error 
> > numbers.  Set
> > APR_OS_START_ERROR = 0xA0000000.  Move on from there.
> 
> Actually, what about inverting the 29th bit for windows errors.
> ergo, erno & 0x20000000 is reserved for windows, everything else
> stays apr, and the bit is flipped back on evaulation.
> 
> What I'm trying to propose is cross platform defintions of macro
> wrappers, not a specific means to the end.

Ahh.  So we are trying to solve two different problems.  :-)  That
explains why I couldn't see the need for all of this.  I'm still not sure
if this is required or not, simply because if you just define APR_OS_FOO
in apr_errno.h, you have cross-platform APR status and error codes
already.

Ryan


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


RE: ap_status_t for Win32

Posted by "William A. Rowe, Jr." <wr...@lnd.com>.
> There is a major problem with this technique.  You can't just do:
> 
> if (STATUS == APR_EFOO) {
> ...
> }

Yes, you can, if...

#define APR_STATUS_FROM_APR(stat) [Make up your math formala here]

#define APR_EFOO APR_STATUS_FROM_APR(1)

APR_EFOO(const) is evaluated by the compiler, so that the macro
is no slower than #define APR_EFOO 1.

> That, and it's not really necessary.

Leaving that for you and Jeff to quibble over <g>
 
> You want Windows to have it's own range of numbers?  We have four
> definitions that tell the OS where to place it's own error 
> numbers.  Set
> APR_OS_START_ERROR = 0xA0000000.  Move on from there.

Actually, what about inverting the 29th bit for windows errors.
ergo, erno & 0x20000000 is reserved for windows, everything else
stays apr, and the bit is flipped back on evaulation.

What I'm trying to propose is cross platform defintions of macro
wrappers, not a specific means to the end.

Re: ap_status_t for Win32

Posted by rb...@apache.org.
> > > For Windows, this implementation of Bill Rowe's desired
> > > classification/manipulation macros would seem to work:
> > >
> > > /* use bits 31-30 to indicate which type of non-Windows error it
> > >    is; bit 29 is on for any non-Windows errors */
> > >
> > > #define APR_ERRORTYPE_MASK  0xE0000000
> > >
> > > #define APR_ERRORTYPE_OS    0x00000000
> > > #define APR_ERRORTYPE_ERRNO 0x20000000
> > > #define APR_ERRORTYPE_APR   0xA0000000
> > > (room for two more types with this value of APR_ERRORTYPE_MASK; we can
> > > always steal more lower-order bits in the future)

There is a major problem with this technique.  You can't just do:

if (STATUS == APR_EFOO) {
...
}

That, and it's not really necessary.

You want Windows to have it's own range of numbers?  We have four
definitions that tell the OS where to place it's own error numbers.  Set
APR_OS_START_ERROR = 0xA0000000.  Move on from there.

I understand that Windows returns different error values, depending on
which type of function was called.  One of the reasons for APR, is that we
want to always use Window's native calls.  APR should NEVER be returning a
non-native error code on Windows, IMHO.  If this is true, then we need to
figure out why it isn't true.

> I'm not going to start with a UNIX-only implementation first, commit
> it, and then start worrying about Win32.  Win32 is the platform with
> the biggest problem now.  (Maybe OS/2 and BeOS as well, but I don't really
> know.)  If somebody wants to do an implementation that handles only

What is the problem that Windows is actually having?  I still haven't seen
a description of the actual problem we are trying to solve here.

> the simple case, go right ahead.  I was interested in an initial
> implementation that handled UNIX and Win32, in the hopes that if it
> handled those two then to add support for some other platform would
> not require much reinvention.  Also, I personally have not been
> frustrated with ap_status_t descriptions on UNIX (the current
> strerror() code works most of the time) but I do on Win32 (most of the
> time the error string is bogus).  Without a solution for my itch,
> there is no reason for me to scratch.  Sorry!

> I have tried to explain in previous notes how much of it is portable.
> Your use of upper case does not help me to come to agreement.
> Explaining *why* a particular statement I am making is wrong does.
> Start with the statements below and help me out.  
> 
> Only one small part of ap_strerror() is not portable: the mechanism
> for retrieving the description of an OS-specific error.
> 
> Summary of portability:
> 
>   portable parts of the ap_strerror()
> 
>   . code to identify that error is errno
>   . code to grab description for an errno

One problem here, not all platforms use errno.

>   . code to identify that error is APR error/status code
>   . code to grab description for an APR error/status code
>   . code to identify that error is OS-specific error code

This is what nobody seems to understand, ALL error codes should be
OS-specific.  If they aren't currently, that's a bug, scratch the itch by
fixing the bug, not working around it.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: ap_status_t for Win32

Posted by Jeff Trawick <tr...@bellsouth.net>.
Once Ryan had hammered into my head his desired design point, I was
willing to take it on faith for a while and see where I ended up.  I'm
afraid I've hit a big mental block on what I should define APR error
codes to be on a system where we might call fwrite() or an OS call
(one that doesn't set errno) at different places in APR.

Backing up just a bit...

I think an extremely important characteristic of Ryan's design is that
it allows an APR application to code something like this:

  status = ap_foo();
  switch(status) {
    case APR_SUCCESS:
      break;
    case APR_ENOENT:
      status = recover1();
      break;
    case APR_ENOSPC:
      status = recover2();
      break;
    case APR_EPERM:
      status = recover3();
      break;
  }

This is absolutely critical.  To do anything else is a crime.  This
was completely missing from my previous thoughts on this subject.

But back to the mental block on how to solve this by simply defining
the APR error codes to the right value?

What is APR_EPERM on a system where the APR implementation sometimes
calls C Standard Library functions (i.e., use errno) and sometimes
calls the OS kernel (i.e., use Win32 error codes or OS/2 error codes)
and maybe even calls some other code that could result in an error
with the same meaning as APR_EPERM?

We could #define APR_EPERM to the C library's EPERM, but we then need to
map at run-time OS errors which mean the same thing to APR_EPERM since
we can't #define APR_EPERM to both the errno value *and* the analogous
OS error.

Not all OS errors will map to APR_Esomething so sometimes ap_status_t
needs to return the raw OS error.  This would likely lead to a generic
error path in the APR app rather than a specific error recovery path.
However, the app needs the capability to know that this is a
particular OS error.  Similarly, it is very useful for ap_strerror()
to know that this is a particular OS error as well.

I think a hybrid design is needed.  We would emphasize the use of APR
error codes such as APR_EPERM, APR_EIO, APR_EINVAL, etc.  APR routines
would return these error codes whenever possible.

The APR implementer could do something like this on certain systems:

  executable code in APR:

  if (clibfunc() == -1) /* a C library call failed */
    status = errno_to_status(errno);

  if (!kernelfunc())
    status = oserr_to_status(GetLastError());

  ap_status_t errno_to_status(int err)
  {
    /* hot darn!  We define our APR errors in terms of errno to start
       with, so we don't have to do much here; if this errno doesn't
       have an APR_Exyz mapping, that's o.k. */

    return APR_STATUS_OF_ERRNO(err);
  }

  ap_status_t oserr_to_status(int err)
  {
    /* These are the normal run-of-the-mill errors we get on this
       platform which map to APR's error codes; 
    switch(err) {
      case I_CAINT_FIND_THAT_DARN_FILE_NOWHERE:
        return APR_STATUS_OF_ERRNO(ENOENT);
      case YOU_CAINT_DO_THAT_BUDDY:
        return APR_STATUS_OF_ERRNO(EPERM);
      case GO_BUY_YERSELF_A_BIGGER_HARD_DISK:
        return APR_STATUS_OF_ERRNO(ENOSPC);
    }
    
    /* This system has all sorts of weird errors which don't have any
       meaning anywhere else.  Just return the OS error. */

    return APR_STATUS_OF_OSERR(err);
  }

So what about APR_STATUS_OF_ERRNO() and APR_STATUS_OF_OSERR()?
Unfortunately, we'll need to use some encoding mechanism, possibly
different on different systems) to indicate what type of error code it
is so that ap_strerror() will work correctly and so that apps can
write OS-specific code to handle errors which don't map to APR in
those infrequent cases where it is really required.  There has been
some discussion on these encoding mechanisms already :)

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: ap_status_t for Win32

Posted by Ben Laurie <be...@algroup.co.uk>.
Jeff Trawick wrote:
> On Win32, Microsoft says that the OS can return any error value except
> when bit 29 is on.  Some sample code posted previously has played with
> bit 29 via masks; other sample code (like what I posted this morning)
> has played with bit 29 via offsets to be added.  Regardless of the
> mechanism, it is clear that bit 29 is important if we need to be able
> to represent certain OS error codes in ap_status_t.  The ones that
> need to be represented are the ones that can't be mapped to the
> appropriate APR errno-style return code.

This is giving me an incredible sensation of deja vu (but fear not, it
was in another existence, so you are not to blame). Anyway, let me just
say that when I researched this question many moons ago, the bit 29
thing was also in OS/2 (in fact, most of Windoze was also in OS/2, but
with three more letters in front of everything), but there was
absolutely no sensible way to do this on 'nix. Except pragmatically, of
course. For which I recommend setting (or not setting, depending on
inversion preference) bit 29.

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

Re: ap_status_t for Win32

Posted by Jeff Trawick <tr...@bellsouth.net>.
> This is the general approach which the error code started with.  The
> general idea being that all errno errors should be valid across
> platforms.

yessir

> This only works one of two ways:
> 
> 1)  Everybody returns the errno value (bad idea)
> 
> 2)  Everybody returns system error codes, and we have a function that
> converts to errno values for a small subset.  This function should not be
> called often.
> 
> I just re-read Brian's last post where he outlines the advantages of his
> scheme.  I think the problem is Brian didn't understand what I thought I
> said.  :-)
> 
> I am all for Brian's scheme, where an offset is defined for OSCODE's.  I
> just think that most if not all of the primitives are there to support it.
> 
> We have four definitions in apr_errno.h.  Those are currently hard-coded
> the same for all platforms.  These should be different for each platform.
> Then, if we want to add a fifth definition for those platforms that need
> it, we can.

yessir

> 
> I don't think we need bit masks, just integer values.  I still haven't see
> an argument that bitmasks are important.

On Win32, Microsoft says that the OS can return any error value except
when bit 29 is on.  Some sample code posted previously has played with
bit 29 via masks; other sample code (like what I posted this morning)
has played with bit 29 via offsets to be added.  Regardless of the
mechanism, it is clear that bit 29 is important if we need to be able
to represent certain OS error codes in ap_status_t.  The ones that
need to be represented are the ones that can't be mapped to the
appropriate APR errno-style return code.

I think we were typing at the same time a few minutes ago...  In
that post, I mentioned that we can use W. Rowe's idea of inverting the
meaning of bit 29 on Win32 so that "return errno" works.

As you say, this all works basically like what had been outlined in
apr_errno.h all along, but with some details fleshed out.

I'm quite interested in your take on the concept of a function on
non-UNIX which maps OS errors to the appropriate APR errno-style
return code... 

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: ap_status_t for Win32

Posted by rb...@apache.org.

This is the general approach which the error code started with.  The
general idea being that all errno errors should be valid across platforms.
This only works one of two ways:

1)  Everybody returns the errno value (bad idea)

2)  Everybody returns system error codes, and we have a function that
converts to errno values for a small subset.  This function should not be
called often.

I just re-read Brian's last post where he outlines the advantages of his
scheme.  I think the problem is Brian didn't understand what I thought I
said.  :-)

I am all for Brian's scheme, where an offset is defined for OSCODE's.  I
just think that most if not all of the primitives are there to support it.

We have four definitions in apr_errno.h.  Those are currently hard-coded
the same for all platforms.  These should be different for each platform.
Then, if we want to add a fifth definition for those platforms that need
it, we can.

I don't think we need bit masks, just integer values.  I still haven't see
an argument that bitmasks are important.

Ryan

On Sat, 1 Apr 2000, Jeff Trawick wrote:

> Here are some excerpts of a version of apr_errno.h which I was playing
> with last night.  I just quickly drafted in some OS2 logic.  More
> macros are needed for testing the type of error code and for
> extracting a certain type of error code, but those are pretty simple.
> 
> What changes are needed from this for OS/2?  Is there anything which this
> doesn't handle?
> 
> The definitions of the offsets need to be in an OS-specific header
> file.  This is pretty darn ugly.
> 
> /* Define four layers of status code offsets so that we don't interfere
>  * with the predefined errno codes on the operating system.  Codes beyond
>  * APR_OS_START_USEERR are reserved for applications that use APR that
>  * layer their own error codes along with APR's.
>  *
>  * For platforms where errnos and system error codes collide, use an offset
>  * for errnos as well.
>  */
> 
> #ifdef WIN32
> 
> /* In order to represent system error codes or APR error codes or other types
>  * of error codes in an int, use offsets like with other platforms but also 
>  * turn on bit 29 because all other values are reserved for the system.
>  */
> 
> #ifndef APR_OS_START_OSERR
> #define APR_OS_START_OSERR      0x00000000
> #endif
> #ifndef APR_OS_START_APRERROR
> #define APR_OS_START_APRERROR   0x20000000
> #endif
> #ifndef APR_OS_START_APRSTATUS  
> #define APR_OS_START_APRSTATUS  0x20000200
> #endif
> #ifndef APR_OS_START_SYSERR
> #define APR_OS_START_SYSERR     0x20000400
> #endif
> #ifndef APR_OS_START_ERRNO
> #define APR_OS_START_ERRNO      0x20000600
> #endif
> #ifndef APR_OS_START_USEERR
> #define APR_OS_START_USEERR     0x20000800
> #endif
>  
> #else
> 
> #ifdef OS2
> 
> #ifndef APR_OS_START_OSERR
> #define APR_OS_START_OSERR      some-magic-number
> #endif
> 
> #else
> 
> #ifndef APR_OS_START_OSERR
> #define APR_OS_START_OSERR      0 /* UNIX */
> #endif
> 
> #endif
> 
> #ifndef APR_OS_START_ERRNO
> #define APR_OS_START_ERRNO      0
> #endif
> #ifndef APR_OS_START_APRERROR
> #define APR_OS_START_APRERROR   4000
> #endif
> #ifndef APR_OS_START_APRSTATUS
> #define APR_OS_START_APRSTATUS  (APR_OS_START_APRERROR + 500)
> #endif
> #ifndef APR_OS_START_SYSERR
> #define APR_OS_START_SYSERR  (APR_OS_START_STATUS + 500)
> #endif
> #ifndef APR_OS_START_USEERR
> #define APR_OS_START_USEERR  (APR_OS_START_SYSERR + 10000)
> #endif
> #endif /* WIN32 */
> 
> #ifndef APR_STATUS_FROM_OSERR
> #define APR_STATUS_FROM_OSERR(err) ((err) + APR_OS_START_OSERR)
> #endif
> #ifndef APR_STATUS_FROM_APRERROR
> #define APR_STATUS_FROM_APRERROR(err) ((err) + APR_OS_START_APRERROR)
> #endif
> #ifndef APR_STATUS_FROM_APRSTATUS
> #define APR_STATUS_FROM_APRSTATUS(err) ((err) + APR_OS_START_STATUS)
> #endif
> #ifndef APR_STATUS_FROM_SYSERR
> #define APR_STATUS_FROM_SYSERR(err) ((err) + APR_OS_START_SYSERR)
> #endif
> #ifndef APR_STATUS_FROM_ERRNO
> #define APR_STATUS_FROM_ERRNO(err) ((err) + APR_OS_START_ERRNO)
> #endif
> 
> #define APR_SUCCESS 0
> 
> /* APR ERROR VALUES */
> #define APR_ENOSTAT        APR_STATUS_FROM_APRERROR(1)
> #define APR_ENOPOOL        APR_STATUS_FROM_APRERROR(2)
> #define APR_ENOFILE        APR_STATUS_FROM_APRERROR(3)
> 
> ...
> 
> /* APR STATUS VALUES */
> #define APR_INCHILD        APR_STATUS_FROM_APRSTATUS(1)
> #define APR_INPARENT       APR_STATUS_FROM_APRSTATUS(2)
> #define APR_DETACH         APR_STATUS_FROM_APRSTATUS(3)
> #define APR_NOTDETACH      APR_STATUS_FROM_APRSTATUS(4)
> 
> ...
> 
> /*
>  * APR equivalents to what should be standard errno codes.
>  */
> #ifdef EACCES
> #define APR_EACCES APR_STATUS_FROM_ERRNO(EACCES)
> #else
> #define APR_EACCES APR_STATUS_FROM_SYSERR(0)
> #endif
> 
> #ifdef EEXIST
> #define APR_EEXIST APR_STATUS_FROM_ERRNO(EEXIST)
> #else
> #define APR_EEXIST APR_STATUS_FROM_SYSERR(1)
> #endif
> 
> ...
> 
> /* never use h_errno values as-is because they can't be distinguished
>  * from errno values
>  * APR_EHOSTNOTFOUND corresponds to HOST_NOT_FOUND
>  * APR_ENODATA corresponds to NO_DATA
>  * APR_ENOADDRESS corresponds to NO_ADDRESS
>  * APR_ENORECOVERY corresponds to NO_RECOVERY
>  */
> #define APR_EHOSTNOTFOUND APR_STATUS_FROM_SYSERR(36)
> 
> #define APR_ENODATA APR_STATUS_FROM_SYSERR(37)
> 
> #define APR_ENOADDRESS APR_STATUS_FROM_SYSERR(38)
> 
> #define APR_ENORECOVERY APR_STATUS_FROM_SYSERR(39)
> 
> #ifdef EISCONN
> #define APR_EISCONN APR_STATUS_FROM_ERRNO(EISCONN)
> #else
> #define APR_EISCONN APR_STATUS_FROM_SYSERR(40)
> #endif
> 
> 
> 
> -- 
> Jeff Trawick | trawick@ibm.net | PGP public key at web site:
>      http://www.geocities.com/SiliconValley/Park/9289/
>           Born in Roswell... married an alien...
> 


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------



Re: ap_status_t for Win32

Posted by Jeff Trawick <tr...@bellsouth.net>.
Here are some excerpts of a version of apr_errno.h which I was playing
with last night.  I just quickly drafted in some OS2 logic.  More
macros are needed for testing the type of error code and for
extracting a certain type of error code, but those are pretty simple.

What changes are needed from this for OS/2?  Is there anything which this
doesn't handle?

The definitions of the offsets need to be in an OS-specific header
file.  This is pretty darn ugly.

/* Define four layers of status code offsets so that we don't interfere
 * with the predefined errno codes on the operating system.  Codes beyond
 * APR_OS_START_USEERR are reserved for applications that use APR that
 * layer their own error codes along with APR's.
 *
 * For platforms where errnos and system error codes collide, use an offset
 * for errnos as well.
 */

#ifdef WIN32

/* In order to represent system error codes or APR error codes or other types
 * of error codes in an int, use offsets like with other platforms but also 
 * turn on bit 29 because all other values are reserved for the system.
 */

#ifndef APR_OS_START_OSERR
#define APR_OS_START_OSERR      0x00000000
#endif
#ifndef APR_OS_START_APRERROR
#define APR_OS_START_APRERROR   0x20000000
#endif
#ifndef APR_OS_START_APRSTATUS  
#define APR_OS_START_APRSTATUS  0x20000200
#endif
#ifndef APR_OS_START_SYSERR
#define APR_OS_START_SYSERR     0x20000400
#endif
#ifndef APR_OS_START_ERRNO
#define APR_OS_START_ERRNO      0x20000600
#endif
#ifndef APR_OS_START_USEERR
#define APR_OS_START_USEERR     0x20000800
#endif
 
#else

#ifdef OS2

#ifndef APR_OS_START_OSERR
#define APR_OS_START_OSERR      some-magic-number
#endif

#else

#ifndef APR_OS_START_OSERR
#define APR_OS_START_OSERR      0 /* UNIX */
#endif

#endif

#ifndef APR_OS_START_ERRNO
#define APR_OS_START_ERRNO      0
#endif
#ifndef APR_OS_START_APRERROR
#define APR_OS_START_APRERROR   4000
#endif
#ifndef APR_OS_START_APRSTATUS
#define APR_OS_START_APRSTATUS  (APR_OS_START_APRERROR + 500)
#endif
#ifndef APR_OS_START_SYSERR
#define APR_OS_START_SYSERR  (APR_OS_START_STATUS + 500)
#endif
#ifndef APR_OS_START_USEERR
#define APR_OS_START_USEERR  (APR_OS_START_SYSERR + 10000)
#endif
#endif /* WIN32 */

#ifndef APR_STATUS_FROM_OSERR
#define APR_STATUS_FROM_OSERR(err) ((err) + APR_OS_START_OSERR)
#endif
#ifndef APR_STATUS_FROM_APRERROR
#define APR_STATUS_FROM_APRERROR(err) ((err) + APR_OS_START_APRERROR)
#endif
#ifndef APR_STATUS_FROM_APRSTATUS
#define APR_STATUS_FROM_APRSTATUS(err) ((err) + APR_OS_START_STATUS)
#endif
#ifndef APR_STATUS_FROM_SYSERR
#define APR_STATUS_FROM_SYSERR(err) ((err) + APR_OS_START_SYSERR)
#endif
#ifndef APR_STATUS_FROM_ERRNO
#define APR_STATUS_FROM_ERRNO(err) ((err) + APR_OS_START_ERRNO)
#endif

#define APR_SUCCESS 0

/* APR ERROR VALUES */
#define APR_ENOSTAT        APR_STATUS_FROM_APRERROR(1)
#define APR_ENOPOOL        APR_STATUS_FROM_APRERROR(2)
#define APR_ENOFILE        APR_STATUS_FROM_APRERROR(3)

...

/* APR STATUS VALUES */
#define APR_INCHILD        APR_STATUS_FROM_APRSTATUS(1)
#define APR_INPARENT       APR_STATUS_FROM_APRSTATUS(2)
#define APR_DETACH         APR_STATUS_FROM_APRSTATUS(3)
#define APR_NOTDETACH      APR_STATUS_FROM_APRSTATUS(4)

...

/*
 * APR equivalents to what should be standard errno codes.
 */
#ifdef EACCES
#define APR_EACCES APR_STATUS_FROM_ERRNO(EACCES)
#else
#define APR_EACCES APR_STATUS_FROM_SYSERR(0)
#endif

#ifdef EEXIST
#define APR_EEXIST APR_STATUS_FROM_ERRNO(EEXIST)
#else
#define APR_EEXIST APR_STATUS_FROM_SYSERR(1)
#endif

...

/* never use h_errno values as-is because they can't be distinguished
 * from errno values
 * APR_EHOSTNOTFOUND corresponds to HOST_NOT_FOUND
 * APR_ENODATA corresponds to NO_DATA
 * APR_ENOADDRESS corresponds to NO_ADDRESS
 * APR_ENORECOVERY corresponds to NO_RECOVERY
 */
#define APR_EHOSTNOTFOUND APR_STATUS_FROM_SYSERR(36)

#define APR_ENODATA APR_STATUS_FROM_SYSERR(37)

#define APR_ENOADDRESS APR_STATUS_FROM_SYSERR(38)

#define APR_ENORECOVERY APR_STATUS_FROM_SYSERR(39)

#ifdef EISCONN
#define APR_EISCONN APR_STATUS_FROM_ERRNO(EISCONN)
#else
#define APR_EISCONN APR_STATUS_FROM_SYSERR(40)
#endif



-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: ap_status_t for Win32 (some conclusion finally?)

Posted by Jeff Trawick <tr...@bellsouth.net>.
> >If I change the APR error definitions I posted earlier today so that
> >on Windows "return errno" works and that in macros we play some trick
> >on Windows like turn on bit 29 for native OS errors, does that meet
> >your approval? 
> 
> I think this is more complex than is needed as it's platform
> specific.

The "trick" to turn on bit 29 is simply a special offset (0x20000000)
to add to OS errors on Win32 so that bit 29 is on.  All non-OS errors
on Win32 should have bit 29 off in our ap_status_t scheme*; thus our
offsets for other types of error codes will be smaller than 0x20000000 

(*this is the opposite of Microsoft's mapping, but we're smart enough
not to get confused)

> Some other platform may have actual error codes that have bit 29
> set.

not an issue at all...  we only have the bit 29 problem on Windows,
and it was already recognized that not all systems will have the same
values for the offset constants.  The bit 29 problem can be solved
simply by defining a special OS-error-offset-constant on Windows.

> Take a look at my proposed scheme and if you can find a significant
> disadvantage or deficiency in it then let us know. The way I've worked
> it, nothing needs to know about any bit mappings in Win32 error codes
> and should work in an identical way on all platforms. In fact it's so
> simple there must be _something_ wrong with it or we would have come up
> with it long ago (unless we're just slow that is ;-)

I just read it and I'm not sure exactly what you're alluding to.

If your proposed scheme is that the offset constants have the same
value on every platform, it is broken because different platforms have
different requirements.  In particular, for OS errors on Win32 we'll
flip on bit 29 by adding the magic constant.

If your proposed scheme allows different offset constants for
different platforms, then it seems like we're all talking about the
same thing with different names.

You called the constant AP_OSCODE_OFFSET and the macro AP_OS_STATUS().
I called the constant APR_OS_START_OSERR and the macro
APR_STATUS_FROM_OSERR().  This macro name came from Mr. Rowe.  The
constant name follows the pattern set in apr_errno.h long ago. 

Let me repost the code I showed this morning, but with the fix to
allow "return errno" to work on Win32.  Except for the system-specific
logic to define the offset constants, I think it is basically the same
as what you proposed.  There were some additional macros, however.

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: ap_status_t for Win32 (some conclusion finally?)

Posted by rb...@apache.org.
> >If I change the APR error definitions I posted earlier today so that
> >on Windows "return errno" works and that in macros we play some trick
> >on Windows like turn on bit 29 for native OS errors, does that meet
> >your approval? 
> 
> I think this is more complex than is needed as it's platform specific.
> Some other platform may have actual error codes that have bit 29 set.
> Take a look at my proposed scheme and if you can find a significant
> disadvantage or deficiency in it then let us know. The way I've worked
> it, nothing needs to know about any bit mappings in Win32 error codes
> and should work in an identical way on all platforms. In fact it's so
> simple there must be _something_ wrong with it or we would have come up
> with it long ago (unless we're just slow that is ;-)

Brian,

Unless I;ve misread your idea, it's just perfect.  And, we did come up
with it a long time ago, we just didn't take it far enough.  Your idea
should basically just add another macro that needs to be defined on each
platform.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: ap_status_t for Win32 (some conclusion finally?)

Posted by Brian Havard <br...@kheldar.apana.org.au>.
On Sat, 1 Apr 2000 12:34:36 -0500, Jeff Trawick wrote:

>> > - It allows using the default unix implementation on non-unix platforms
>> > without having to use macro wrappers around errno. IE "return errno;"
>> > can be used safely everywhere.
>> 
>> All the advantages I was hoping for.  As long as we can "return errno" and
>> do a 
>
>Ryan (and anyone else):
>
>If I change the APR error definitions I posted earlier today so that
>on Windows "return errno" works and that in macros we play some trick
>on Windows like turn on bit 29 for native OS errors, does that meet
>your approval? 

I think this is more complex than is needed as it's platform specific.
Some other platform may have actual error codes that have bit 29 set.
Take a look at my proposed scheme and if you can find a significant
disadvantage or deficiency in it then let us know. The way I've worked
it, nothing needs to know about any bit mappings in Win32 error codes
and should work in an identical way on all platforms. In fact it's so
simple there must be _something_ wrong with it or we would have come up
with it long ago (unless we're just slow that is ;-)

-- 
 ______________________________________________________________________________
 |  Brian Havard                 |  "He is not the messiah!                   |
 |  brianh@kheldar.apana.org.au  |  He's a very naughty boy!" - Life of Brian |
 ------------------------------------------------------------------------------


Re: ap_status_t for Win32 (some conclusion finally?)

Posted by Jeff Trawick <tr...@bellsouth.net>.
> > - It allows using the default unix implementation on non-unix platforms
> > without having to use macro wrappers around errno. IE "return errno;"
> > can be used safely everywhere.
> 
> All the advantages I was hoping for.  As long as we can "return errno" and
> do a 

Ryan (and anyone else):

If I change the APR error definitions I posted earlier today so that
on Windows "return errno" works and that in macros we play some trick
on Windows like turn on bit 29 for native OS errors, does that meet
your approval? 

We can get rid of the APR_STATUS_FROM_ERRNO() junk since errno is
always the natural ap_status_t.

The bit-29 thing is a Microsoft-ism.  They say they own all error
codes where bit 29 is off.  We can invert that (as W. Rowe) suggested
so that "return errno" works.  This isn't a problem as far as I am
concerned.

Do you agree that non-UNIX APR will need a way at run-time to map
OS-specific functions to APR_Exxx return codes, as illustrated in a
post I made yesterday?

Thanks a bunch!

Jeff
-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: ap_status_t for Win32

Posted by rb...@apache.org.
> As I understand it, the current scheme doesn't really work in that
> errno values collide with OS error codes. 
> EG, on OS/2 APR_ENOMEM == ENOMEM == 12
> 
> but in OS/2's codes
> 
> #define ERROR_INVALID_ACCESS    12
> 
> 
> The advantages of my scheme are:
> - It's simple (always a good thing :)
> - It can be done exactly the same on all platforms.
> - It allows using the default unix implementation on non-unix platforms
> without having to use macro wrappers around errno. IE "return errno;"
> can be used safely everywhere.

All the advantages I was hoping for.  As long as we can "return errno" and
do a 

status = ap_foo_func();

if status != APR_SUCCESS

I say go for it.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: ap_status_t for Win32

Posted by Brian Havard <br...@kheldar.apana.org.au>.
On Fri, 31 Mar 2000 11:29:18 -0500 (EST), rbb@apache.org wrote:

>> Just an idea (feel free to shoot it down, I haven't thought about it
>> too hard), what if OS error codes were offset some fixed amount,
>> leaving 0->n for errno codes? The only exception being 0 stays 0 (which
>> == APR_SUCCESS). A macro for returning an OS error code could be:
>> 
>> AP_APRCODE_OFFSET 100  /* some room for APR defined codes */
>> AP_OSCODE_OFFSET  200
>> AP_OS_STATUS(oscode) (oscode ? oscode + AP_OSCODE_OFFSET : APR_SUCCESS)
>
>Can't all of this be done by just redefining the current APR_FOO macros in
>apr_errno.h by platform, and adding some for platforms that need it.  I
>was under the impression that was the goal when this code was originally
>committed.

As I understand it, the current scheme doesn't really work in that
errno values collide with OS error codes. 
EG, on OS/2 APR_ENOMEM == ENOMEM == 12

but in OS/2's codes

#define ERROR_INVALID_ACCESS    12


The advantages of my scheme are:
- It's simple (always a good thing :)
- It can be done exactly the same on all platforms.
- It allows using the default unix implementation on non-unix platforms
without having to use macro wrappers around errno. IE "return errno;"
can be used safely everywhere.

There should also be a public function to transform OS error codes to
errno type codes that can be used by the application iff it needs to
make a decision based on the particular error. It would be a 'do
nothing' macro on unix.

-- 
 ______________________________________________________________________________
 |  Brian Havard                 |  "He is not the messiah!                   |
 |  brianh@kheldar.apana.org.au  |  He's a very naughty boy!" - Life of Brian |
 ------------------------------------------------------------------------------


Re: ap_status_t for Win32

Posted by rb...@apache.org.
> >If all of these errno returns are gotten rid of, the current errno stuff
> >should work everywhere.
> 
> On OS/2 the situation is similar to Win32 in that some APR functions
> are implemented using C library routines that return errno values &
> others use API calls that return OS/2 error codes. I don't think
> banning errno values is the answer either as we'll then be doomed to
> re-implement C library functions in APR.
> 
> EG. OS/2's ap_create_thread() uses the C library function
> _beginthread() rather than the API call DosCreateThread() as the latter
> doesn't initialize the C library for the new thread.
> 
> Just an idea (feel free to shoot it down, I haven't thought about it
> too hard), what if OS error codes were offset some fixed amount,
> leaving 0->n for errno codes? The only exception being 0 stays 0 (which
> == APR_SUCCESS). A macro for returning an OS error code could be:
> 
> AP_APRCODE_OFFSET 100  /* some room for APR defined codes */
> AP_OSCODE_OFFSET  200
> AP_OS_STATUS(oscode) (oscode ? oscode + AP_OSCODE_OFFSET : APR_SUCCESS)

Can't all of this be done by just redefining the current APR_FOO macros in
apr_errno.h by platform, and adding some for platforms that need it.  I
was under the impression that was the goal when this code was originally
committed.

Ryan


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: ap_status_t for Win32

Posted by Brian Havard <br...@kheldar.apana.org.au>.
I think I need to put my 2c in here.


On Thu, 30 Mar 2000 10:06:07 -0500 (EST), rbb@apache.org wrote:

[...]

>If all of these errno returns are gotten rid of, the current errno stuff
>should work everywhere.

On OS/2 the situation is similar to Win32 in that some APR functions
are implemented using C library routines that return errno values &
others use API calls that return OS/2 error codes. I don't think
banning errno values is the answer either as we'll then be doomed to
re-implement C library functions in APR.

EG. OS/2's ap_create_thread() uses the C library function
_beginthread() rather than the API call DosCreateThread() as the latter
doesn't initialize the C library for the new thread.

Just an idea (feel free to shoot it down, I haven't thought about it
too hard), what if OS error codes were offset some fixed amount,
leaving 0->n for errno codes? The only exception being 0 stays 0 (which
== APR_SUCCESS). A macro for returning an OS error code could be:

AP_APRCODE_OFFSET 100  /* some room for APR defined codes */
AP_OSCODE_OFFSET  200
AP_OS_STATUS(oscode) (oscode ? oscode + AP_OSCODE_OFFSET : APR_SUCCESS)

This is for OS/2 which returns 0 for no error.
ap_strerror() would easily be able to tell what type of code it is just
by comparing it to AP_APRCODE_OFFSET/AP_OSCODE_OFFSET.

As long as the OS doesn't define any codes above 2^32-AP_OSCODE_OFFSET
we have room for everything.

-- 
 ______________________________________________________________________________
 |  Brian Havard                 |  "He is not the messiah!                   |
 |  brianh@kheldar.apana.org.au  |  He's a very naughty boy!" - Life of Brian |
 ------------------------------------------------------------------------------


Re: ap_status_t for Win32

Posted by rb...@apache.org.
I just dug through all of the win32 code to figure out how often we are
returning errno from within APR on windows.  Here's the breakdown.  If you
are having a problem with errno on Windows, remove these errno returns,
don't change an already portable error implementation.  BTW, the reason
the error string you are currently getting is usually wrong, is because we
are calling strerror everywhere currently.

We also currently include errno from a bunch of files on win32, I'm not
going to document those.

ap_get_file_info calls stat, with a note this needs to be changed.  Once
this is changed, we will no longer return errno.

ap_bind is returning errno, but I believe win32 has it's own bind
function, or at least it implements it's own errors on top of bind.

Same thing for accept.  In fact, I was under the impression we weren't
calling accept on win32, hmmm.

gethostbyname is using h_errno.  I am pretty sure this can be replaced by
a windows function

Same thing goes for ap_get_remote_hostname.  There is even a comment that
this is the wrong errno to use (probably)

ap_kill is returning an errno value.

ap_execle is returning an error, this isn't a portable function though,
because I don't think windows has execce anyway.

same goes for execve.

If all of these errno returns are gotten rid of, the current errno stuff
should work everywhere.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------



Re: ap_status_t for Win32

Posted by Jeff Trawick <tr...@bellsouth.net>.
> > Other than Windows errors, the other types of errors we must support
> > on Windows are:
> >
> > . errnos set by C run-time library
> > . portable APR error codes like APR_ENOPOOL and status codes like
> >   APR_EOF
> > . error codes from other libraries such as those from libtool
> 
> PLUS - app specific error extensions (give them a pool of n
> numbers).

fine with me, but as far as I'm concerned, "app specific error
extensions" are a part of the "error codes from other libraries"
problem; an arbitrary number of other libraries could be used with
APR, and app errors are sort of in the same boat

> 
> > For Windows, this implementation of Bill Rowe's desired
> > classification/manipulation macros would seem to work:
> >
> > /* use bits 31-30 to indicate which type of non-Windows error it
> >    is; bit 29 is on for any non-Windows errors */
> >
> > #define APR_ERRORTYPE_MASK  0xE0000000
> >
> > #define APR_ERRORTYPE_OS    0x00000000
> > #define APR_ERRORTYPE_ERRNO 0x20000000
> > #define APR_ERRORTYPE_APR   0xA0000000
> > (room for two more types with this value of APR_ERRORTYPE_MASK; we can
> > always steal more lower-order bits in the future)
> 
> I wouldn't mess with the top 2 bits - leave them alone (40, 80, C0).

What is special about the top two bits?  To me, that helps stay as far
away as possible as the bits that other libraries will want to use for
their own purposes.

> 
> If you like suggestions for win32... using the facility to clarify,
> 
>  0x00000000 (no bit 29) would be windows
>  0x20000000 would be good for clib
>  0x20010000 would be good for apr
>  0x20020000... for apps (multiple, perhaps?)

There is no difference between this and what I had, other than that
you use the term "facility" and I didn't, and that I put them in a
higher-order range where they are less likely to collide with error
codes from other packages. 

> > UNIX is similar, though there is no requirement for bit 29 and no
> > separate OS error, since OS errors are errnos.  APR_STATUS_IS_OS()
> > would always return 0 (false).
> 
> True enough of APR_STATUS_IS_OS.  This should be a _simple_ case
> for illustration, start here.  Don't confuse everyone with the Win32
> implementation details yet.

I'm not going to start with a UNIX-only implementation first, commit
it, and then start worrying about Win32.  Win32 is the platform with
the biggest problem now.  (Maybe OS/2 and BeOS as well, but I don't really
know.)  If somebody wants to do an implementation that handles only
the simple case, go right ahead.  I was interested in an initial
implementation that handled UNIX and Win32, in the hopes that if it
handled those two then to add support for some other platform would
not require much reinvention.  Also, I personally have not been
frustrated with ap_status_t descriptions on UNIX (the current
strerror() code works most of the time) but I do on Win32 (most of the
time the error string is bogus).  Without a solution for my itch,
there is no reason for me to scratch.  Sorry!

> No... ap_strerror() is portable only in it's declaration.  It is _NOT_
> portable in it's implementation.

I have tried to explain in previous notes how much of it is portable.
Your use of upper case does not help me to come to agreement.
Explaining *why* a particular statement I am making is wrong does.
Start with the statements below and help me out.  

Only one small part of ap_strerror() is not portable: the mechanism
for retrieving the description of an OS-specific error.

Summary of portability:

  portable parts of the ap_strerror()

  . code to identify that error is errno
  . code to grab description for an errno
  . code to identify that error is APR error/status code
  . code to grab description for an APR error/status code
  . code to identify that error is OS-specific error code
  . code to handle other types of error codes

  non-portable parts of ap_strerror()

  . code to grab description for an OS-specific error code

Clearly, ap_strerror() is largely (85%?) portable.  It just needs a
service routine implemented for each platform to retrieve the
description for an OS-specific error code.

The implementations of the macros to manipulate ap_status_t are
definitely unique to each OS, but that is outside of the scope of
ap_strerror(). 

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

RE: ap_status_t for Win32

Posted by "William A. Rowe, Jr." <wr...@lnd.com>.
Just making sure I'm not misquoted...

> From: Jeff Trawick [mailto:trawickj@bellsouth.net]
> Sent: Wednesday, March 29, 2000 8:11 PM
>
> Paraphrase of text in the GetLastError() documentation:
>
>   GetLastError() returns 32-bit error codes with bit 29 off.
>   Application-defined error codes should turn bit 29 on.
>
> It seems that we don't need more than 32 bits for Windows...
> If we turn on bit 29 for non-OS-specific errors, we won't
> collide with any Windows errors.

True, for Windows.  Don't assume ANYTHING on other platforms.

> Other than Windows errors, the other types of errors we must support
> on Windows are:
>
> . errnos set by C run-time library
> . portable APR error codes like APR_ENOPOOL and status codes like
>   APR_EOF
> . error codes from other libraries such as those from libtool

PLUS - app specific error extensions (give them a pool of n numbers).

> For Windows, this implementation of Bill Rowe's desired
> classification/manipulation macros would seem to work:
>
> /* use bits 31-30 to indicate which type of non-Windows error it
>    is; bit 29 is on for any non-Windows errors */
>
> #define APR_ERRORTYPE_MASK  0xE0000000
>
> #define APR_ERRORTYPE_OS    0x00000000
> #define APR_ERRORTYPE_ERRNO 0x20000000
> #define APR_ERRORTYPE_APR   0xA0000000
> (room for two more types with this value of APR_ERRORTYPE_MASK; we can
> always steal more lower-order bits in the future)

I wouldn't mess with the top 2 bits - leave them alone (40, 80, C0).

If you like suggestions for win32... using the facility to clarify,

 0x00000000 (no bit 29) would be windows
 0x20000000 would be good for clib
 0x20010000 would be good for apr
 0x20020000... for apps (multiple, perhaps?)

But these are PRIVATE IMPLEMENTATION DETAILS.  We wouldn't assume they will
be bit flags or offsets across platforms.

> #define APR_STATUS_IS_OS(s) \
>         (((s) & APR_ERRORTYPE_MASK) == APR_ERRORTYPE_OS)
>
> #define APR_STATUS_IS_ERRNO(s) \
>         (((s)&APR_ERRORTYPE_MASK) == APR_ERRORTYPE_ERRNO)
>
> #define APR_STATUS_OF_ERRNO(e) \
>         ((e) APR_ERRORTYPE_ERRNO)
>
> #define APR_ERRNO_OF_STATUS(s) \
>         ((s) &~APR_ERRORTYPE_ERRNO)
>
> (similar gorp for other types of error values)

These are the sort of macros I would like to see across platforms!
With tests too, please, so I can ask if an ap_status_t is my own
app error... then I can ask the wrapper to hand me back my number.

Oh, the errors would be constant... i.e.

#define CLUELESS_USER_ERROR APR_APPERROR(1)

would be GUARENTEED ACROSS PLATFORMS to evaluate to the literal
value of ap_status_t (not == 1, but == APR_APPERROR(1), and
== CLUELESS_USER_ERROR).

The reason - it takes no brains for the compiler to calculate the
literal value to the constant dword, so no run-time math is involved.

That is not the same as testing

i = 1
[...]
if (retval == APR_APPERRNO(i))

where if i is obscured enough, the compiler can't optimize out the
run time calculations.  We want to _avoid_ this.

> UNIX is similar, though there is no requirement for bit 29 and no
> separate OS error, since OS errors are errnos.  APR_STATUS_IS_OS()
> would always return 0 (false).

True enough of APR_STATUS_IS_OS.  This should be a _simple_ case
for illustration, start here.  Don't confuse everyone with the Win32
implementation details yet.

> The implementation of ap_strerror() could be very similar to the one I
> posted this morning, but the test macros would be used instead of
> looking at the range of the value.  The routine to describe an OS
> error would be in an OS-specific file, but most of ap_strerror() is
> portable.  The bulk of it is in the service routines which describe
> the portable APR error/status codes.

No... ap_strerror() is portable only in it's declaration.  It is _NOT_
portable in it's implementation.

> --
> Jeff Trawick | trawick@ibm.net | PGP public key at web site:
>      http://www.geocities.com/SiliconValley/Park/9289/
>           Born in Roswell... married an alien...
>