mirror of https://github.com/ipxe/ipxe.git
Handle structured error codes.
parent
18f9f939a8
commit
cde6d776e3
|
@ -24,9 +24,60 @@ static struct errortab errortab_end[0]
|
||||||
__table_end ( struct errortab, errortab );
|
__table_end ( struct errortab, errortab );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve string representation of error number.
|
* Find error description
|
||||||
*
|
*
|
||||||
* @v errno Error number
|
* @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
|
* @ret strerror Pointer to error text
|
||||||
*
|
*
|
||||||
* If the error is not found in the linked-in error tables, generates
|
* 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 ) {
|
const char * strerror ( int errno ) {
|
||||||
static char *generic_message = "Error 0x0000";
|
static char errbuf[64];
|
||||||
struct errortab *errortab;
|
struct errortab *errortab;
|
||||||
|
|
||||||
/* Allow for strerror(rc) as well as strerror(errno) */
|
/* Allow for strerror(rc) as well as strerror(errno) */
|
||||||
if ( errno < 0 )
|
if ( errno < 0 )
|
||||||
errno = -errno;
|
errno = -errno;
|
||||||
|
|
||||||
for ( errortab = errortab_start ; errortab < errortab_end ;
|
/* Find the error description, if one exists */
|
||||||
errortab++ ) {
|
errortab = find_closest_error ( errno );
|
||||||
if ( errortab->errno == errno )
|
|
||||||
return errortab->text;
|
/* 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 errbuf;
|
||||||
return generic_message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The most common errors */
|
/** The most common errors */
|
||||||
|
|
Loading…
Reference in New Issue