| #include <errno.h> | |
| #include <string.h> | |
| #include <stdio.h> | |
| #include <ipxe/errortab.h> | |
| #include <config/branding.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_OR_UBDL ); | |
| FILE_SECBOOT ( PERMITTED ); | |
| /** | |
| * 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(). | |
| * | |
| */ | |
| 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 (" PRODUCT_ERROR_URI ")", | |
| errortab->text, errno ); | |
| } else { | |
| snprintf ( errbuf, sizeof ( errbuf ), | |
| "Error %#08x (" PRODUCT_ERROR_URI ")", | |
| 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 ), | |
| }; |