summaryrefslogtreecommitdiffstats
path: root/src/hci/strerror.c
diff options
context:
space:
mode:
authorMichael Brown2007-01-19 14:52:50 +0100
committerMichael Brown2007-01-19 14:52:50 +0100
commitcde6d776e30c097e851a0944b151cf1c3868e3b0 (patch)
treebb3bb732cdfcf62eba55d5f5659322d08b544c50 /src/hci/strerror.c
parentIntroduce structured error codes. (diff)
downloadipxe-cde6d776e30c097e851a0944b151cf1c3868e3b0.tar.gz
ipxe-cde6d776e30c097e851a0944b151cf1c3868e3b0.tar.xz
ipxe-cde6d776e30c097e851a0944b151cf1c3868e3b0.zip
Handle structured error codes.
Diffstat (limited to 'src/hci/strerror.c')
-rw-r--r--src/hci/strerror.c71
1 files changed, 63 insertions, 8 deletions
diff --git a/src/hci/strerror.c b/src/hci/strerror.c
index 56b07e8a..045e6357 100644
--- a/src/hci/strerror.c
+++ b/src/hci/strerror.c
@@ -24,9 +24,60 @@ static struct errortab errortab_end[0]
__table_end ( struct errortab, errortab );
/**
- * Retrieve string representation of error number.
+ * Find error description
+ *
+ * @v errno Error number
+ * @v mask Mask of bits that we care about
+ * @ret errortab Error description, or NULL
+ */
+static struct errortab * find_error ( int errno, int mask ) {
+ struct errortab *errortab;
+
+ for ( errortab = errortab_start ; errortab < errortab_end ;
+ errortab++ ) {
+ if ( ( ( errortab->errno ^ errno ) & mask ) == 0 )
+ return errortab;
+ }
+
+ return NULL;
+}
+
+/**
+ * Find closest error description
*
* @v errno Error number
+ * @ret errortab Error description, or NULL
+ *
+ *
+ */
+static struct errortab * find_closest_error ( int errno ) {
+ struct errortab *errortab;
+
+ /* First, look for an exact match */
+ if ( ( errortab = find_error ( errno, 0x7fffffff ) ) != NULL )
+ return errortab;
+
+ /* Second, try masking off the gPXE-specific bit and seeing if
+ * we have an entry for the generic POSIX error message.
+ */
+ if ( ( errortab = find_error ( errno, 0x0000ffff ) ) != NULL )
+ return errortab;
+
+ /* Lastly, try masking off the POSIX bits and seeing if we
+ * have a match just based on the PXENV component. This
+ * allows us to report errors from underlying PXE stacks.
+ */
+ if ( ( errortab = find_error ( ( errno & 0x000000ff ),
+ 0xffff00ff ) ) != NULL )
+ return errortab;
+
+ return NULL;
+}
+
+/**
+ * Retrieve string representation of error number.
+ *
+ * @v errno/rc Error number or return status code
* @ret strerror Pointer to error text
*
* If the error is not found in the linked-in error tables, generates
@@ -37,21 +88,25 @@ static struct errortab errortab_end[0]
*
*/
const char * strerror ( int errno ) {
- static char *generic_message = "Error 0x0000";
+ static char errbuf[64];
struct errortab *errortab;
/* Allow for strerror(rc) as well as strerror(errno) */
if ( errno < 0 )
errno = -errno;
- for ( errortab = errortab_start ; errortab < errortab_end ;
- errortab++ ) {
- if ( errortab->errno == errno )
- return errortab->text;
+ /* Find the error description, if one exists */
+ errortab = find_closest_error ( errno );
+
+ /* Construct the error message */
+ if ( errortab ) {
+ snprintf ( errbuf, sizeof ( errbuf ), "%s (%#08x)",
+ errortab->text, errno );
+ } else {
+ snprintf ( errbuf, sizeof ( errbuf ), "Error %#08x", errno );
}
- sprintf ( generic_message + 8, "%hx", errno );
- return generic_message;
+ return errbuf;
}
/** The most common errors */