You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
9.9 KiB
226 lines
9.9 KiB
// 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
|