httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ryan Bloom <...@ntrnet.net>
Subject APR errno handling finished.
Date Wed, 05 Apr 2000 23:00:12 GMT

I have reworked and documented APR error handling so that it is portable.
I am posting a patch here that implements this, as well as an extra file
that will need to be flushed out to actually finish the work, but this
version of the file does get things started.

The docs are all in APRDesign in this patch.  This is the design I thought
we had agreed upon in the last few weeks.  It is basically Ben Laurie's
idea, as I understand it, written out as code and flushed out a tiny
little bit.

If nobody objects, I'll commit this tomorrow evening West Coast Time.  :-)

Ryan

Index: lib/apr/APRDesign
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/APRDesign,v
retrieving revision 1.7
diff -u -d -b -w -u -r1.7 APRDesign
--- lib/apr/APRDesign	2000/04/03 18:40:36	1.7
+++ lib/apr/APRDesign	2000/04/05 22:47:51
@@ -179,3 +179,160 @@
  */                                                                             
 
 For an actual example, look at any function in the fileio/unix directory.
+
+APR Error reporting
+
+Most APR functions should return an ap_status_t type.  The only time an
+APR function does not return an ap_status_t is if it absolutly CAN NOT
+fail.  Examples of this would be filling out an array when you know you are
+not beyond the array's range.  If it cannot fail on your platform, but it
+could conceivably fail on another platform, it should return an ap_status_t.
+Unless you are sure, return an ap_status_t.  :-)
+
+Each platform decides what their primary status values will be.  On Unix
+primary status values are errno values, on Win32 systems they are native
+Win32 errors.  Beyond standard error values, each platform can have as many
+supplamental error values as they need.  For example, on Unix, h_errno is a
+supplamental error value.
+
+There are six (well five, but we'll get to that) that all platforms have.
+
+    Name			Purpose
+1) 			This is 0 for all platforms and isn't really defined
+ 			anywhere, but it is the offset for the platform's
+			standard error value.
+2) APR_OS_START_ERRNO2	This is platform dependant, and is the offset to add
+			to supplamental error values to get a unique error
+			code.
+3) APR_OS_START_ERROR	This is platform dependant, and is the offset at which
+			APR errors start to be defined.
+4) APR_OS_START_STATUS	This is platform dependant, and is the offset at which
+			APR status values start.
+5) APR_OS_START_SYSERR	This is platform dependant, and is the offset at which
+			canonical error values start (canonical error values
+			are explained later)
+6) APR_OS_START_USEERR	This is platform dependany, and is the offset at which
+			APR apps can begin to add their own error codes.
+
+If a platform needs more offsets for more supplemental error codes, it is
+possible to define APR_OS_START_ERRNO# as well.  APR_SUCCESS is always defined
+as zero.
+
+All of these definitions can be found in apr_errno.h for all platforms.  When
+an error occurs in an APR function, the function must return an error code.
+If the error occured in a system call and that system uses the primary status
+values for that system, then the code is returned unchanged.  For example:
+
+    On Unix which uses errno as the primary status values in ap_open:
+        if (open(fname, oflags, 0777) < 0)
+            return errno;
+
+    On Windows which uses win32 native errors in ap_open:
+        if (CreateFile(fname, oflags, sharemod, NULL, 
+                       createflags, attributes,0) == INVALID_HANDLE_VALUE
+            return GetLAstError();
+
+Obviously even if the underlying problem is the same on both platforms, this
+will result in two different error codes being returned.  This is OKAY, and
+is correct for APR.  APR relies on the fact that most of the time an error
+occurs, the program logs the error and continues, it does not try to
+programatically solve the problem.  This does not mean we have not provided
+support for programmatically solving the problem, it just isn't the default
+case.  We'll get to how this problem is solved in a little while.
+
+The next place an error can occur is a system call that uses some error value
+other than the primary error value on a platform.  This can also be handled
+by APR applications.  For example:
+
+    On Unix which uses h_errno as a supplemental error value in ap_connect:
+        if (gethostbyname(hostname) == NULL)
+            return (h_errno + APR_OS_START_ERRNO2);
+
+If the error occurs in an APR function but it is not due to a system call,
+but it is actually an APR error or just a status code from APR, then the
+appropriate code should be returned.  These codes are defined in apr_errno.h
+and are self explanitory.
+
+No APR code should ever return a code higher than APR_OS_START_USEERR, those
+codes are reserved for APR applications.
+
+To programmatically correct an error in a running application, the error codes
+need to be consistent across platforms.  This should make sense.  To get
+consistent error codes, APR provides a function ap_canonicalize_error().
+This function will take as input any ap_status_t value, and return a small
+subset of canonical APR error codes.  These codes will be equivalent to
+Unix errno's.  Why is it a small subset?  Because we don't want to try to
+convert everything in the first pass.  As more programs require that more
+error codes are converted, they will be added to this function.  
+
+Why did APR take this approach?  There are two ways to deal with error 
+codes portably.
+
+1)  return the same error code across all platforms.  2)  return platform
+specific error codes and convert them when necessary.  
+
+The problem with option number one is that it takes time to convert error 
+codes to a common code, and most of the time programs want to just output 
+an error string.  If we convert all errors to a common subset, we have four 
+steps to output an error string:
+
+    make syscall that fails
+        convert to common error code                 step 1
+        return common error code
+            check for success
+            call error output function               step 2
+                convert back to system error         step 3
+                output error string                  step 4
+
+By keeping the errors platform specific, we can output error strings in two
+steps.
+
+    make syscall that fails
+        return error code
+            check for success
+            call error output function               step 1
+                output error string                  step 2
+
+Less often, programs change their execution based on what error was returned.
+This is no more expensive using option 2 and it is using option 1, but we
+put the onus of converting the error code on the programmer themselves.
+For example, using option 1:
+
+    make syscall that fails
+        convert to common error code
+        return common error code
+            decide execution basd on common error code
+
+Using option 2:
+    
+    make syscall that fails
+        return error code
+            convert to common error code (using ap_canonicalize_error)
+            decide execution based on common error code
+
+Finally, there is one more operation on error codes.  You can get a string
+that explains in human readable form what has happened.  To do this using 
+APR, call ap_strerror().
+
+On all platforms ap_strerror takes the form:
+
+char *ap_strerror(ap_status_t err)
+{
+    if (err < APR_OS_START_ERRNO2)
+        return (platform dependant error string generator)
+    if (err < APR_OS_START_ERROR)
+        return (platform dependant error string generator for
+                supplemental error values)
+    if (err < APR_OS_SYSERR)
+        return (APR generated error or status string)
+    if (err == 0)
+        return "No error was found"
+    else
+        return "APR doesn't understand this error value"
+}
+
+Notice, this does not handle canonicalized error values at all.  Those will 
+return "APR doesn't understand this error value" on any platform that does
+not use errno as it's primary error value.  To deal with this, just get the
+string before canonicalizing your error code.
+
Index: lib/apr/include/apr_errno.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_errno.h,v
retrieving revision 1.21
diff -u -d -b -w -u -r1.21 apr_errno.h
--- lib/apr/include/apr_errno.h	2000/04/05 12:28:23	1.21
+++ lib/apr/include/apr_errno.h	2000/04/05 22:47:52
@@ -62,29 +62,32 @@
 extern "C" {
 #endif /* __cplusplus */
 
-/* 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_ERRNO2 should be used for secondary error values on 
+ *     each platform.  For platforms that have multiple error types that
+ *     overlap, more of these can be defined (APR_OS_START_ERRNO3, etc).
+ *     For example, on Unix systems, h_errno uses the same value as errno,
+ *     so h_errno codes are h_errno + APR_OS_START_ERRNO2.
+ * APR_OS_START_ERROR is where the APR specific error values should start.
+ * APR_OS_START_STATUS is where the APR specific status codes should start.
+ * APR_OS_START_SYSERR is the where APR will start to define errno values
+ *     for platforms that do not support them.  This 
  * APR_OS_START_USEERR are reserved for applications that use APR that
  * layer their own error codes along with APR's.
  */
-#ifndef APR_OS_START_ERROR
+#if (WIN32)
+#else
+#define APR_OS_START_ERRNO2  3500
 #define APR_OS_START_ERROR   4000
-#endif
-#ifndef APR_OS_START_STATUS
 #define APR_OS_START_STATUS  (APR_OS_START_ERROR + 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 + 500)
 #endif
 
-/* If this definition of APRStatus changes, then we can remove this, but right
- * now, the decision was to use an errno-like implementation.
- */
 typedef int ap_status_t;
 
+int ap_canonical_error(ap_status_t err);
+char *ap_strerror(ap_status_t err);
+
 #define APR_SUCCESS 0
 
 /* APR ERROR VALUES */
@@ -144,9 +147,6 @@
  */
 #define APR_EMISMATCH      (APR_OS_START_STATUS + 18)
 
-/*
- * APR equivalents to what should be standard errno codes.
- */
 #ifdef EACCES
 #define APR_EACCES EACCES
 #else
@@ -159,295 +159,94 @@
 #define APR_EEXIST (APR_OS_START_SYSERR + 1)
 #endif
 
-#ifdef EISDIR
-#define APR_EISDIR EISDIR
-#else
-#define APR_EISDIR (APR_OS_START_SYSERR + 2)
-#endif
-
 #ifdef ENAMETOOLONG
 #define APR_ENAMETOOLONG ENAMETOOLONG
 #else
-#define APR_ENAMETOOLONG (APR_OS_START_SYSERR + 3)
+#define APR_ENAMETOOLONG (APR_OS_START_SYSERR + 2)
 #endif
 
 #ifdef ENOENT
 #define APR_ENOENT ENOENT
 #else
-#define APR_ENOENT (APR_OS_START_SYSERR + 4)
+#define APR_ENOENT (APR_OS_START_SYSERR + 3)
 #endif
 
 #ifdef ENOTDIR
 #define APR_ENOTDIR ENOTDIR
 #else
-#define APR_ENOTDIR (APR_OS_START_SYSERR + 5)
-#endif
-
-#ifdef ENXIO
-#define APR_ENXIO ENXIO
-#else
-#define APR_ENXIO (APR_OS_START_SYSERR + 6)
-#endif
-
-#ifdef ENODEV
-#define APR_ENODEV ENODEV
-#else
-#define APR_ENODEV (APR_OS_START_SYSERR + 7)
-#endif
-
-#ifdef EROFS
-#define APR_EROFS EROFS
-#else
-#define APR_EROFS (APR_OS_START_SYSERR + 8)
-#endif
-
-#ifdef ETXTBSY
-#define APR_ETXTBSY ETXTBSY
-#else
-#define APR_ETXTBSY (APR_OS_START_SYSERR + 9)
-#endif
-
-#ifdef EFAULT
-#define APR_EFAULT EFAULT
-#else
-#define APR_EFAULT (APR_OS_START_SYSERR + 10)
-#endif
-
-#ifdef ELOOP
-#define APR_ELOOP ELOOP
-#else
-#define APR_ELOOP (APR_OS_START_SYSERR + 11)
+#define APR_ENOTDIR (APR_OS_START_SYSERR + 4)
 #endif
 
 #ifdef ENOSPC
 #define APR_ENOSPC ENOSPC
 #else
-#define APR_ENOSPC (APR_OS_START_SYSERR + 12)
+#define APR_ENOSPC (APR_OS_START_SYSERR + 5)
 #endif
 
 #ifdef ENONOMEM
 #define APR_ENOMEM ENOMEM
 #else
-#define APR_ENOMEM (APR_OS_START_SYSERR + 13)
+#define APR_ENOMEM (APR_OS_START_SYSERR + 6)
 #endif
 
 #ifdef EMFILE
 #define APR_EMFILE EMFILE
 #else
-#define APR_EMFILE (APR_OS_START_SYSERR + 14)
+#define APR_EMFILE (APR_OS_START_SYSERR + 7)
 #endif
 
 #ifdef ENFILE
 #define APR_ENFILE ENFILE
 #else
-#define APR_ENFILE (APR_OS_START_SYSERR + 15)
+#define APR_ENFILE (APR_OS_START_SYSERR + 8)
 #endif
 
 #ifdef EBADF
 #define APR_EBADF EBADF
-#else
-#define APR_EBADF (APR_OS_START_SYSERR + 16)
-#endif
-
-#ifdef EPERM
-#define APR_EPERM EPERM
-#else
-#define APR_EPERM (APR_OS_START_SYSERR + 17)
-#endif
-
-#ifdef EIO
-#define APR_EIO EIO
 #else
-#define APR_EIO (APR_OS_START_SYSERR + 18)
+#define APR_EBADF (APR_OS_START_SYSERR + 9)
 #endif
 
 #ifdef EINVAL
 #define APR_EINVAL EINVAL
-#else
-#define APR_EINVAL (APR_OS_START_SYSERR + 19)
-#endif
-
-#ifdef ENOEMPTY
-#define APR_ENOEMPTY ENOEMPTY
-#else
-#define APR_ENOEMPTY (APR_OS_START_SYSERR + 20)
-#endif
-
-#ifdef EBUSY
-#define APR_EBUSY EBUSY
 #else
-#define APR_EBUSY (APR_OS_START_SYSERR + 21)
+#define APR_EINVAL (APR_OS_START_SYSERR + 10)
 #endif
 
 #ifdef ESPIPE
 #define APR_ESPIPE ESPIPE
-#else
-#define APR_ESPIPE (APR_OS_START_SYSERR + 22)
-#endif
-
-#ifdef EIDRM
-#define APR_EIDRM EIDRM
-#else
-#define APR_EIDRM (APR_OS_START_SYSERR + 23)
-#endif
-
-#ifdef ERANGE
-#define APR_ERANGE ERANGE
 #else
-#define APR_ERANGE (APR_OS_START_SYSERR + 24)
-#endif
-
-#ifdef E2BIG
-#define APR_E2BIG E2BIG
-#else
-#define APR_E2BIG (APR_OS_START_SYSERR + 25)
+#define APR_ESPIPE (APR_OS_START_SYSERR + 11)
 #endif
 
 #ifdef EAGAIN
 #define APR_EAGAIN EAGAIN
-#else
-#define APR_EAGAIN (APR_OS_START_SYSERR + 26)
-#endif
-
-#ifdef EFBIG
-#define APR_EFBIG EFBIG
 #else
-#define APR_EFBIG (APR_OS_START_SYSERR + 27)
+#define APR_EAGAIN (APR_OS_START_SYSERR + 12)
 #endif
 
 #ifdef EINTR
 #define APR_EINTR EINTR
-#else
-#define APR_EINTR (APR_OS_START_SYSERR + 28)
-#endif
-
-#ifdef EDEADLK
-#define APR_EDEADLK EDEADLK
 #else
-#define APR_EDEADLK (APR_OS_START_SYSERR + 29)
-#endif
-
-#ifdef ENOLCK
-#define APR_ENOLCK ENOLCK
-#else
-#define APR_ENOLCK (APR_OS_START_SYSERR + 30)
-#endif
-
-#ifdef EWOULDBLOCK
-#define APR_EWOULDBLOCK EWOULDBLOCK
-#else
-#define APR_EWOULDBLOCK (APR_OS_START_SYSERR + 31)
-#endif
-
-#ifdef EPROTONOSUPPORT
-#define APR_EPROTONOSUPPORT EPROTONOSUPPORT
-#else
-#define APR_EPROTONOSUPPORT (APR_OS_START_SYSERR + 32)
+#define APR_EINTR (APR_OS_START_SYSERR + 13)
 #endif
 
 #ifdef ENOTSOCK
 #define APR_ENOTSOCK ENOTSOCK
-#else
-#define APR_ENOTSOCK (APR_OS_START_SYSERR + 33)
-#endif
-
-#ifdef ENOTCONN
-#define APR_ENOTCONN ENOTCONN
-#else
-#define APR_ENOTCONN (APR_OS_START_SYSERR + 34)
-#endif
-
-#ifdef EOPNOTSUPP
-#define APR_EOPNOTSUPP EOPNOTSUPP
-#else
-#define APR_EOPNOTSUPP (APR_OS_START_SYSERR + 35)
-#endif
-
-/* never use h_errno values as-is because doing so makes them 
- * indistinguishable 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_OS_START_SYSERR + 36)
-
-#define APR_ENODATA (APR_OS_START_SYSERR + 37)
-
-#define APR_ENOADDRESS (APR_OS_START_SYSERR + 38)
-
-#define APR_ENORECOVERY (APR_OS_START_SYSERR + 39)
-
-#ifdef EISCONN
-#define APR_EISCONN EISCONN
 #else
-#define APR_EISCONN (APR_OS_START_SYSERR + 40)
-#endif
-
-#ifdef ETIMEDOUT
-#define APR_ETIMEDOUT ETIMEDOUT
-#else
-#define APR_ETIMEDOUT (APR_OS_START_SYSERR + 41)
+#define APR_ENOTSOCK (APR_OS_START_SYSERR + 14)
 #endif
 
 #ifdef ECONNREFUSED
 #define APR_ECONNREFUSED ECONNREFUSED
 #else
-#define APR_ECONNREFUSED (APR_OS_START_SYSERR + 42)
-#endif
-
-#ifdef ENETUNREACH
-#define APR_ENETUNREACH ENETUNREACH
-#else
-#define APR_ENETUNREACH (APR_OS_START_SYSERR + 43)
-#endif
-
-#ifdef EADDRINUSE
-#define APR_EADDRINUSE EADDRINUSE
-#else
-#define APR_EADDRINUSE (APR_OS_START_SYSERR + 44)
+#define APR_ECONNREFUSED (APR_OS_START_SYSERR + 15)
 #endif
 
 #ifdef EINPROGRESS
 #define APR_EINPROGRESS EINPROGRESS
-#else
-#define APR_EINPROGRESS (APR_OS_START_SYSERR + 45)
-#endif
-
-#ifdef EALREADY
-#define APR_EALREADY EALREADY
 #else
-#define APR_EALREADY (APR_OS_START_SYSERR + 46)
-#endif
-
-#ifdef EAFNOSUPPORT
-#define APR_EAFNOSUPPORT EAFNOSUPPORT
-#else
-#define APR_EAFNOSUPPORT (APR_OS_START_SYSERR + 47)
-#endif
-
-#ifdef ENOPROTOOPT
-#define APR_ENOPROTOOPT ENOPROTOOPT
-#else
-#define APR_ENOPROTOOPT (APR_OS_START_SYSERR + 48)
-#endif
-
-#ifdef ENOCHILD
-#define APR_ENOCHILD ENOCHILD
-#else
-#define APR_ENOCHILD (APR_OS_START_SYSERR + 49)
-#endif
-
-#ifdef ESRCH
-#define APR_ESRCH ESRCH
-#else
-#define APR_ESRCH (APR_OS_START_SYSERR + 50)
-#endif
-
-#ifdef ENOTSUP
-#define APR_ENOTSUP ENOTSUP
-#else
-#define APR_ENOTSUP (APR_OS_START_SYSERR + 51)
+#define APR_EINPROGRESS (APR_OS_START_SYSERR + 16)
 #endif
 
 #ifdef __cplusplus
Index: lib/apr/misc/unix/Makefile.in
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/misc/unix/Makefile.in,v
retrieving revision 1.10
diff -u -d -b -w -u -r1.10 Makefile.in
--- lib/apr/misc/unix/Makefile.in	2000/04/04 17:58:47	1.10
+++ lib/apr/misc/unix/Makefile.in	2000/04/05 22:47:53
@@ -15,7 +15,7 @@
 
 #LIB=libmisc.a
 
-OBJS=start.o getopt.o otherchild.o 
+OBJS=start.o getopt.o otherchild.o9 error.c 
 
 .c.o:
 	$(CC) $(CFLAGS) -c $(INCLUDES) $<
Index: lib/apr/network_io/unix/networkio.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/networkio.h,v
retrieving revision 1.19
diff -u -d -b -w -u -r1.19 networkio.h
--- lib/apr/network_io/unix/networkio.h	2000/04/03 18:37:35	1.19
+++ lib/apr/network_io/unix/networkio.h	2000/04/05 22:47:54
@@ -57,6 +57,7 @@
 
 #include "apr_config.h"
 #include "apr_network_io.h"
+#include "apr_errno.h"
 #include "apr_general.h"
 #include "apr_lib.h"
 
@@ -135,8 +136,6 @@
 
 ap_int16_t get_event(ap_int16_t);
 ap_int16_t get_revent(ap_int16_t);
-
-ap_status_t status_from_res_error(int);
 
 #endif  /* ! NETWORK_IO_H */
 
Index: lib/apr/network_io/unix/sockets.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sockets.c,v
retrieving revision 1.35
diff -u -d -b -w -u -r1.35 sockets.c
--- lib/apr/network_io/unix/sockets.c	2000/04/04 11:44:27	1.35
+++ lib/apr/network_io/unix/sockets.c	2000/04/05 22:47:54
@@ -232,7 +232,7 @@
             return APR_ENOTSOCK;
         }
         if (!hp)  {
-            return status_from_res_error(h_errno);
+            return (h_errno + APR_OS_START_ERRNO2);
         }
     
         memcpy((char *)&sock->remote_addr->sin_addr, hp->h_addr_list[0], hp->h_length);
Index: lib/apr/network_io/unix/sockopt.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sockopt.c,v
retrieving revision 1.20
diff -u -d -b -w -u -r1.20 sockopt.c
--- lib/apr/network_io/unix/sockopt.c	2000/04/03 19:45:11	1.20
+++ lib/apr/network_io/unix/sockopt.c	2000/04/05 22:47:54
@@ -208,33 +208,6 @@
     }
 
     /* XXX - Is referencing h_errno threadsafe? */
-    return status_from_res_error(h_errno);
-}
-
-ap_status_t status_from_res_error(int herr)
-{
-    ap_status_t status;
-    switch(herr) {
-    case HOST_NOT_FOUND:
-        status = APR_EHOSTNOTFOUND;
-        break;
-    case TRY_AGAIN:
-        status = APR_EAGAIN;
-        break;
-    case NO_RECOVERY:
-        status = APR_ENORECOVERY;
-        break;
-    case NO_ADDRESS:
-        status = APR_ENOADDRESS;
-        break;
-#if defined(NO_DATA) && (NO_ADDRESS != NO_DATA)
-    case NO_DATA:
-#endif
-        status = APR_ENODATA;
-        break;
-    default:
-        status = APR_ENORECOVERY;
-    }
-    return status;
+    return (h_errno + APR_OS_START_ERRNO2);
 }
 
apr/misc/unix/error.c
--------------------
/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "misc.h"

/* ***APRDOC********************************************************
 * int ap_canonical_error(ap_status_t err)
 *    Convert an ap_status_t to a small canonical error so that
 *    execution decisions can be made based on what the error is.
 * arg 1) An ap_status_t value returned from some APR function.
 * NOTE:  The set of canonical error values is a very small subset
 *        of possible error values.  This subset will grow with time
 *        as the errors are needed.
 */
int ap_canonical_error(ap_status_t err)
{
/* The current list of possible return codes for this function.  These
 * are the errors that effect execution (other than error strings)
 * at run time.
 */
/*
    APR_EACCES 
    APR_EEXIST 
    APR_ENAMETOOLONG 
    APR_ENOENT 
    APR_ENOTDIR 
    APR_ENOSPC 
    APR_ENOMEM
    APR_EMFILE 
    APR_ENFILE 
    APR_EBADF 
    APR_EINVAL 
    APR_ESPIPE 
    APR_EAGAIN 
    APR_EINTR 
    APR_ENOTSOCK
    APR_EINPROGRESS
*/
    /* On unix, these errors are alread canonicalized. */
    return err;
}

const char *ap_strerror(ap_status_t err)
{
    if (err < APR_OS_START_ERRNO2) {
        /* err is an errno value */
        return strerr(err);
    }
    if (err < APR_OS_START_ERROR) {
        /* err is an h_errno value */
        return hstrerror(err - APR_OS_START_ERRNO2);
    }
    if (err < APR_OS_START_SYSERR) {
        /* err is an apr error or an apr status code */
        /* we may want to use gettext here */
        switch (err) {
            APR_ENOSTAT:
                return "Could not stat file\n";
            APR_ENOPOOL:
                return "No pool variable was provided\n";
        }
    }
    if (err == APR_SUCCESS)
        return "No error found\n"
    else
        return "APR does not understand this error\n";
}

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


Mime
View raw message