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.
ErrorCodeFromSystemError(int errnum)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
AddSystemError(ErrorPtr * error,const tracked_objects::Location & location,int errnum)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