You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Brian Havard <br...@kheldar.apana.org.au> on 2000/04/01 08:37:58 UTC

Re: ap_status_t for Win32

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 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
-------------------------------------------------------------------------------