david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Handle structured error codes.

This commit is contained in:
Michael Brown 2007-01-19 13:52:50 +00:00
parent 18f9f939a8
commit cde6d776e3
1 changed files with 63 additions and 8 deletions

View File

@ -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 */