1 #include <errno.h> 2 #include <string.h> 3 #include <stdio.h> 4 #include <gpxe/errortab.h> 5 6 /** @file 7 * 8 * Error descriptions. 9 * 10 * The error numbers used by Etherboot are a superset of those defined 11 * by the PXE specification version 2.1. See errno.h for a listing of 12 * the error values. 13 * 14 * To save space in ROM images, error string tables are optional. Use 15 * the ERRORMSG_XXX options in config.h to select which error string 16 * tables you want to include. If an error string table is omitted, 17 * strerror() will simply return the text "Error 0x<errno>". 18 * 19 */ 20 21 FILE_LICENCE ( GPL2_OR_LATER ); 22 23 /** 24 * Find error description 25 * 26 * @v errno Error number 27 * @ret errortab Error description, or NULL 28 */ 29 static struct errortab * find_error ( int errno ) { 30 struct errortab *errortab; 31 32 for_each_table_entry ( errortab, ERRORTAB ) { 33 if ( errortab->errno == errno ) 34 return errortab; 35 } 36 37 return NULL; 38 } 39 40 /** 41 * Find closest error description 42 * 43 * @v errno Error number 44 * @ret errortab Error description, or NULL 45 * 46 * 47 */ 48 static struct errortab * find_closest_error ( int errno ) { 49 struct errortab *errortab; 50 51 /* First, look for an exact match */ 52 if ( ( errortab = find_error ( errno ) ) != NULL ) 53 return errortab; 54 55 /* Second, try masking off the gPXE-specific bit and seeing if 56 * we have an entry for the generic POSIX error message. 57 */ 58 if ( ( errortab = find_error ( errno & 0x7f0000ff ) ) != NULL ) 59 return errortab; 60 61 return NULL; 62 } 63 64 /** 65 * Retrieve string representation of error number. 66 * 67 * @v errno/rc Error number or return status code 68 * @ret strerror Pointer to error text 69 * 70 * If the error is not found in the linked-in error tables, generates 71 * a generic "Error 0x<errno>" message. 72 * 73 * The pointer returned by strerror() is valid only until the next 74 * call to strerror(). 75 * 76 */ 77 const char * strerror ( int errno ) { 78 static char errbuf[64]; 79 struct errortab *errortab; 80 81 /* Allow for strerror(rc) as well as strerror(errno) */ 82 if ( errno < 0 ) 83 errno = -errno; 84 85 /* Find the error description, if one exists */ 86 errortab = find_closest_error ( errno ); 87 88 /* Construct the error message */ 89 if ( errortab ) { 90 snprintf ( errbuf, sizeof ( errbuf ), "%s (%#08x)", 91 errortab->text, errno ); 92 } else { 93 snprintf ( errbuf, sizeof ( errbuf ), "Error %#08x", errno ); 94 } 95 96 return errbuf; 97 } 98 99 /* Do not include ERRFILE portion in the numbers in the error table */ 100 #undef ERRFILE 101 #define ERRFILE 0 102 103 /** The most common errors */ 104 struct errortab common_errors[] __errortab = { 105 { 0, "No error" }, 106 { EACCES, "Permission denied" }, 107 { ECANCELED, "Operation cancelled" }, 108 { ECONNRESET, "Connection reset" }, 109 { EINVAL, "Invalid argument" }, 110 { EIO, "Input/output error" }, 111 { ENETUNREACH, "Network unreachable" }, 112 { ENODEV, "No such device" }, 113 { ENOENT, "File not found" }, 114 { ENOEXEC, "Not an executable image" }, 115 { ENOMEM, "Out of memory" }, 116 { ENOSPC, "No space left on device" }, 117 { ENOTCONN, "Not connected" }, 118 { ENOTSUP, "Not supported" }, 119 { EPERM, "Operation not permitted" }, 120 { ERANGE, "Out of range" }, 121 { ETIMEDOUT, "Connection timed out" }, 122 }; 123