/proc/self/cwd/external/com_google_absl/absl/status/status.cc
Line | Count | Source (jump to first uncovered line) |
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 <cassert> |
19 | | #include <utility> |
20 | | |
21 | | #include "absl/base/internal/raw_logging.h" |
22 | | #include "absl/base/internal/strerror.h" |
23 | | #include "absl/base/macros.h" |
24 | | #include "absl/debugging/stacktrace.h" |
25 | | #include "absl/debugging/symbolize.h" |
26 | | #include "absl/status/status_payload_printer.h" |
27 | | #include "absl/strings/escaping.h" |
28 | | #include "absl/strings/str_cat.h" |
29 | | #include "absl/strings/str_format.h" |
30 | | #include "absl/strings/str_split.h" |
31 | | |
32 | | namespace absl { |
33 | | ABSL_NAMESPACE_BEGIN |
34 | | |
35 | 0 | std::string StatusCodeToString(StatusCode code) { |
36 | 0 | switch (code) { |
37 | 0 | case StatusCode::kOk: |
38 | 0 | return "OK"; |
39 | 0 | case StatusCode::kCancelled: |
40 | 0 | return "CANCELLED"; |
41 | 0 | case StatusCode::kUnknown: |
42 | 0 | return "UNKNOWN"; |
43 | 0 | case StatusCode::kInvalidArgument: |
44 | 0 | return "INVALID_ARGUMENT"; |
45 | 0 | case StatusCode::kDeadlineExceeded: |
46 | 0 | return "DEADLINE_EXCEEDED"; |
47 | 0 | case StatusCode::kNotFound: |
48 | 0 | return "NOT_FOUND"; |
49 | 0 | case StatusCode::kAlreadyExists: |
50 | 0 | return "ALREADY_EXISTS"; |
51 | 0 | case StatusCode::kPermissionDenied: |
52 | 0 | return "PERMISSION_DENIED"; |
53 | 0 | case StatusCode::kUnauthenticated: |
54 | 0 | return "UNAUTHENTICATED"; |
55 | 0 | case StatusCode::kResourceExhausted: |
56 | 0 | return "RESOURCE_EXHAUSTED"; |
57 | 0 | case StatusCode::kFailedPrecondition: |
58 | 0 | return "FAILED_PRECONDITION"; |
59 | 0 | case StatusCode::kAborted: |
60 | 0 | return "ABORTED"; |
61 | 0 | case StatusCode::kOutOfRange: |
62 | 0 | return "OUT_OF_RANGE"; |
63 | 0 | case StatusCode::kUnimplemented: |
64 | 0 | return "UNIMPLEMENTED"; |
65 | 0 | case StatusCode::kInternal: |
66 | 0 | return "INTERNAL"; |
67 | 0 | case StatusCode::kUnavailable: |
68 | 0 | return "UNAVAILABLE"; |
69 | 0 | case StatusCode::kDataLoss: |
70 | 0 | return "DATA_LOSS"; |
71 | 0 | default: |
72 | 0 | return ""; |
73 | 0 | } |
74 | 0 | } |
75 | | |
76 | 0 | std::ostream& operator<<(std::ostream& os, StatusCode code) { |
77 | 0 | return os << StatusCodeToString(code); |
78 | 0 | } |
79 | | |
80 | | namespace status_internal { |
81 | | |
82 | | static absl::optional<size_t> FindPayloadIndexByUrl( |
83 | | const Payloads* payloads, |
84 | 0 | absl::string_view type_url) { |
85 | 0 | if (payloads == nullptr) |
86 | 0 | return absl::nullopt; |
87 | | |
88 | 0 | for (size_t i = 0; i < payloads->size(); ++i) { |
89 | 0 | if ((*payloads)[i].type_url == type_url) return i; |
90 | 0 | } |
91 | | |
92 | 0 | return absl::nullopt; |
93 | 0 | } |
94 | | |
95 | | // Convert canonical code to a value known to this binary. |
96 | 0 | absl::StatusCode MapToLocalCode(int value) { |
97 | 0 | absl::StatusCode code = static_cast<absl::StatusCode>(value); |
98 | 0 | switch (code) { |
99 | 0 | case absl::StatusCode::kOk: |
100 | 0 | case absl::StatusCode::kCancelled: |
101 | 0 | case absl::StatusCode::kUnknown: |
102 | 0 | case absl::StatusCode::kInvalidArgument: |
103 | 0 | case absl::StatusCode::kDeadlineExceeded: |
104 | 0 | case absl::StatusCode::kNotFound: |
105 | 0 | case absl::StatusCode::kAlreadyExists: |
106 | 0 | case absl::StatusCode::kPermissionDenied: |
107 | 0 | case absl::StatusCode::kResourceExhausted: |
108 | 0 | case absl::StatusCode::kFailedPrecondition: |
109 | 0 | case absl::StatusCode::kAborted: |
110 | 0 | case absl::StatusCode::kOutOfRange: |
111 | 0 | case absl::StatusCode::kUnimplemented: |
112 | 0 | case absl::StatusCode::kInternal: |
113 | 0 | case absl::StatusCode::kUnavailable: |
114 | 0 | case absl::StatusCode::kDataLoss: |
115 | 0 | case absl::StatusCode::kUnauthenticated: |
116 | 0 | return code; |
117 | 0 | default: |
118 | 0 | return absl::StatusCode::kUnknown; |
119 | 0 | } |
120 | 0 | } |
121 | | } // namespace status_internal |
122 | | |
123 | | absl::optional<absl::Cord> Status::GetPayload( |
124 | 0 | absl::string_view type_url) const { |
125 | 0 | const auto* payloads = GetPayloads(); |
126 | 0 | absl::optional<size_t> index = |
127 | 0 | status_internal::FindPayloadIndexByUrl(payloads, type_url); |
128 | 0 | if (index.has_value()) |
129 | 0 | return (*payloads)[index.value()].payload; |
130 | | |
131 | 0 | return absl::nullopt; |
132 | 0 | } |
133 | | |
134 | 0 | void Status::SetPayload(absl::string_view type_url, absl::Cord payload) { |
135 | 0 | if (ok()) return; |
136 | | |
137 | 0 | PrepareToModify(); |
138 | |
|
139 | 0 | status_internal::StatusRep* rep = RepToPointer(rep_); |
140 | 0 | if (!rep->payloads) { |
141 | 0 | rep->payloads = absl::make_unique<status_internal::Payloads>(); |
142 | 0 | } |
143 | |
|
144 | 0 | absl::optional<size_t> index = |
145 | 0 | status_internal::FindPayloadIndexByUrl(rep->payloads.get(), type_url); |
146 | 0 | if (index.has_value()) { |
147 | 0 | (*rep->payloads)[index.value()].payload = std::move(payload); |
148 | 0 | return; |
149 | 0 | } |
150 | | |
151 | 0 | rep->payloads->push_back({std::string(type_url), std::move(payload)}); |
152 | 0 | } |
153 | | |
154 | 0 | bool Status::ErasePayload(absl::string_view type_url) { |
155 | 0 | absl::optional<size_t> index = |
156 | 0 | status_internal::FindPayloadIndexByUrl(GetPayloads(), type_url); |
157 | 0 | if (index.has_value()) { |
158 | 0 | PrepareToModify(); |
159 | 0 | GetPayloads()->erase(GetPayloads()->begin() + index.value()); |
160 | 0 | if (GetPayloads()->empty() && message().empty()) { |
161 | | // Special case: If this can be represented inlined, it MUST be |
162 | | // inlined (EqualsSlow depends on this behavior). |
163 | 0 | StatusCode c = static_cast<StatusCode>(raw_code()); |
164 | 0 | Unref(rep_); |
165 | 0 | rep_ = CodeToInlinedRep(c); |
166 | 0 | } |
167 | 0 | return true; |
168 | 0 | } |
169 | | |
170 | 0 | return false; |
171 | 0 | } |
172 | | |
173 | | void Status::ForEachPayload( |
174 | | absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor) |
175 | 0 | const { |
176 | 0 | if (auto* payloads = GetPayloads()) { |
177 | 0 | bool in_reverse = |
178 | 0 | payloads->size() > 1 && reinterpret_cast<uintptr_t>(payloads) % 13 > 6; |
179 | |
|
180 | 0 | for (size_t index = 0; index < payloads->size(); ++index) { |
181 | 0 | const auto& elem = |
182 | 0 | (*payloads)[in_reverse ? payloads->size() - 1 - index : index]; |
183 | |
|
184 | | #ifdef NDEBUG |
185 | | visitor(elem.type_url, elem.payload); |
186 | | #else |
187 | | // In debug mode invalidate the type url to prevent users from relying on |
188 | | // this string lifetime. |
189 | | |
190 | | // NOLINTNEXTLINE intentional extra conversion to force temporary. |
191 | 0 | visitor(std::string(elem.type_url), elem.payload); |
192 | 0 | #endif // NDEBUG |
193 | 0 | } |
194 | 0 | } |
195 | 0 | } |
196 | | |
197 | 0 | const std::string* Status::EmptyString() { |
198 | 0 | static union EmptyString { |
199 | 0 | std::string str; |
200 | 0 | ~EmptyString() {} |
201 | 0 | } empty = {{}}; |
202 | 0 | return &empty.str; |
203 | 0 | } |
204 | | |
205 | | #ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL |
206 | | constexpr const char Status::kMovedFromString[]; |
207 | | #endif |
208 | | |
209 | 0 | const std::string* Status::MovedFromString() { |
210 | 0 | static std::string* moved_from_string = new std::string(kMovedFromString); |
211 | 0 | return moved_from_string; |
212 | 0 | } |
213 | | |
214 | 137 | void Status::UnrefNonInlined(uintptr_t rep) { |
215 | 137 | status_internal::StatusRep* r = RepToPointer(rep); |
216 | | // Fast path: if ref==1, there is no need for a RefCountDec (since |
217 | | // this is the only reference and therefore no other thread is |
218 | | // allowed to be mucking with r). |
219 | 137 | if (r->ref.load(std::memory_order_acquire) == 1 || |
220 | 137 | r->ref.fetch_sub(1, std::memory_order_acq_rel) - 1 == 0) { |
221 | 137 | delete r; |
222 | 137 | } |
223 | 137 | } |
224 | | |
225 | | Status::Status(absl::StatusCode code, absl::string_view msg) |
226 | 137 | : rep_(CodeToInlinedRep(code)) { |
227 | 137 | if (code != absl::StatusCode::kOk && !msg.empty()) { |
228 | 137 | rep_ = PointerToRep(new status_internal::StatusRep(code, msg, nullptr)); |
229 | 137 | } |
230 | 137 | } |
231 | | |
232 | 0 | int Status::raw_code() const { |
233 | 0 | if (IsInlined(rep_)) { |
234 | 0 | return static_cast<int>(InlinedRepToCode(rep_)); |
235 | 0 | } |
236 | 0 | status_internal::StatusRep* rep = RepToPointer(rep_); |
237 | 0 | return static_cast<int>(rep->code); |
238 | 0 | } |
239 | | |
240 | 0 | absl::StatusCode Status::code() const { |
241 | 0 | return status_internal::MapToLocalCode(raw_code()); |
242 | 0 | } |
243 | | |
244 | 0 | void Status::PrepareToModify() { |
245 | 0 | ABSL_RAW_CHECK(!ok(), "PrepareToModify shouldn't be called on OK status."); |
246 | 0 | if (IsInlined(rep_)) { |
247 | 0 | rep_ = PointerToRep(new status_internal::StatusRep( |
248 | 0 | static_cast<absl::StatusCode>(raw_code()), absl::string_view(), |
249 | 0 | nullptr)); |
250 | 0 | return; |
251 | 0 | } |
252 | | |
253 | 0 | uintptr_t rep_i = rep_; |
254 | 0 | status_internal::StatusRep* rep = RepToPointer(rep_); |
255 | 0 | if (rep->ref.load(std::memory_order_acquire) != 1) { |
256 | 0 | std::unique_ptr<status_internal::Payloads> payloads; |
257 | 0 | if (rep->payloads) { |
258 | 0 | payloads = absl::make_unique<status_internal::Payloads>(*rep->payloads); |
259 | 0 | } |
260 | 0 | status_internal::StatusRep* const new_rep = new status_internal::StatusRep( |
261 | 0 | rep->code, message(), std::move(payloads)); |
262 | 0 | rep_ = PointerToRep(new_rep); |
263 | 0 | UnrefNonInlined(rep_i); |
264 | 0 | } |
265 | 0 | } |
266 | | |
267 | 0 | bool Status::EqualsSlow(const absl::Status& a, const absl::Status& b) { |
268 | 0 | if (IsInlined(a.rep_) != IsInlined(b.rep_)) return false; |
269 | 0 | if (a.message() != b.message()) return false; |
270 | 0 | if (a.raw_code() != b.raw_code()) return false; |
271 | 0 | if (a.GetPayloads() == b.GetPayloads()) return true; |
272 | | |
273 | 0 | const status_internal::Payloads no_payloads; |
274 | 0 | const status_internal::Payloads* larger_payloads = |
275 | 0 | a.GetPayloads() ? a.GetPayloads() : &no_payloads; |
276 | 0 | const status_internal::Payloads* smaller_payloads = |
277 | 0 | b.GetPayloads() ? b.GetPayloads() : &no_payloads; |
278 | 0 | if (larger_payloads->size() < smaller_payloads->size()) { |
279 | 0 | std::swap(larger_payloads, smaller_payloads); |
280 | 0 | } |
281 | 0 | if ((larger_payloads->size() - smaller_payloads->size()) > 1) return false; |
282 | | // Payloads can be ordered differently, so we can't just compare payload |
283 | | // vectors. |
284 | 0 | for (const auto& payload : *larger_payloads) { |
285 | |
|
286 | 0 | bool found = false; |
287 | 0 | for (const auto& other_payload : *smaller_payloads) { |
288 | 0 | if (payload.type_url == other_payload.type_url) { |
289 | 0 | if (payload.payload != other_payload.payload) { |
290 | 0 | return false; |
291 | 0 | } |
292 | 0 | found = true; |
293 | 0 | break; |
294 | 0 | } |
295 | 0 | } |
296 | 0 | if (!found) return false; |
297 | 0 | } |
298 | 0 | return true; |
299 | 0 | } |
300 | | |
301 | 0 | std::string Status::ToStringSlow(StatusToStringMode mode) const { |
302 | 0 | std::string text; |
303 | 0 | absl::StrAppend(&text, absl::StatusCodeToString(code()), ": ", message()); |
304 | |
|
305 | 0 | const bool with_payload = (mode & StatusToStringMode::kWithPayload) == |
306 | 0 | StatusToStringMode::kWithPayload; |
307 | |
|
308 | 0 | if (with_payload) { |
309 | 0 | status_internal::StatusPayloadPrinter printer = |
310 | 0 | status_internal::GetStatusPayloadPrinter(); |
311 | 0 | this->ForEachPayload([&](absl::string_view type_url, |
312 | 0 | const absl::Cord& payload) { |
313 | 0 | absl::optional<std::string> result; |
314 | 0 | if (printer) result = printer(type_url, payload); |
315 | 0 | absl::StrAppend( |
316 | 0 | &text, " [", type_url, "='", |
317 | 0 | result.has_value() ? *result : absl::CHexEscape(std::string(payload)), |
318 | 0 | "']"); |
319 | 0 | }); |
320 | 0 | } |
321 | |
|
322 | 0 | return text; |
323 | 0 | } |
324 | | |
325 | 0 | std::ostream& operator<<(std::ostream& os, const Status& x) { |
326 | 0 | os << x.ToString(StatusToStringMode::kWithEverything); |
327 | 0 | return os; |
328 | 0 | } |
329 | | |
330 | 0 | Status AbortedError(absl::string_view message) { |
331 | 0 | return Status(absl::StatusCode::kAborted, message); |
332 | 0 | } |
333 | | |
334 | 0 | Status AlreadyExistsError(absl::string_view message) { |
335 | 0 | return Status(absl::StatusCode::kAlreadyExists, message); |
336 | 0 | } |
337 | | |
338 | 0 | Status CancelledError(absl::string_view message) { |
339 | 0 | return Status(absl::StatusCode::kCancelled, message); |
340 | 0 | } |
341 | | |
342 | 0 | Status DataLossError(absl::string_view message) { |
343 | 0 | return Status(absl::StatusCode::kDataLoss, message); |
344 | 0 | } |
345 | | |
346 | 0 | Status DeadlineExceededError(absl::string_view message) { |
347 | 0 | return Status(absl::StatusCode::kDeadlineExceeded, message); |
348 | 0 | } |
349 | | |
350 | 0 | Status FailedPreconditionError(absl::string_view message) { |
351 | 0 | return Status(absl::StatusCode::kFailedPrecondition, message); |
352 | 0 | } |
353 | | |
354 | 0 | Status InternalError(absl::string_view message) { |
355 | 0 | return Status(absl::StatusCode::kInternal, message); |
356 | 0 | } |
357 | | |
358 | 0 | Status InvalidArgumentError(absl::string_view message) { |
359 | 0 | return Status(absl::StatusCode::kInvalidArgument, message); |
360 | 0 | } |
361 | | |
362 | 0 | Status NotFoundError(absl::string_view message) { |
363 | 0 | return Status(absl::StatusCode::kNotFound, message); |
364 | 0 | } |
365 | | |
366 | 0 | Status OutOfRangeError(absl::string_view message) { |
367 | 0 | return Status(absl::StatusCode::kOutOfRange, message); |
368 | 0 | } |
369 | | |
370 | 0 | Status PermissionDeniedError(absl::string_view message) { |
371 | 0 | return Status(absl::StatusCode::kPermissionDenied, message); |
372 | 0 | } |
373 | | |
374 | 0 | Status ResourceExhaustedError(absl::string_view message) { |
375 | 0 | return Status(absl::StatusCode::kResourceExhausted, message); |
376 | 0 | } |
377 | | |
378 | 0 | Status UnauthenticatedError(absl::string_view message) { |
379 | 0 | return Status(absl::StatusCode::kUnauthenticated, message); |
380 | 0 | } |
381 | | |
382 | 0 | Status UnavailableError(absl::string_view message) { |
383 | 0 | return Status(absl::StatusCode::kUnavailable, message); |
384 | 0 | } |
385 | | |
386 | 0 | Status UnimplementedError(absl::string_view message) { |
387 | 0 | return Status(absl::StatusCode::kUnimplemented, message); |
388 | 0 | } |
389 | | |
390 | 0 | Status UnknownError(absl::string_view message) { |
391 | 0 | return Status(absl::StatusCode::kUnknown, message); |
392 | 0 | } |
393 | | |
394 | 0 | bool IsAborted(const Status& status) { |
395 | 0 | return status.code() == absl::StatusCode::kAborted; |
396 | 0 | } |
397 | | |
398 | 0 | bool IsAlreadyExists(const Status& status) { |
399 | 0 | return status.code() == absl::StatusCode::kAlreadyExists; |
400 | 0 | } |
401 | | |
402 | 0 | bool IsCancelled(const Status& status) { |
403 | 0 | return status.code() == absl::StatusCode::kCancelled; |
404 | 0 | } |
405 | | |
406 | 0 | bool IsDataLoss(const Status& status) { |
407 | 0 | return status.code() == absl::StatusCode::kDataLoss; |
408 | 0 | } |
409 | | |
410 | 0 | bool IsDeadlineExceeded(const Status& status) { |
411 | 0 | return status.code() == absl::StatusCode::kDeadlineExceeded; |
412 | 0 | } |
413 | | |
414 | 0 | bool IsFailedPrecondition(const Status& status) { |
415 | 0 | return status.code() == absl::StatusCode::kFailedPrecondition; |
416 | 0 | } |
417 | | |
418 | 0 | bool IsInternal(const Status& status) { |
419 | 0 | return status.code() == absl::StatusCode::kInternal; |
420 | 0 | } |
421 | | |
422 | 0 | bool IsInvalidArgument(const Status& status) { |
423 | 0 | return status.code() == absl::StatusCode::kInvalidArgument; |
424 | 0 | } |
425 | | |
426 | 0 | bool IsNotFound(const Status& status) { |
427 | 0 | return status.code() == absl::StatusCode::kNotFound; |
428 | 0 | } |
429 | | |
430 | 0 | bool IsOutOfRange(const Status& status) { |
431 | 0 | return status.code() == absl::StatusCode::kOutOfRange; |
432 | 0 | } |
433 | | |
434 | 0 | bool IsPermissionDenied(const Status& status) { |
435 | 0 | return status.code() == absl::StatusCode::kPermissionDenied; |
436 | 0 | } |
437 | | |
438 | 0 | bool IsResourceExhausted(const Status& status) { |
439 | 0 | return status.code() == absl::StatusCode::kResourceExhausted; |
440 | 0 | } |
441 | | |
442 | 0 | bool IsUnauthenticated(const Status& status) { |
443 | 0 | return status.code() == absl::StatusCode::kUnauthenticated; |
444 | 0 | } |
445 | | |
446 | 0 | bool IsUnavailable(const Status& status) { |
447 | 0 | return status.code() == absl::StatusCode::kUnavailable; |
448 | 0 | } |
449 | | |
450 | 0 | bool IsUnimplemented(const Status& status) { |
451 | 0 | return status.code() == absl::StatusCode::kUnimplemented; |
452 | 0 | } |
453 | | |
454 | 0 | bool IsUnknown(const Status& status) { |
455 | 0 | return status.code() == absl::StatusCode::kUnknown; |
456 | 0 | } |
457 | | |
458 | 0 | StatusCode ErrnoToStatusCode(int error_number) { |
459 | 0 | switch (error_number) { |
460 | 0 | case 0: |
461 | 0 | return StatusCode::kOk; |
462 | 0 | case EINVAL: // Invalid argument |
463 | 0 | case ENAMETOOLONG: // Filename too long |
464 | 0 | case E2BIG: // Argument list too long |
465 | 0 | case EDESTADDRREQ: // Destination address required |
466 | 0 | case EDOM: // Mathematics argument out of domain of function |
467 | 0 | case EFAULT: // Bad address |
468 | 0 | case EILSEQ: // Illegal byte sequence |
469 | 0 | case ENOPROTOOPT: // Protocol not available |
470 | 0 | case ENOSTR: // Not a STREAM |
471 | 0 | case ENOTSOCK: // Not a socket |
472 | 0 | case ENOTTY: // Inappropriate I/O control operation |
473 | 0 | case EPROTOTYPE: // Protocol wrong type for socket |
474 | 0 | case ESPIPE: // Invalid seek |
475 | 0 | return StatusCode::kInvalidArgument; |
476 | 0 | case ETIMEDOUT: // Connection timed out |
477 | 0 | case ETIME: // Timer expired |
478 | 0 | return StatusCode::kDeadlineExceeded; |
479 | 0 | case ENODEV: // No such device |
480 | 0 | case ENOENT: // No such file or directory |
481 | 0 | #ifdef ENOMEDIUM |
482 | 0 | case ENOMEDIUM: // No medium found |
483 | 0 | #endif |
484 | 0 | case ENXIO: // No such device or address |
485 | 0 | case ESRCH: // No such process |
486 | 0 | return StatusCode::kNotFound; |
487 | 0 | case EEXIST: // File exists |
488 | 0 | case EADDRNOTAVAIL: // Address not available |
489 | 0 | case EALREADY: // Connection already in progress |
490 | 0 | #ifdef ENOTUNIQ |
491 | 0 | case ENOTUNIQ: // Name not unique on network |
492 | 0 | #endif |
493 | 0 | return StatusCode::kAlreadyExists; |
494 | 0 | case EPERM: // Operation not permitted |
495 | 0 | case EACCES: // Permission denied |
496 | 0 | #ifdef ENOKEY |
497 | 0 | case ENOKEY: // Required key not available |
498 | 0 | #endif |
499 | 0 | case EROFS: // Read only file system |
500 | 0 | return StatusCode::kPermissionDenied; |
501 | 0 | case ENOTEMPTY: // Directory not empty |
502 | 0 | case EISDIR: // Is a directory |
503 | 0 | case ENOTDIR: // Not a directory |
504 | 0 | case EADDRINUSE: // Address already in use |
505 | 0 | case EBADF: // Invalid file descriptor |
506 | 0 | #ifdef EBADFD |
507 | 0 | case EBADFD: // File descriptor in bad state |
508 | 0 | #endif |
509 | 0 | case EBUSY: // Device or resource busy |
510 | 0 | case ECHILD: // No child processes |
511 | 0 | case EISCONN: // Socket is connected |
512 | 0 | #ifdef EISNAM |
513 | 0 | case EISNAM: // Is a named type file |
514 | 0 | #endif |
515 | 0 | #ifdef ENOTBLK |
516 | 0 | case ENOTBLK: // Block device required |
517 | 0 | #endif |
518 | 0 | case ENOTCONN: // The socket is not connected |
519 | 0 | case EPIPE: // Broken pipe |
520 | 0 | #ifdef ESHUTDOWN |
521 | 0 | case ESHUTDOWN: // Cannot send after transport endpoint shutdown |
522 | 0 | #endif |
523 | 0 | case ETXTBSY: // Text file busy |
524 | 0 | #ifdef EUNATCH |
525 | 0 | case EUNATCH: // Protocol driver not attached |
526 | 0 | #endif |
527 | 0 | return StatusCode::kFailedPrecondition; |
528 | 0 | case ENOSPC: // No space left on device |
529 | 0 | #ifdef EDQUOT |
530 | 0 | case EDQUOT: // Disk quota exceeded |
531 | 0 | #endif |
532 | 0 | case EMFILE: // Too many open files |
533 | 0 | case EMLINK: // Too many links |
534 | 0 | case ENFILE: // Too many open files in system |
535 | 0 | case ENOBUFS: // No buffer space available |
536 | 0 | case ENODATA: // No message is available on the STREAM read queue |
537 | 0 | case ENOMEM: // Not enough space |
538 | 0 | case ENOSR: // No STREAM resources |
539 | 0 | #ifdef EUSERS |
540 | 0 | case EUSERS: // Too many users |
541 | 0 | #endif |
542 | 0 | return StatusCode::kResourceExhausted; |
543 | 0 | #ifdef ECHRNG |
544 | 0 | case ECHRNG: // Channel number out of range |
545 | 0 | #endif |
546 | 0 | case EFBIG: // File too large |
547 | 0 | case EOVERFLOW: // Value too large to be stored in data type |
548 | 0 | case ERANGE: // Result too large |
549 | 0 | return StatusCode::kOutOfRange; |
550 | 0 | #ifdef ENOPKG |
551 | 0 | case ENOPKG: // Package not installed |
552 | 0 | #endif |
553 | 0 | case ENOSYS: // Function not implemented |
554 | 0 | case ENOTSUP: // Operation not supported |
555 | 0 | case EAFNOSUPPORT: // Address family not supported |
556 | 0 | #ifdef EPFNOSUPPORT |
557 | 0 | case EPFNOSUPPORT: // Protocol family not supported |
558 | 0 | #endif |
559 | 0 | case EPROTONOSUPPORT: // Protocol not supported |
560 | 0 | #ifdef ESOCKTNOSUPPORT |
561 | 0 | case ESOCKTNOSUPPORT: // Socket type not supported |
562 | 0 | #endif |
563 | 0 | case EXDEV: // Improper link |
564 | 0 | return StatusCode::kUnimplemented; |
565 | 0 | case EAGAIN: // Resource temporarily unavailable |
566 | 0 | #ifdef ECOMM |
567 | 0 | case ECOMM: // Communication error on send |
568 | 0 | #endif |
569 | 0 | case ECONNREFUSED: // Connection refused |
570 | 0 | case ECONNABORTED: // Connection aborted |
571 | 0 | case ECONNRESET: // Connection reset |
572 | 0 | case EINTR: // Interrupted function call |
573 | 0 | #ifdef EHOSTDOWN |
574 | 0 | case EHOSTDOWN: // Host is down |
575 | 0 | #endif |
576 | 0 | case EHOSTUNREACH: // Host is unreachable |
577 | 0 | case ENETDOWN: // Network is down |
578 | 0 | case ENETRESET: // Connection aborted by network |
579 | 0 | case ENETUNREACH: // Network unreachable |
580 | 0 | case ENOLCK: // No locks available |
581 | 0 | case ENOLINK: // Link has been severed |
582 | 0 | #ifdef ENONET |
583 | 0 | case ENONET: // Machine is not on the network |
584 | 0 | #endif |
585 | 0 | return StatusCode::kUnavailable; |
586 | 0 | case EDEADLK: // Resource deadlock avoided |
587 | 0 | #ifdef ESTALE |
588 | 0 | case ESTALE: // Stale file handle |
589 | 0 | #endif |
590 | 0 | return StatusCode::kAborted; |
591 | 0 | case ECANCELED: // Operation cancelled |
592 | 0 | return StatusCode::kCancelled; |
593 | 0 | default: |
594 | 0 | return StatusCode::kUnknown; |
595 | 0 | } |
596 | 0 | } |
597 | | |
598 | | namespace { |
599 | | std::string MessageForErrnoToStatus(int error_number, |
600 | 0 | absl::string_view message) { |
601 | 0 | return absl::StrCat(message, ": ", |
602 | 0 | absl::base_internal::StrError(error_number)); |
603 | 0 | } |
604 | | } // namespace |
605 | | |
606 | 0 | Status ErrnoToStatus(int error_number, absl::string_view message) { |
607 | 0 | return Status(ErrnoToStatusCode(error_number), |
608 | 0 | MessageForErrnoToStatus(error_number, message)); |
609 | 0 | } |
610 | | |
611 | | namespace status_internal { |
612 | | |
613 | | std::string* MakeCheckFailString(const absl::Status* status, |
614 | 0 | const char* prefix) { |
615 | 0 | return new std::string( |
616 | 0 | absl::StrCat(prefix, " (", |
617 | 0 | status->ToString(StatusToStringMode::kWithEverything), ")")); |
618 | 0 | } |
619 | | |
620 | | } // namespace status_internal |
621 | | |
622 | | ABSL_NAMESPACE_END |
623 | | } // namespace absl |