// 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 base::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