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