diff options
Diffstat (limited to 'roms/ipxe/src/hci/strerror.c')
-rw-r--r-- | roms/ipxe/src/hci/strerror.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/roms/ipxe/src/hci/strerror.c b/roms/ipxe/src/hci/strerror.c new file mode 100644 index 00000000..9356e9e0 --- /dev/null +++ b/roms/ipxe/src/hci/strerror.c @@ -0,0 +1,125 @@ +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <ipxe/errortab.h> + +/** @file + * + * Error descriptions. + * + * The error numbers used by Etherboot are a superset of those defined + * by the PXE specification version 2.1. See errno.h for a listing of + * the error values. + * + * To save space in ROM images, error string tables are optional. Use + * the ERRORMSG_XXX options in config.h to select which error string + * tables you want to include. If an error string table is omitted, + * strerror() will simply return the text "Error 0x<errno>". + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** + * Find error description + * + * @v errno Error number + * @ret errortab Error description, or NULL + */ +static struct errortab * find_error ( int errno ) { + struct errortab *errortab; + + for_each_table_entry ( errortab, ERRORTAB ) { + if ( errortab->errno == errno ) + 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 ) ) != NULL ) + return errortab; + + /* Second, try masking off the iPXE-specific bit and seeing if + * we have an entry for the generic POSIX error message. + */ + if ( ( errortab = find_error ( errno & 0x7f0000ff ) ) != 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 + * a generic "Error 0x<errno>" message. + * + * The pointer returned by strerror() is valid only until the next + * call to strerror(). + * + */ +const char * strerror ( int errno ) { + static char errbuf[64]; + struct errortab *errortab; + + /* Allow for strerror(rc) as well as strerror(errno) */ + if ( errno < 0 ) + errno = -errno; + + /* Find the error description, if one exists */ + errortab = find_closest_error ( errno ); + + /* Construct the error message */ + if ( errortab ) { + snprintf ( errbuf, sizeof ( errbuf ), + "%s (http://ipxe.org/%08x)", + errortab->text, errno ); + } else { + snprintf ( errbuf, sizeof ( errbuf ), + "Error %#08x (http://ipxe.org/%08x)", + errno, errno ); + } + + return errbuf; +} + +/* Do not include ERRFILE portion in the numbers in the error table */ +#undef ERRFILE +#define ERRFILE 0 + +/** The most common errors */ +struct errortab common_errors[] __errortab = { + __einfo_errortab ( EINFO_ENOERR ), + __einfo_errortab ( EINFO_EACCES ), + __einfo_errortab ( EINFO_ECANCELED ), + __einfo_errortab ( EINFO_ECONNRESET ), + __einfo_errortab ( EINFO_EINVAL ), + __einfo_errortab ( EINFO_EIO ), + __einfo_errortab ( EINFO_ENETUNREACH ), + __einfo_errortab ( EINFO_ENODEV ), + __einfo_errortab ( EINFO_ENOENT ), + __einfo_errortab ( EINFO_ENOEXEC ), + __einfo_errortab ( EINFO_ENOMEM ), + __einfo_errortab ( EINFO_ENOSPC ), + __einfo_errortab ( EINFO_ENOTCONN ), + __einfo_errortab ( EINFO_ENOTSUP ), + __einfo_errortab ( EINFO_EPERM ), + __einfo_errortab ( EINFO_ERANGE ), + __einfo_errortab ( EINFO_ETIMEDOUT ), +}; |