/proc/self/cwd/external/abseil-cpp~/absl/status/status.cc
Line | Count | Source |
1 | | // Copyright 2019 The Abseil Authors. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | #include "absl/status/status.h" |
15 | | |
16 | | #include <errno.h> |
17 | | |
18 | | #include <atomic> |
19 | | #include <cstddef> |
20 | | #include <cstdint> |
21 | | #include <cstring> |
22 | | #include <memory> |
23 | | #include <ostream> |
24 | | #include <string> |
25 | | |
26 | | #include "absl/base/attributes.h" |
27 | | #include "absl/base/config.h" |
28 | | #include "absl/base/internal/raw_logging.h" |
29 | | #include "absl/base/internal/strerror.h" |
30 | | #include "absl/base/macros.h" |
31 | | #include "absl/base/no_destructor.h" |
32 | | #include "absl/base/nullability.h" |
33 | | #include "absl/debugging/stacktrace.h" |
34 | | #include "absl/debugging/symbolize.h" |
35 | | #include "absl/status/internal/status_internal.h" |
36 | | #include "absl/strings/str_cat.h" |
37 | | #include "absl/strings/str_format.h" |
38 | | #include "absl/strings/str_split.h" |
39 | | #include "absl/strings/string_view.h" |
40 | | #include "absl/types/optional.h" |
41 | | |
42 | | namespace absl { |
43 | | ABSL_NAMESPACE_BEGIN |
44 | | |
45 | | static_assert( |
46 | | alignof(status_internal::StatusRep) >= 4, |
47 | | "absl::Status assumes it can use the bottom 2 bits of a StatusRep*."); |
48 | | |
49 | 0 | std::string StatusCodeToString(StatusCode code) { |
50 | 0 | return std::string(absl::StatusCodeToStringView(code)); |
51 | 0 | } |
52 | | |
53 | 0 | absl::string_view StatusCodeToStringView(StatusCode code) { |
54 | 0 | switch (code) { |
55 | 0 | case StatusCode::kOk: |
56 | 0 | return "OK"; |
57 | 0 | case StatusCode::kCancelled: |
58 | 0 | return "CANCELLED"; |
59 | 0 | case StatusCode::kUnknown: |
60 | 0 | return "UNKNOWN"; |
61 | 0 | case StatusCode::kInvalidArgument: |
62 | 0 | return "INVALID_ARGUMENT"; |
63 | 0 | case StatusCode::kDeadlineExceeded: |
64 | 0 | return "DEADLINE_EXCEEDED"; |
65 | 0 | case StatusCode::kNotFound: |
66 | 0 | return "NOT_FOUND"; |
67 | 0 | case StatusCode::kAlreadyExists: |
68 | 0 | return "ALREADY_EXISTS"; |
69 | 0 | case StatusCode::kPermissionDenied: |
70 | 0 | return "PERMISSION_DENIED"; |
71 | 0 | case StatusCode::kUnauthenticated: |
72 | 0 | return "UNAUTHENTICATED"; |
73 | 0 | case StatusCode::kResourceExhausted: |
74 | 0 | return "RESOURCE_EXHAUSTED"; |
75 | 0 | case StatusCode::kFailedPrecondition: |
76 | 0 | return "FAILED_PRECONDITION"; |
77 | 0 | case StatusCode::kAborted: |
78 | 0 | return "ABORTED"; |
79 | 0 | case StatusCode::kOutOfRange: |
80 | 0 | return "OUT_OF_RANGE"; |
81 | 0 | case StatusCode::kUnimplemented: |
82 | 0 | return "UNIMPLEMENTED"; |
83 | 0 | case StatusCode::kInternal: |
84 | 0 | return "INTERNAL"; |
85 | 0 | case StatusCode::kUnavailable: |
86 | 0 | return "UNAVAILABLE"; |
87 | 0 | case StatusCode::kDataLoss: |
88 | 0 | return "DATA_LOSS"; |
89 | 0 | default: |
90 | 0 | return ""; |
91 | 0 | } |
92 | 0 | } |
93 | | |
94 | 0 | std::ostream& operator<<(std::ostream& os, StatusCode code) { |
95 | 0 | return os << StatusCodeToString(code); |
96 | 0 | } |
97 | | |
98 | 0 | const std::string* absl_nonnull Status::EmptyString() { |
99 | 0 | static const absl::NoDestructor<std::string> kEmpty; |
100 | 0 | return kEmpty.get(); |
101 | 0 | } |
102 | | |
103 | 0 | const std::string* absl_nonnull Status::MovedFromString() { |
104 | 0 | static const absl::NoDestructor<std::string> kMovedFrom(kMovedFromString); |
105 | 0 | return kMovedFrom.get(); |
106 | 0 | } |
107 | | |
108 | | Status::Status(absl::StatusCode code, absl::string_view msg) |
109 | 9.67k | : rep_(CodeToInlinedRep(code)) { |
110 | 9.67k | if (code != absl::StatusCode::kOk && !msg.empty()) { |
111 | 9.67k | rep_ = PointerToRep(new status_internal::StatusRep(code, msg, nullptr)); |
112 | 9.67k | } |
113 | 9.67k | } |
114 | | |
115 | | status_internal::StatusRep* absl_nonnull Status::PrepareToModify( |
116 | 0 | uintptr_t rep) { |
117 | 0 | if (IsInlined(rep)) { |
118 | 0 | return new status_internal::StatusRep(InlinedRepToCode(rep), |
119 | 0 | absl::string_view(), nullptr); |
120 | 0 | } |
121 | 0 | return RepToPointer(rep)->CloneAndUnref(); |
122 | 0 | } |
123 | | |
124 | 0 | std::string Status::ToStringSlow(uintptr_t rep, StatusToStringMode mode) { |
125 | 0 | if (IsInlined(rep)) { |
126 | 0 | return absl::StrCat(absl::StatusCodeToString(InlinedRepToCode(rep)), ": "); |
127 | 0 | } |
128 | 0 | return RepToPointer(rep)->ToString(mode); |
129 | 0 | } |
130 | | |
131 | 0 | std::ostream& operator<<(std::ostream& os, const Status& x) { |
132 | 0 | os << x.ToString(StatusToStringMode::kWithEverything); |
133 | 0 | return os; |
134 | 0 | } |
135 | | |
136 | 0 | Status AbortedError(absl::string_view message) { |
137 | 0 | return Status(absl::StatusCode::kAborted, message); |
138 | 0 | } |
139 | | |
140 | 0 | Status AlreadyExistsError(absl::string_view message) { |
141 | 0 | return Status(absl::StatusCode::kAlreadyExists, message); |
142 | 0 | } |
143 | | |
144 | 5 | Status CancelledError(absl::string_view message) { |
145 | 5 | return Status(absl::StatusCode::kCancelled, message); |
146 | 5 | } |
147 | | |
148 | 0 | Status DataLossError(absl::string_view message) { |
149 | 0 | return Status(absl::StatusCode::kDataLoss, message); |
150 | 0 | } |
151 | | |
152 | 0 | Status DeadlineExceededError(absl::string_view message) { |
153 | 0 | return Status(absl::StatusCode::kDeadlineExceeded, message); |
154 | 0 | } |
155 | | |
156 | 0 | Status FailedPreconditionError(absl::string_view message) { |
157 | 0 | return Status(absl::StatusCode::kFailedPrecondition, message); |
158 | 0 | } |
159 | | |
160 | 0 | Status InternalError(absl::string_view message) { |
161 | 0 | return Status(absl::StatusCode::kInternal, message); |
162 | 0 | } |
163 | | |
164 | 9.67k | Status InvalidArgumentError(absl::string_view message) { |
165 | 9.67k | return Status(absl::StatusCode::kInvalidArgument, message); |
166 | 9.67k | } |
167 | | |
168 | 0 | Status NotFoundError(absl::string_view message) { |
169 | 0 | return Status(absl::StatusCode::kNotFound, message); |
170 | 0 | } |
171 | | |
172 | 0 | Status OutOfRangeError(absl::string_view message) { |
173 | 0 | return Status(absl::StatusCode::kOutOfRange, message); |
174 | 0 | } |
175 | | |
176 | 0 | Status PermissionDeniedError(absl::string_view message) { |
177 | 0 | return Status(absl::StatusCode::kPermissionDenied, message); |
178 | 0 | } |
179 | | |
180 | 0 | Status ResourceExhaustedError(absl::string_view message) { |
181 | 0 | return Status(absl::StatusCode::kResourceExhausted, message); |
182 | 0 | } |
183 | | |
184 | 0 | Status UnauthenticatedError(absl::string_view message) { |
185 | 0 | return Status(absl::StatusCode::kUnauthenticated, message); |
186 | 0 | } |
187 | | |
188 | 0 | Status UnavailableError(absl::string_view message) { |
189 | 0 | return Status(absl::StatusCode::kUnavailable, message); |
190 | 0 | } |
191 | | |
192 | 0 | Status UnimplementedError(absl::string_view message) { |
193 | 0 | return Status(absl::StatusCode::kUnimplemented, message); |
194 | 0 | } |
195 | | |
196 | 0 | Status UnknownError(absl::string_view message) { |
197 | 0 | return Status(absl::StatusCode::kUnknown, message); |
198 | 0 | } |
199 | | |
200 | 0 | bool IsAborted(const Status& status) { |
201 | 0 | return status.code() == absl::StatusCode::kAborted; |
202 | 0 | } |
203 | | |
204 | 0 | bool IsAlreadyExists(const Status& status) { |
205 | 0 | return status.code() == absl::StatusCode::kAlreadyExists; |
206 | 0 | } |
207 | | |
208 | 0 | bool IsCancelled(const Status& status) { |
209 | 0 | return status.code() == absl::StatusCode::kCancelled; |
210 | 0 | } |
211 | | |
212 | 0 | bool IsDataLoss(const Status& status) { |
213 | 0 | return status.code() == absl::StatusCode::kDataLoss; |
214 | 0 | } |
215 | | |
216 | 0 | bool IsDeadlineExceeded(const Status& status) { |
217 | 0 | return status.code() == absl::StatusCode::kDeadlineExceeded; |
218 | 0 | } |
219 | | |
220 | 0 | bool IsFailedPrecondition(const Status& status) { |
221 | 0 | return status.code() == absl::StatusCode::kFailedPrecondition; |
222 | 0 | } |
223 | | |
224 | 0 | bool IsInternal(const Status& status) { |
225 | 0 | return status.code() == absl::StatusCode::kInternal; |
226 | 0 | } |
227 | | |
228 | 0 | bool IsInvalidArgument(const Status& status) { |
229 | 0 | return status.code() == absl::StatusCode::kInvalidArgument; |
230 | 0 | } |
231 | | |
232 | 0 | bool IsNotFound(const Status& status) { |
233 | 0 | return status.code() == absl::StatusCode::kNotFound; |
234 | 0 | } |
235 | | |
236 | 0 | bool IsOutOfRange(const Status& status) { |
237 | 0 | return status.code() == absl::StatusCode::kOutOfRange; |
238 | 0 | } |
239 | | |
240 | 0 | bool IsPermissionDenied(const Status& status) { |
241 | 0 | return status.code() == absl::StatusCode::kPermissionDenied; |
242 | 0 | } |
243 | | |
244 | 0 | bool IsResourceExhausted(const Status& status) { |
245 | 0 | return status.code() == absl::StatusCode::kResourceExhausted; |
246 | 0 | } |
247 | | |
248 | 0 | bool IsUnauthenticated(const Status& status) { |
249 | 0 | return status.code() == absl::StatusCode::kUnauthenticated; |
250 | 0 | } |
251 | | |
252 | 0 | bool IsUnavailable(const Status& status) { |
253 | 0 | return status.code() == absl::StatusCode::kUnavailable; |
254 | 0 | } |
255 | | |
256 | 0 | bool IsUnimplemented(const Status& status) { |
257 | 0 | return status.code() == absl::StatusCode::kUnimplemented; |
258 | 0 | } |
259 | | |
260 | 0 | bool IsUnknown(const Status& status) { |
261 | 0 | return status.code() == absl::StatusCode::kUnknown; |
262 | 0 | } |
263 | | |
264 | 0 | StatusCode ErrnoToStatusCode(int error_number) { |
265 | 0 | switch (error_number) { |
266 | 0 | case 0: |
267 | 0 | return StatusCode::kOk; |
268 | 0 | case EINVAL: // Invalid argument |
269 | 0 | case ENAMETOOLONG: // Filename too long |
270 | 0 | case E2BIG: // Argument list too long |
271 | 0 | case EDESTADDRREQ: // Destination address required |
272 | 0 | case EDOM: // Mathematics argument out of domain of function |
273 | 0 | case EFAULT: // Bad address |
274 | 0 | case EILSEQ: // Illegal byte sequence |
275 | 0 | case ENOPROTOOPT: // Protocol not available |
276 | 0 | case ENOTSOCK: // Not a socket |
277 | 0 | case ENOTTY: // Inappropriate I/O control operation |
278 | 0 | case EPROTOTYPE: // Protocol wrong type for socket |
279 | 0 | case ESPIPE: // Invalid seek |
280 | 0 | return StatusCode::kInvalidArgument; |
281 | 0 | case ETIMEDOUT: // Connection timed out |
282 | 0 | return StatusCode::kDeadlineExceeded; |
283 | 0 | case ENODEV: // No such device |
284 | 0 | case ENOENT: // No such file or directory |
285 | 0 | #ifdef ENOMEDIUM |
286 | 0 | case ENOMEDIUM: // No medium found |
287 | 0 | #endif |
288 | 0 | case ENXIO: // No such device or address |
289 | 0 | case ESRCH: // No such process |
290 | 0 | return StatusCode::kNotFound; |
291 | 0 | case EEXIST: // File exists |
292 | 0 | case EADDRNOTAVAIL: // Address not available |
293 | 0 | case EALREADY: // Connection already in progress |
294 | 0 | #ifdef ENOTUNIQ |
295 | 0 | case ENOTUNIQ: // Name not unique on network |
296 | 0 | #endif |
297 | 0 | return StatusCode::kAlreadyExists; |
298 | 0 | case EPERM: // Operation not permitted |
299 | 0 | case EACCES: // Permission denied |
300 | 0 | #ifdef ENOKEY |
301 | 0 | case ENOKEY: // Required key not available |
302 | 0 | #endif |
303 | 0 | case EROFS: // Read only file system |
304 | 0 | return StatusCode::kPermissionDenied; |
305 | 0 | case ENOTEMPTY: // Directory not empty |
306 | 0 | case EISDIR: // Is a directory |
307 | 0 | case ENOTDIR: // Not a directory |
308 | 0 | case EADDRINUSE: // Address already in use |
309 | 0 | case EBADF: // Invalid file descriptor |
310 | 0 | #ifdef EBADFD |
311 | 0 | case EBADFD: // File descriptor in bad state |
312 | 0 | #endif |
313 | 0 | case EBUSY: // Device or resource busy |
314 | 0 | case ECHILD: // No child processes |
315 | 0 | case EISCONN: // Socket is connected |
316 | 0 | #ifdef EISNAM |
317 | 0 | case EISNAM: // Is a named type file |
318 | 0 | #endif |
319 | 0 | #ifdef ENOTBLK |
320 | 0 | case ENOTBLK: // Block device required |
321 | 0 | #endif |
322 | 0 | case ENOTCONN: // The socket is not connected |
323 | 0 | case EPIPE: // Broken pipe |
324 | 0 | #ifdef ESHUTDOWN |
325 | 0 | case ESHUTDOWN: // Cannot send after transport endpoint shutdown |
326 | 0 | #endif |
327 | 0 | case ETXTBSY: // Text file busy |
328 | 0 | #ifdef EUNATCH |
329 | 0 | case EUNATCH: // Protocol driver not attached |
330 | 0 | #endif |
331 | 0 | return StatusCode::kFailedPrecondition; |
332 | 0 | case ENOSPC: // No space left on device |
333 | 0 | #ifdef EDQUOT |
334 | 0 | case EDQUOT: // Disk quota exceeded |
335 | 0 | #endif |
336 | 0 | case EMFILE: // Too many open files |
337 | 0 | case EMLINK: // Too many links |
338 | 0 | case ENFILE: // Too many open files in system |
339 | 0 | case ENOBUFS: // No buffer space available |
340 | 0 | case ENOMEM: // Not enough space |
341 | 0 | #ifdef EUSERS |
342 | 0 | case EUSERS: // Too many users |
343 | 0 | #endif |
344 | 0 | return StatusCode::kResourceExhausted; |
345 | 0 | #ifdef ECHRNG |
346 | 0 | case ECHRNG: // Channel number out of range |
347 | 0 | #endif |
348 | 0 | case EFBIG: // File too large |
349 | 0 | case EOVERFLOW: // Value too large to be stored in data type |
350 | 0 | case ERANGE: // Result too large |
351 | 0 | return StatusCode::kOutOfRange; |
352 | 0 | #ifdef ENOPKG |
353 | 0 | case ENOPKG: // Package not installed |
354 | 0 | #endif |
355 | 0 | case ENOSYS: // Function not implemented |
356 | 0 | case ENOTSUP: // Operation not supported |
357 | 0 | case EAFNOSUPPORT: // Address family not supported |
358 | 0 | #ifdef EPFNOSUPPORT |
359 | 0 | case EPFNOSUPPORT: // Protocol family not supported |
360 | 0 | #endif |
361 | 0 | case EPROTONOSUPPORT: // Protocol not supported |
362 | 0 | #ifdef ESOCKTNOSUPPORT |
363 | 0 | case ESOCKTNOSUPPORT: // Socket type not supported |
364 | 0 | #endif |
365 | 0 | case EXDEV: // Improper link |
366 | 0 | return StatusCode::kUnimplemented; |
367 | 0 | case EAGAIN: // Resource temporarily unavailable |
368 | 0 | #ifdef ECOMM |
369 | 0 | case ECOMM: // Communication error on send |
370 | 0 | #endif |
371 | 0 | case ECONNREFUSED: // Connection refused |
372 | 0 | case ECONNABORTED: // Connection aborted |
373 | 0 | case ECONNRESET: // Connection reset |
374 | 0 | case EINTR: // Interrupted function call |
375 | 0 | #ifdef EHOSTDOWN |
376 | 0 | case EHOSTDOWN: // Host is down |
377 | 0 | #endif |
378 | 0 | case EHOSTUNREACH: // Host is unreachable |
379 | 0 | case ENETDOWN: // Network is down |
380 | 0 | case ENETRESET: // Connection aborted by network |
381 | 0 | case ENETUNREACH: // Network unreachable |
382 | 0 | case ENOLCK: // No locks available |
383 | 0 | case ENOLINK: // Link has been severed |
384 | 0 | #ifdef ENONET |
385 | 0 | case ENONET: // Machine is not on the network |
386 | 0 | #endif |
387 | 0 | return StatusCode::kUnavailable; |
388 | 0 | case EDEADLK: // Resource deadlock avoided |
389 | 0 | #ifdef ESTALE |
390 | 0 | case ESTALE: // Stale file handle |
391 | 0 | #endif |
392 | 0 | return StatusCode::kAborted; |
393 | 0 | case ECANCELED: // Operation cancelled |
394 | 0 | return StatusCode::kCancelled; |
395 | 0 | default: |
396 | 0 | return StatusCode::kUnknown; |
397 | 0 | } |
398 | 0 | } |
399 | | |
400 | | namespace { |
401 | | std::string MessageForErrnoToStatus(int error_number, |
402 | 0 | absl::string_view message) { |
403 | 0 | return absl::StrCat(message, ": ", |
404 | 0 | absl::base_internal::StrError(error_number)); |
405 | 0 | } |
406 | | } // namespace |
407 | | |
408 | 0 | Status ErrnoToStatus(int error_number, absl::string_view message) { |
409 | 0 | return Status(ErrnoToStatusCode(error_number), |
410 | 0 | MessageForErrnoToStatus(error_number, message)); |
411 | 0 | } |
412 | | |
413 | 0 | const char* absl_nonnull StatusMessageAsCStr(const Status& status) { |
414 | | // As an internal implementation detail, we guarantee that if status.message() |
415 | | // is non-empty, then the resulting string_view is null terminated. |
416 | 0 | auto sv_message = status.message(); |
417 | 0 | return sv_message.empty() ? "" : sv_message.data(); |
418 | 0 | } |
419 | | |
420 | | ABSL_NAMESPACE_END |
421 | | } // namespace absl |