iPXE
strerror.c
Go to the documentation of this file.
00001 #include <errno.h>
00002 #include <string.h>
00003 #include <stdio.h>
00004 #include <ipxe/errortab.h>
00005 #include <config/branding.h>
00006 
00007 /** @file
00008  *
00009  * Error descriptions.
00010  *
00011  * The error numbers used by Etherboot are a superset of those defined
00012  * by the PXE specification version 2.1.  See errno.h for a listing of
00013  * the error values.
00014  *
00015  * To save space in ROM images, error string tables are optional.  Use
00016  * the ERRORMSG_XXX options in config.h to select which error string
00017  * tables you want to include.  If an error string table is omitted,
00018  * strerror() will simply return the text "Error 0x<errno>".
00019  *
00020  */
00021 
00022 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00023 
00024 /**
00025  * Find error description
00026  *
00027  * @v errno             Error number
00028  * @ret errortab        Error description, or NULL
00029  */
00030 static struct errortab * find_error ( int errno ) {
00031         struct errortab *errortab;
00032 
00033         for_each_table_entry ( errortab, ERRORTAB ) {
00034                 if ( errortab->errno == errno )
00035                         return errortab;
00036         }
00037 
00038         return NULL;
00039 }
00040 
00041 /**
00042  * Find closest error description
00043  *
00044  * @v errno             Error number
00045  * @ret errortab        Error description, or NULL
00046  *
00047  * 
00048  */
00049 static struct errortab * find_closest_error ( int errno ) {
00050         struct errortab *errortab;
00051 
00052         /* First, look for an exact match */
00053         if ( ( errortab = find_error ( errno ) ) != NULL )
00054                 return errortab;
00055 
00056         /* Second, try masking off the iPXE-specific bit and seeing if
00057          * we have an entry for the generic POSIX error message.
00058          */
00059         if ( ( errortab = find_error ( errno & 0x7f0000ff ) ) != NULL )
00060                 return errortab;
00061 
00062         return NULL;
00063 }
00064 
00065 /**
00066  * Retrieve string representation of error number.
00067  *
00068  * @v errno/rc          Error number or return status code
00069  * @ret strerror        Pointer to error text
00070  *
00071  * If the error is not found in the linked-in error tables, generates
00072  * a generic "Error 0x<errno>" message.
00073  *
00074  * The pointer returned by strerror() is valid only until the next
00075  * call to strerror().
00076  *
00077  */
00078 char * strerror ( int errno ) {
00079         static char errbuf[64];
00080         struct errortab *errortab;
00081 
00082         /* Allow for strerror(rc) as well as strerror(errno) */
00083         if ( errno < 0 )
00084                 errno = -errno;
00085 
00086         /* Find the error description, if one exists */
00087         errortab = find_closest_error ( errno );
00088 
00089         /* Construct the error message */
00090         if ( errortab ) {
00091                 snprintf ( errbuf, sizeof ( errbuf ),
00092                            "%s (" PRODUCT_ERROR_URI ")",
00093                            errortab->text, errno );
00094         } else {
00095                 snprintf ( errbuf, sizeof ( errbuf ),
00096                            "Error %#08x (" PRODUCT_ERROR_URI ")",
00097                            errno, errno );
00098         }
00099 
00100         return errbuf;
00101 }
00102 
00103 /* Do not include ERRFILE portion in the numbers in the error table */
00104 #undef ERRFILE
00105 #define ERRFILE 0
00106 
00107 /** The most common errors */
00108 struct errortab common_errors[] __errortab = {
00109         __einfo_errortab ( EINFO_ENOERR ),
00110         __einfo_errortab ( EINFO_EACCES ),
00111         __einfo_errortab ( EINFO_ECANCELED ),
00112         __einfo_errortab ( EINFO_ECONNRESET ),
00113         __einfo_errortab ( EINFO_EINVAL ),
00114         __einfo_errortab ( EINFO_EIO ),
00115         __einfo_errortab ( EINFO_ENETUNREACH ),
00116         __einfo_errortab ( EINFO_ENODEV ),
00117         __einfo_errortab ( EINFO_ENOENT ),
00118         __einfo_errortab ( EINFO_ENOEXEC ),
00119         __einfo_errortab ( EINFO_ENOMEM ),
00120         __einfo_errortab ( EINFO_ENOSPC ),
00121         __einfo_errortab ( EINFO_ENOTCONN ),
00122         __einfo_errortab ( EINFO_ENOTSUP ),
00123         __einfo_errortab ( EINFO_EPERM ),
00124         __einfo_errortab ( EINFO_ERANGE ),
00125         __einfo_errortab ( EINFO_ETIMEDOUT ),
00126 };