Home | History | Annotate | Download | only in errors
      1 // Copyright 2014 The Chromium OS Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <brillo/errors/error_codes.h>
      6 
      7 #include <base/posix/safe_strerror.h>
      8 
      9 namespace brillo {
     10 namespace errors {
     11 
     12 namespace dbus {
     13 const char kDomain[] = "dbus";
     14 }  // namespace dbus
     15 
     16 namespace json {
     17 const char kDomain[] = "json_parser";
     18 const char kParseError[] = "json_parse_error";
     19 const char kObjectExpected[] = "json_object_expected";
     20 }  // namespace json
     21 
     22 namespace http {
     23 const char kDomain[] = "http";
     24 }  // namespace http
     25 
     26 namespace system {
     27 const char kDomain[] = "system";
     28 
     29 namespace {
     30 const struct ErrorMapEntry {
     31   const char* error_code;
     32   int errnum;
     33 } error_map[] = {
     34 #define ERROR_ENTRY(err) { #err, err }
     35   ERROR_ENTRY(EPERM),            // Operation not permitted
     36   ERROR_ENTRY(ENOENT),           // No such file or directory
     37   ERROR_ENTRY(ESRCH),            // No such process
     38   ERROR_ENTRY(EINTR),            // Interrupted system call
     39   ERROR_ENTRY(EIO),              // I/O error
     40   ERROR_ENTRY(ENXIO),            // No such device or address
     41   ERROR_ENTRY(E2BIG),            // Argument list too long
     42   ERROR_ENTRY(ENOEXEC),          // Exec format error
     43   ERROR_ENTRY(EBADF),            // Bad file number
     44   ERROR_ENTRY(ECHILD),           // No child processes
     45   ERROR_ENTRY(EAGAIN),           // Try again
     46   ERROR_ENTRY(ENOMEM),           // Out of memory
     47   ERROR_ENTRY(EACCES),           // Permission denied
     48   ERROR_ENTRY(EFAULT),           // Bad address
     49   ERROR_ENTRY(ENOTBLK),          // Block device required
     50   ERROR_ENTRY(EBUSY),            // Device or resource busy
     51   ERROR_ENTRY(EEXIST),           // File exists
     52   ERROR_ENTRY(EXDEV),            // Cross-device link
     53   ERROR_ENTRY(ENODEV),           // No such device
     54   ERROR_ENTRY(ENOTDIR),          // Not a directory
     55   ERROR_ENTRY(EISDIR),           // Is a directory
     56   ERROR_ENTRY(EINVAL),           // Invalid argument
     57   ERROR_ENTRY(ENFILE),           // File table overflow
     58   ERROR_ENTRY(EMFILE),           // Too many open files
     59   ERROR_ENTRY(ENOTTY),           // Not a typewriter
     60   ERROR_ENTRY(ETXTBSY),          // Text file busy
     61   ERROR_ENTRY(EFBIG),            // File too large
     62   ERROR_ENTRY(ENOSPC),           // No space left on device
     63   ERROR_ENTRY(ESPIPE),           // Illegal seek
     64   ERROR_ENTRY(EROFS),            // Read-only file system
     65   ERROR_ENTRY(EMLINK),           // Too many links
     66   ERROR_ENTRY(EPIPE),            // Broken pipe
     67   ERROR_ENTRY(EDOM),             // Math argument out of domain of func
     68   ERROR_ENTRY(ERANGE),           // Math result not representable
     69   ERROR_ENTRY(EDEADLK),          // Resource deadlock would occur
     70   ERROR_ENTRY(ENAMETOOLONG),     // File name too long
     71   ERROR_ENTRY(ENOLCK),           // No record locks available
     72   ERROR_ENTRY(ENOSYS),           // Function not implemented
     73   ERROR_ENTRY(ENOTEMPTY),        // Directory not empty
     74   ERROR_ENTRY(ELOOP),            // Too many symbolic links encountered
     75   ERROR_ENTRY(ENOMSG),           // No message of desired type
     76   ERROR_ENTRY(EIDRM),            // Identifier removed
     77 #ifdef __linux__
     78   ERROR_ENTRY(ECHRNG),           // Channel number out of range
     79   ERROR_ENTRY(EL2NSYNC),         // Level 2 not synchronized
     80   ERROR_ENTRY(EL3HLT),           // Level 3 halted
     81   ERROR_ENTRY(EL3RST),           // Level 3 reset
     82   ERROR_ENTRY(ELNRNG),           // Link number out of range
     83   ERROR_ENTRY(EUNATCH),          // Protocol driver not attached
     84   ERROR_ENTRY(ENOCSI),           // No CSI structure available
     85   ERROR_ENTRY(EL2HLT),           // Level 2 halted
     86   ERROR_ENTRY(EBADE),            // Invalid exchange
     87   ERROR_ENTRY(EBADR),            // Invalid request descriptor
     88   ERROR_ENTRY(EXFULL),           // Exchange full
     89   ERROR_ENTRY(ENOANO),           // No anode
     90   ERROR_ENTRY(EBADRQC),          // Invalid request code
     91   ERROR_ENTRY(EBADSLT),          // Invalid slot
     92   ERROR_ENTRY(EBFONT),           // Bad font file format
     93 #endif  // __linux__
     94   ERROR_ENTRY(ENOSTR),           // Device not a stream
     95   ERROR_ENTRY(ENODATA),          // No data available
     96   ERROR_ENTRY(ETIME),            // Timer expired
     97   ERROR_ENTRY(ENOSR),            // Out of streams resources
     98 #ifdef __linux__
     99   ERROR_ENTRY(ENONET),           // Machine is not on the network
    100   ERROR_ENTRY(ENOPKG),           // Package not installed
    101 #endif  // __linux__
    102   ERROR_ENTRY(EREMOTE),          // Object is remote
    103   ERROR_ENTRY(ENOLINK),          // Link has been severed
    104 #ifdef __linux__
    105   ERROR_ENTRY(EADV),             // Advertise error
    106   ERROR_ENTRY(ESRMNT),           // Srmount error
    107   ERROR_ENTRY(ECOMM),            // Communication error on send
    108 #endif  // __linux__
    109   ERROR_ENTRY(EPROTO),           // Protocol error
    110   ERROR_ENTRY(EMULTIHOP),        // Multihop attempted
    111 #ifdef __linux__
    112   ERROR_ENTRY(EDOTDOT),          // RFS specific error
    113 #endif  // __linux__
    114   ERROR_ENTRY(EBADMSG),          // Not a data message
    115   ERROR_ENTRY(EOVERFLOW),        // Value too large for defined data type
    116 #ifdef __linux__
    117   ERROR_ENTRY(ENOTUNIQ),         // Name not unique on network
    118   ERROR_ENTRY(EBADFD),           // File descriptor in bad state
    119   ERROR_ENTRY(EREMCHG),          // Remote address changed
    120   ERROR_ENTRY(ELIBACC),          // Can not access a needed shared library
    121   ERROR_ENTRY(ELIBBAD),          // Accessing a corrupted shared library
    122   ERROR_ENTRY(ELIBSCN),          // .lib section in a.out corrupted
    123   ERROR_ENTRY(ELIBMAX),          // Attempting to link in too many shared libs.
    124   ERROR_ENTRY(ELIBEXEC),         // Cannot exec a shared library directly
    125 #endif  // __linux__
    126   ERROR_ENTRY(EILSEQ),           // Illegal byte sequence
    127 #ifdef __linux__
    128   ERROR_ENTRY(ERESTART),         // Interrupted system call should be restarted
    129   ERROR_ENTRY(ESTRPIPE),         // Streams pipe error
    130 #endif  // __linux__
    131   ERROR_ENTRY(EUSERS),           // Too many users
    132   ERROR_ENTRY(ENOTSOCK),         // Socket operation on non-socket
    133   ERROR_ENTRY(EDESTADDRREQ),     // Destination address required
    134   ERROR_ENTRY(EMSGSIZE),         // Message too long
    135   ERROR_ENTRY(EPROTOTYPE),       // Protocol wrong type for socket
    136   ERROR_ENTRY(ENOPROTOOPT),      // Protocol not available
    137   ERROR_ENTRY(EPROTONOSUPPORT),  // Protocol not supported
    138   ERROR_ENTRY(ESOCKTNOSUPPORT),  // Socket type not supported
    139   ERROR_ENTRY(EOPNOTSUPP),       // Operation not supported o/transport endpoint
    140   ERROR_ENTRY(EPFNOSUPPORT),     // Protocol family not supported
    141   ERROR_ENTRY(EAFNOSUPPORT),     // Address family not supported by protocol
    142   ERROR_ENTRY(EADDRINUSE),       // Address already in use
    143   ERROR_ENTRY(EADDRNOTAVAIL),    // Cannot assign requested address
    144   ERROR_ENTRY(ENETDOWN),         // Network is down
    145   ERROR_ENTRY(ENETUNREACH),      // Network is unreachable
    146   ERROR_ENTRY(ENETRESET),        // Network dropped connection because of reset
    147   ERROR_ENTRY(ECONNABORTED),     // Software caused connection abort
    148   ERROR_ENTRY(ECONNRESET),       // Connection reset by peer
    149   ERROR_ENTRY(ENOBUFS),          // No buffer space available
    150   ERROR_ENTRY(EISCONN),          // Transport endpoint is already connected
    151   ERROR_ENTRY(ENOTCONN),         // Transport endpoint is not connected
    152   ERROR_ENTRY(ESHUTDOWN),        // Cannot send after transp. endpoint shutdown
    153   ERROR_ENTRY(ETOOMANYREFS),     // Too many references: cannot splice
    154   ERROR_ENTRY(ETIMEDOUT),        // Connection timed out
    155   ERROR_ENTRY(ECONNREFUSED),     // Connection refused
    156   ERROR_ENTRY(EHOSTDOWN),        // Host is down
    157   ERROR_ENTRY(EHOSTUNREACH),     // No route to host
    158   ERROR_ENTRY(EALREADY),         // Operation already in progress
    159   ERROR_ENTRY(EINPROGRESS),      // Operation now in progress
    160   ERROR_ENTRY(ESTALE),           // Stale file handle
    161 #ifdef __linux__
    162   ERROR_ENTRY(EUCLEAN),          // Structure needs cleaning
    163   ERROR_ENTRY(ENOTNAM),          // Not a XENIX named type file
    164   ERROR_ENTRY(ENAVAIL),          // No XENIX semaphores available
    165   ERROR_ENTRY(EISNAM),           // Is a named type file
    166   ERROR_ENTRY(EREMOTEIO),        // Remote I/O error
    167 #endif  // __linux__
    168   ERROR_ENTRY(EDQUOT),           // Quota exceeded
    169 #ifdef __linux__
    170   ERROR_ENTRY(ENOMEDIUM),        // No medium found
    171   ERROR_ENTRY(EMEDIUMTYPE),      // Wrong medium type
    172 #endif  // __linux__
    173   ERROR_ENTRY(ECANCELED),        // Operation Canceled
    174 #ifdef __linux__
    175   ERROR_ENTRY(ENOKEY),           // Required key not available
    176   ERROR_ENTRY(EKEYEXPIRED),      // Key has expired
    177   ERROR_ENTRY(EKEYREVOKED),      // Key has been revoked
    178   ERROR_ENTRY(EKEYREJECTED),     // Key was rejected by service
    179 #endif  // __linux__
    180   ERROR_ENTRY(EOWNERDEAD),       // Owner died
    181   ERROR_ENTRY(ENOTRECOVERABLE),  // State not recoverable
    182 #ifdef __linux__
    183   ERROR_ENTRY(ERFKILL),          // Operation not possible due to RF-kill
    184   ERROR_ENTRY(EHWPOISON),        // Memory page has hardware error
    185 #endif  // __linux__
    186 #undef ERROR_ENTRY
    187   // This list comes from <errno.h> system header. The elements are ordered
    188   // by increasing errnum values which is the same order used in the header
    189   // file. So, when new error codes are added to glibc, it should be relatively
    190   // easy to identify them and add them to this list.
    191 };
    192 
    193 // Gets the error code string from system error code. If unknown system error
    194 // number is provided, returns an empty string.
    195 std::string ErrorCodeFromSystemError(int errnum) {
    196   std::string error_code;
    197   for (const ErrorMapEntry& entry : error_map) {
    198     if (entry.errnum == errnum) {
    199       error_code = entry.error_code;
    200       break;
    201     }
    202   }
    203   return error_code;
    204 }
    205 
    206 }  // anonymous namespace
    207 
    208 void AddSystemError(ErrorPtr* error,
    209                     const tracked_objects::Location& location,
    210                     int errnum) {
    211   std::string message = base::safe_strerror(errnum);
    212   std::string code = ErrorCodeFromSystemError(errnum);
    213   if (message.empty())
    214     message = "Unknown error " + std::to_string(errnum);
    215 
    216   if (code.empty())
    217     code = "error_" + std::to_string(errnum);
    218 
    219   Error::AddTo(error, location, kDomain, code, message);
    220 }
    221 
    222 }  // namespace system
    223 
    224 }  // namespace errors
    225 }  // namespace brillo
    226