// Copyright 2014 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include <brillo/errors/error_codes.h> #include <base/posix/safe_strerror.h> namespace brillo { namespace errors { namespace dbus { const char kDomain[] = "dbus"; } // namespace dbus namespace json { const char kDomain[] = "json_parser"; const char kParseError[] = "json_parse_error"; const char kObjectExpected[] = "json_object_expected"; } // namespace json namespace http { const char kDomain[] = "http"; } // namespace http namespace system { const char kDomain[] = "system"; namespace { const struct ErrorMapEntry { const char* error_code; int errnum; } error_map[] = { #define ERROR_ENTRY(err) { #err, err } ERROR_ENTRY(EPERM), // Operation not permitted ERROR_ENTRY(ENOENT), // No such file or directory ERROR_ENTRY(ESRCH), // No such process ERROR_ENTRY(EINTR), // Interrupted system call ERROR_ENTRY(EIO), // I/O error ERROR_ENTRY(ENXIO), // No such device or address ERROR_ENTRY(E2BIG), // Argument list too long ERROR_ENTRY(ENOEXEC), // Exec format error ERROR_ENTRY(EBADF), // Bad file number ERROR_ENTRY(ECHILD), // No child processes ERROR_ENTRY(EAGAIN), // Try again ERROR_ENTRY(ENOMEM), // Out of memory ERROR_ENTRY(EACCES), // Permission denied ERROR_ENTRY(EFAULT), // Bad address ERROR_ENTRY(ENOTBLK), // Block device required ERROR_ENTRY(EBUSY), // Device or resource busy ERROR_ENTRY(EEXIST), // File exists ERROR_ENTRY(EXDEV), // Cross-device link ERROR_ENTRY(ENODEV), // No such device ERROR_ENTRY(ENOTDIR), // Not a directory ERROR_ENTRY(EISDIR), // Is a directory ERROR_ENTRY(EINVAL), // Invalid argument ERROR_ENTRY(ENFILE), // File table overflow ERROR_ENTRY(EMFILE), // Too many open files ERROR_ENTRY(ENOTTY), // Not a typewriter ERROR_ENTRY(ETXTBSY), // Text file busy ERROR_ENTRY(EFBIG), // File too large ERROR_ENTRY(ENOSPC), // No space left on device ERROR_ENTRY(ESPIPE), // Illegal seek ERROR_ENTRY(EROFS), // Read-only file system ERROR_ENTRY(EMLINK), // Too many links ERROR_ENTRY(EPIPE), // Broken pipe ERROR_ENTRY(EDOM), // Math argument out of domain of func ERROR_ENTRY(ERANGE), // Math result not representable ERROR_ENTRY(EDEADLK), // Resource deadlock would occur ERROR_ENTRY(ENAMETOOLONG), // File name too long ERROR_ENTRY(ENOLCK), // No record locks available ERROR_ENTRY(ENOSYS), // Function not implemented ERROR_ENTRY(ENOTEMPTY), // Directory not empty ERROR_ENTRY(ELOOP), // Too many symbolic links encountered ERROR_ENTRY(ENOMSG), // No message of desired type ERROR_ENTRY(EIDRM), // Identifier removed #ifdef __linux__ ERROR_ENTRY(ECHRNG), // Channel number out of range ERROR_ENTRY(EL2NSYNC), // Level 2 not synchronized ERROR_ENTRY(EL3HLT), // Level 3 halted ERROR_ENTRY(EL3RST), // Level 3 reset ERROR_ENTRY(ELNRNG), // Link number out of range ERROR_ENTRY(EUNATCH), // Protocol driver not attached ERROR_ENTRY(ENOCSI), // No CSI structure available ERROR_ENTRY(EL2HLT), // Level 2 halted ERROR_ENTRY(EBADE), // Invalid exchange ERROR_ENTRY(EBADR), // Invalid request descriptor ERROR_ENTRY(EXFULL), // Exchange full ERROR_ENTRY(ENOANO), // No anode ERROR_ENTRY(EBADRQC), // Invalid request code ERROR_ENTRY(EBADSLT), // Invalid slot ERROR_ENTRY(EBFONT), // Bad font file format #endif // __linux__ ERROR_ENTRY(ENOSTR), // Device not a stream ERROR_ENTRY(ENODATA), // No data available ERROR_ENTRY(ETIME), // Timer expired ERROR_ENTRY(ENOSR), // Out of streams resources #ifdef __linux__ ERROR_ENTRY(ENONET), // Machine is not on the network ERROR_ENTRY(ENOPKG), // Package not installed #endif // __linux__ ERROR_ENTRY(EREMOTE), // Object is remote ERROR_ENTRY(ENOLINK), // Link has been severed #ifdef __linux__ ERROR_ENTRY(EADV), // Advertise error ERROR_ENTRY(ESRMNT), // Srmount error ERROR_ENTRY(ECOMM), // Communication error on send #endif // __linux__ ERROR_ENTRY(EPROTO), // Protocol error ERROR_ENTRY(EMULTIHOP), // Multihop attempted #ifdef __linux__ ERROR_ENTRY(EDOTDOT), // RFS specific error #endif // __linux__ ERROR_ENTRY(EBADMSG), // Not a data message ERROR_ENTRY(EOVERFLOW), // Value too large for defined data type #ifdef __linux__ ERROR_ENTRY(ENOTUNIQ), // Name not unique on network ERROR_ENTRY(EBADFD), // File descriptor in bad state ERROR_ENTRY(EREMCHG), // Remote address changed ERROR_ENTRY(ELIBACC), // Can not access a needed shared library ERROR_ENTRY(ELIBBAD), // Accessing a corrupted shared library ERROR_ENTRY(ELIBSCN), // .lib section in a.out corrupted ERROR_ENTRY(ELIBMAX), // Attempting to link in too many shared libs. ERROR_ENTRY(ELIBEXEC), // Cannot exec a shared library directly #endif // __linux__ ERROR_ENTRY(EILSEQ), // Illegal byte sequence #ifdef __linux__ ERROR_ENTRY(ERESTART), // Interrupted system call should be restarted ERROR_ENTRY(ESTRPIPE), // Streams pipe error #endif // __linux__ ERROR_ENTRY(EUSERS), // Too many users ERROR_ENTRY(ENOTSOCK), // Socket operation on non-socket ERROR_ENTRY(EDESTADDRREQ), // Destination address required ERROR_ENTRY(EMSGSIZE), // Message too long ERROR_ENTRY(EPROTOTYPE), // Protocol wrong type for socket ERROR_ENTRY(ENOPROTOOPT), // Protocol not available ERROR_ENTRY(EPROTONOSUPPORT), // Protocol not supported ERROR_ENTRY(ESOCKTNOSUPPORT), // Socket type not supported ERROR_ENTRY(EOPNOTSUPP), // Operation not supported o/transport endpoint ERROR_ENTRY(EPFNOSUPPORT), // Protocol family not supported ERROR_ENTRY(EAFNOSUPPORT), // Address family not supported by protocol ERROR_ENTRY(EADDRINUSE), // Address already in use ERROR_ENTRY(EADDRNOTAVAIL), // Cannot assign requested address ERROR_ENTRY(ENETDOWN), // Network is down ERROR_ENTRY(ENETUNREACH), // Network is unreachable ERROR_ENTRY(ENETRESET), // Network dropped connection because of reset ERROR_ENTRY(ECONNABORTED), // Software caused connection abort ERROR_ENTRY(ECONNRESET), // Connection reset by peer ERROR_ENTRY(ENOBUFS), // No buffer space available ERROR_ENTRY(EISCONN), // Transport endpoint is already connected ERROR_ENTRY(ENOTCONN), // Transport endpoint is not connected ERROR_ENTRY(ESHUTDOWN), // Cannot send after transp. endpoint shutdown ERROR_ENTRY(ETOOMANYREFS), // Too many references: cannot splice ERROR_ENTRY(ETIMEDOUT), // Connection timed out ERROR_ENTRY(ECONNREFUSED), // Connection refused ERROR_ENTRY(EHOSTDOWN), // Host is down ERROR_ENTRY(EHOSTUNREACH), // No route to host ERROR_ENTRY(EALREADY), // Operation already in progress ERROR_ENTRY(EINPROGRESS), // Operation now in progress ERROR_ENTRY(ESTALE), // Stale file handle #ifdef __linux__ ERROR_ENTRY(EUCLEAN), // Structure needs cleaning ERROR_ENTRY(ENOTNAM), // Not a XENIX named type file ERROR_ENTRY(ENAVAIL), // No XENIX semaphores available ERROR_ENTRY(EISNAM), // Is a named type file ERROR_ENTRY(EREMOTEIO), // Remote I/O error #endif // __linux__ ERROR_ENTRY(EDQUOT), // Quota exceeded #ifdef __linux__ ERROR_ENTRY(ENOMEDIUM), // No medium found ERROR_ENTRY(EMEDIUMTYPE), // Wrong medium type #endif // __linux__ ERROR_ENTRY(ECANCELED), // Operation Canceled #ifdef __linux__ ERROR_ENTRY(ENOKEY), // Required key not available ERROR_ENTRY(EKEYEXPIRED), // Key has expired ERROR_ENTRY(EKEYREVOKED), // Key has been revoked ERROR_ENTRY(EKEYREJECTED), // Key was rejected by service #endif // __linux__ ERROR_ENTRY(EOWNERDEAD), // Owner died ERROR_ENTRY(ENOTRECOVERABLE), // State not recoverable #ifdef __linux__ ERROR_ENTRY(ERFKILL), // Operation not possible due to RF-kill ERROR_ENTRY(EHWPOISON), // Memory page has hardware error #endif // __linux__ #undef ERROR_ENTRY // This list comes from <errno.h> system header. The elements are ordered // by increasing errnum values which is the same order used in the header // file. So, when new error codes are added to glibc, it should be relatively // easy to identify them and add them to this list. }; // Gets the error code string from system error code. If unknown system error // number is provided, returns an empty string. std::string ErrorCodeFromSystemError(int errnum) { std::string error_code; for (const ErrorMapEntry& entry : error_map) { if (entry.errnum == errnum) { error_code = entry.error_code; break; } } return error_code; } } // anonymous namespace void AddSystemError(ErrorPtr* error, const tracked_objects::Location& location, int errnum) { std::string message = base::safe_strerror(errnum); std::string code = ErrorCodeFromSystemError(errnum); if (message.empty()) message = "Unknown error " + std::to_string(errnum); if (code.empty()) code = "error_" + std::to_string(errnum); Error::AddTo(error, location, kDomain, code, message); } } // namespace system } // namespace errors } // namespace brillo