1 // -*- C++ -*- 2 //===---------------------------- system_error ----------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef _LIBCPP_SYSTEM_ERROR 12 #define _LIBCPP_SYSTEM_ERROR 13 14 /* 15 system_error synopsis 16 17 namespace std 18 { 19 20 class error_category 21 { 22 public: 23 virtual ~error_category() noexcept; 24 25 error_category(const error_category&) = delete; 26 error_category& operator=(const error_category&) = delete; 27 28 virtual const char* name() const noexcept = 0; 29 virtual error_condition default_error_condition(int ev) const noexcept; 30 virtual bool equivalent(int code, const error_condition& condition) const noexcept; 31 virtual bool equivalent(const error_code& code, int condition) const noexcept; 32 virtual string message(int ev) const = 0; 33 34 bool operator==(const error_category& rhs) const noexcept; 35 bool operator!=(const error_category& rhs) const noexcept; 36 bool operator<(const error_category& rhs) const noexcept; 37 }; 38 39 const error_category& generic_category() noexcept; 40 const error_category& system_category() noexcept; 41 42 template <class T> struct is_error_code_enum 43 : public false_type {}; 44 45 template <class T> struct is_error_condition_enum 46 : public false_type {}; 47 48 class error_code 49 { 50 public: 51 // constructors: 52 error_code() noexcept; 53 error_code(int val, const error_category& cat) noexcept; 54 template <class ErrorCodeEnum> 55 error_code(ErrorCodeEnum e) noexcept; 56 57 // modifiers: 58 void assign(int val, const error_category& cat) noexcept; 59 template <class ErrorCodeEnum> 60 error_code& operator=(ErrorCodeEnum e) noexcept; 61 void clear() noexcept; 62 63 // observers: 64 int value() const noexcept; 65 const error_category& category() const noexcept; 66 error_condition default_error_condition() const noexcept; 67 string message() const; 68 explicit operator bool() const noexcept; 69 }; 70 71 // non-member functions: 72 bool operator<(const error_code& lhs, const error_code& rhs) noexcept; 73 template <class charT, class traits> 74 basic_ostream<charT,traits>& 75 operator<<(basic_ostream<charT,traits>& os, const error_code& ec); 76 77 class error_condition 78 { 79 public: 80 // constructors: 81 error_condition() noexcept; 82 error_condition(int val, const error_category& cat) noexcept; 83 template <class ErrorConditionEnum> 84 error_condition(ErrorConditionEnum e) noexcept; 85 86 // modifiers: 87 void assign(int val, const error_category& cat) noexcept; 88 template <class ErrorConditionEnum> 89 error_condition& operator=(ErrorConditionEnum e) noexcept; 90 void clear() noexcept; 91 92 // observers: 93 int value() const noexcept; 94 const error_category& category() const noexcept; 95 string message() const noexcept; 96 explicit operator bool() const noexcept; 97 }; 98 99 bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept; 100 101 class system_error 102 : public runtime_error 103 { 104 public: 105 system_error(error_code ec, const string& what_arg); 106 system_error(error_code ec, const char* what_arg); 107 system_error(error_code ec); 108 system_error(int ev, const error_category& ecat, const string& what_arg); 109 system_error(int ev, const error_category& ecat, const char* what_arg); 110 system_error(int ev, const error_category& ecat); 111 112 const error_code& code() const noexcept; 113 const char* what() const noexcept; 114 }; 115 116 enum class errc 117 { 118 address_family_not_supported, // EAFNOSUPPORT 119 address_in_use, // EADDRINUSE 120 address_not_available, // EADDRNOTAVAIL 121 already_connected, // EISCONN 122 argument_list_too_long, // E2BIG 123 argument_out_of_domain, // EDOM 124 bad_address, // EFAULT 125 bad_file_descriptor, // EBADF 126 bad_message, // EBADMSG 127 broken_pipe, // EPIPE 128 connection_aborted, // ECONNABORTED 129 connection_already_in_progress, // EALREADY 130 connection_refused, // ECONNREFUSED 131 connection_reset, // ECONNRESET 132 cross_device_link, // EXDEV 133 destination_address_required, // EDESTADDRREQ 134 device_or_resource_busy, // EBUSY 135 directory_not_empty, // ENOTEMPTY 136 executable_format_error, // ENOEXEC 137 file_exists, // EEXIST 138 file_too_large, // EFBIG 139 filename_too_long, // ENAMETOOLONG 140 function_not_supported, // ENOSYS 141 host_unreachable, // EHOSTUNREACH 142 identifier_removed, // EIDRM 143 illegal_byte_sequence, // EILSEQ 144 inappropriate_io_control_operation, // ENOTTY 145 interrupted, // EINTR 146 invalid_argument, // EINVAL 147 invalid_seek, // ESPIPE 148 io_error, // EIO 149 is_a_directory, // EISDIR 150 message_size, // EMSGSIZE 151 network_down, // ENETDOWN 152 network_reset, // ENETRESET 153 network_unreachable, // ENETUNREACH 154 no_buffer_space, // ENOBUFS 155 no_child_process, // ECHILD 156 no_link, // ENOLINK 157 no_lock_available, // ENOLCK 158 no_message_available, // ENODATA 159 no_message, // ENOMSG 160 no_protocol_option, // ENOPROTOOPT 161 no_space_on_device, // ENOSPC 162 no_stream_resources, // ENOSR 163 no_such_device_or_address, // ENXIO 164 no_such_device, // ENODEV 165 no_such_file_or_directory, // ENOENT 166 no_such_process, // ESRCH 167 not_a_directory, // ENOTDIR 168 not_a_socket, // ENOTSOCK 169 not_a_stream, // ENOSTR 170 not_connected, // ENOTCONN 171 not_enough_memory, // ENOMEM 172 not_supported, // ENOTSUP 173 operation_canceled, // ECANCELED 174 operation_in_progress, // EINPROGRESS 175 operation_not_permitted, // EPERM 176 operation_not_supported, // EOPNOTSUPP 177 operation_would_block, // EWOULDBLOCK 178 owner_dead, // EOWNERDEAD 179 permission_denied, // EACCES 180 protocol_error, // EPROTO 181 protocol_not_supported, // EPROTONOSUPPORT 182 read_only_file_system, // EROFS 183 resource_deadlock_would_occur, // EDEADLK 184 resource_unavailable_try_again, // EAGAIN 185 result_out_of_range, // ERANGE 186 state_not_recoverable, // ENOTRECOVERABLE 187 stream_timeout, // ETIME 188 text_file_busy, // ETXTBSY 189 timed_out, // ETIMEDOUT 190 too_many_files_open_in_system, // ENFILE 191 too_many_files_open, // EMFILE 192 too_many_links, // EMLINK 193 too_many_symbolic_link_levels, // ELOOP 194 value_too_large, // EOVERFLOW 195 wrong_protocol_type // EPROTOTYPE 196 }; 197 198 template <> struct is_error_condition_enum<errc> 199 : true_type { } 200 201 error_code make_error_code(errc e) noexcept; 202 error_condition make_error_condition(errc e) noexcept; 203 204 // Comparison operators: 205 bool operator==(const error_code& lhs, const error_code& rhs) noexcept; 206 bool operator==(const error_code& lhs, const error_condition& rhs) noexcept; 207 bool operator==(const error_condition& lhs, const error_code& rhs) noexcept; 208 bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept; 209 bool operator!=(const error_code& lhs, const error_code& rhs) noexcept; 210 bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; 211 bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; 212 bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; 213 214 template <> struct hash<std::error_code>; 215 216 } // std 217 218 */ 219 220 #include <__config> 221 #include <cerrno> 222 #include <type_traits> 223 #include <stdexcept> 224 #include <__functional_base> 225 226 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 227 #pragma GCC system_header 228 #endif 229 230 _LIBCPP_BEGIN_NAMESPACE_STD 231 232 // is_error_code_enum 233 234 template <class _Tp> 235 struct _LIBCPP_VISIBLE is_error_code_enum 236 : public false_type {}; 237 238 // is_error_condition_enum 239 240 template <class _Tp> 241 struct _LIBCPP_VISIBLE is_error_condition_enum 242 : public false_type {}; 243 244 // Some error codes are not present on all platforms, so we provide equivalents 245 // for them: 246 247 //enum class errc 248 _LIBCPP_DECLARE_STRONG_ENUM(errc) 249 { 250 address_family_not_supported = EAFNOSUPPORT, 251 address_in_use = EADDRINUSE, 252 address_not_available = EADDRNOTAVAIL, 253 already_connected = EISCONN, 254 argument_list_too_long = E2BIG, 255 argument_out_of_domain = EDOM, 256 bad_address = EFAULT, 257 bad_file_descriptor = EBADF, 258 bad_message = EBADMSG, 259 broken_pipe = EPIPE, 260 connection_aborted = ECONNABORTED, 261 connection_already_in_progress = EALREADY, 262 connection_refused = ECONNREFUSED, 263 connection_reset = ECONNRESET, 264 cross_device_link = EXDEV, 265 destination_address_required = EDESTADDRREQ, 266 device_or_resource_busy = EBUSY, 267 directory_not_empty = ENOTEMPTY, 268 executable_format_error = ENOEXEC, 269 file_exists = EEXIST, 270 file_too_large = EFBIG, 271 filename_too_long = ENAMETOOLONG, 272 function_not_supported = ENOSYS, 273 host_unreachable = EHOSTUNREACH, 274 identifier_removed = EIDRM, 275 illegal_byte_sequence = EILSEQ, 276 inappropriate_io_control_operation = ENOTTY, 277 interrupted = EINTR, 278 invalid_argument = EINVAL, 279 invalid_seek = ESPIPE, 280 io_error = EIO, 281 is_a_directory = EISDIR, 282 message_size = EMSGSIZE, 283 network_down = ENETDOWN, 284 network_reset = ENETRESET, 285 network_unreachable = ENETUNREACH, 286 no_buffer_space = ENOBUFS, 287 no_child_process = ECHILD, 288 no_link = ENOLINK, 289 no_lock_available = ENOLCK, 290 #ifdef ENODATA 291 no_message_available = ENODATA, 292 #else 293 no_message_available = ENOMSG, 294 #endif 295 no_message = ENOMSG, 296 no_protocol_option = ENOPROTOOPT, 297 no_space_on_device = ENOSPC, 298 #ifdef ENOSR 299 no_stream_resources = ENOSR, 300 #else 301 no_stream_resources = ENOMEM, 302 #endif 303 no_such_device_or_address = ENXIO, 304 no_such_device = ENODEV, 305 no_such_file_or_directory = ENOENT, 306 no_such_process = ESRCH, 307 not_a_directory = ENOTDIR, 308 not_a_socket = ENOTSOCK, 309 #ifdef ENOSTR 310 not_a_stream = ENOSTR, 311 #else 312 not_a_stream = EINVAL, 313 #endif 314 not_connected = ENOTCONN, 315 not_enough_memory = ENOMEM, 316 not_supported = ENOTSUP, 317 operation_canceled = ECANCELED, 318 operation_in_progress = EINPROGRESS, 319 operation_not_permitted = EPERM, 320 operation_not_supported = EOPNOTSUPP, 321 operation_would_block = EWOULDBLOCK, 322 owner_dead = EOWNERDEAD, 323 permission_denied = EACCES, 324 protocol_error = EPROTO, 325 protocol_not_supported = EPROTONOSUPPORT, 326 read_only_file_system = EROFS, 327 resource_deadlock_would_occur = EDEADLK, 328 resource_unavailable_try_again = EAGAIN, 329 result_out_of_range = ERANGE, 330 state_not_recoverable = ENOTRECOVERABLE, 331 #ifdef ETIME 332 stream_timeout = ETIME, 333 #else 334 stream_timeout = ETIMEDOUT, 335 #endif 336 text_file_busy = ETXTBSY, 337 timed_out = ETIMEDOUT, 338 too_many_files_open_in_system = ENFILE, 339 too_many_files_open = EMFILE, 340 too_many_links = EMLINK, 341 too_many_symbolic_link_levels = ELOOP, 342 value_too_large = EOVERFLOW, 343 wrong_protocol_type = EPROTOTYPE 344 }; 345 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc) 346 347 template <> 348 struct _LIBCPP_VISIBLE is_error_condition_enum<errc> 349 : true_type { }; 350 351 #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS 352 template <> 353 struct _LIBCPP_VISIBLE is_error_condition_enum<errc::__lx> 354 : true_type { }; 355 #endif 356 357 class _LIBCPP_VISIBLE error_condition; 358 class _LIBCPP_VISIBLE error_code; 359 360 // class error_category 361 362 class _LIBCPP_HIDDEN __do_message; 363 364 class _LIBCPP_VISIBLE error_category 365 { 366 public: 367 virtual ~error_category() _NOEXCEPT; 368 369 error_category() _NOEXCEPT; 370 private: 371 error_category(const error_category&);// = delete; 372 error_category& operator=(const error_category&);// = delete; 373 374 public: 375 virtual const char* name() const _NOEXCEPT = 0; 376 virtual error_condition default_error_condition(int __ev) const _NOEXCEPT; 377 virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT; 378 virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; 379 virtual string message(int __ev) const = 0; 380 381 _LIBCPP_ALWAYS_INLINE 382 bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;} 383 384 _LIBCPP_ALWAYS_INLINE 385 bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);} 386 387 _LIBCPP_ALWAYS_INLINE 388 bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;} 389 390 friend class _LIBCPP_HIDDEN __do_message; 391 }; 392 393 class _LIBCPP_HIDDEN __do_message 394 : public error_category 395 { 396 public: 397 virtual string message(int ev) const; 398 }; 399 400 const error_category& generic_category() _NOEXCEPT; 401 const error_category& system_category() _NOEXCEPT; 402 403 class _LIBCPP_VISIBLE error_condition 404 { 405 int __val_; 406 const error_category* __cat_; 407 public: 408 _LIBCPP_ALWAYS_INLINE 409 error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {} 410 411 _LIBCPP_ALWAYS_INLINE 412 error_condition(int __val, const error_category& __cat) _NOEXCEPT 413 : __val_(__val), __cat_(&__cat) {} 414 415 template <class _Ep> 416 _LIBCPP_ALWAYS_INLINE 417 error_condition(_Ep __e, 418 typename enable_if<is_error_condition_enum<_Ep>::value>::type* = 0 419 ) _NOEXCEPT 420 {*this = make_error_condition(__e);} 421 422 _LIBCPP_ALWAYS_INLINE 423 void assign(int __val, const error_category& __cat) _NOEXCEPT 424 { 425 __val_ = __val; 426 __cat_ = &__cat; 427 } 428 429 template <class _Ep> 430 _LIBCPP_ALWAYS_INLINE 431 typename enable_if 432 < 433 is_error_condition_enum<_Ep>::value, 434 error_condition& 435 >::type 436 operator=(_Ep __e) _NOEXCEPT 437 {*this = make_error_condition(__e); return *this;} 438 439 _LIBCPP_ALWAYS_INLINE 440 void clear() _NOEXCEPT 441 { 442 __val_ = 0; 443 __cat_ = &generic_category(); 444 } 445 446 _LIBCPP_ALWAYS_INLINE 447 int value() const _NOEXCEPT {return __val_;} 448 449 _LIBCPP_ALWAYS_INLINE 450 const error_category& category() const _NOEXCEPT {return *__cat_;} 451 string message() const; 452 453 _LIBCPP_ALWAYS_INLINE 454 _LIBCPP_EXPLICIT 455 operator bool() const _NOEXCEPT {return __val_ != 0;} 456 }; 457 458 inline _LIBCPP_INLINE_VISIBILITY 459 error_condition 460 make_error_condition(errc __e) _NOEXCEPT 461 { 462 return error_condition(static_cast<int>(__e), generic_category()); 463 } 464 465 inline _LIBCPP_INLINE_VISIBILITY 466 bool 467 operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT 468 { 469 return __x.category() < __y.category() 470 || (__x.category() == __y.category() && __x.value() < __y.value()); 471 } 472 473 // error_code 474 475 class _LIBCPP_VISIBLE error_code 476 { 477 int __val_; 478 const error_category* __cat_; 479 public: 480 _LIBCPP_ALWAYS_INLINE 481 error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {} 482 483 _LIBCPP_ALWAYS_INLINE 484 error_code(int __val, const error_category& __cat) _NOEXCEPT 485 : __val_(__val), __cat_(&__cat) {} 486 487 template <class _Ep> 488 _LIBCPP_ALWAYS_INLINE 489 error_code(_Ep __e, 490 typename enable_if<is_error_code_enum<_Ep>::value>::type* = 0 491 ) _NOEXCEPT 492 {*this = make_error_code(__e);} 493 494 _LIBCPP_ALWAYS_INLINE 495 void assign(int __val, const error_category& __cat) _NOEXCEPT 496 { 497 __val_ = __val; 498 __cat_ = &__cat; 499 } 500 501 template <class _Ep> 502 _LIBCPP_ALWAYS_INLINE 503 typename enable_if 504 < 505 is_error_code_enum<_Ep>::value, 506 error_code& 507 >::type 508 operator=(_Ep __e) _NOEXCEPT 509 {*this = make_error_code(__e); return *this;} 510 511 _LIBCPP_ALWAYS_INLINE 512 void clear() _NOEXCEPT 513 { 514 __val_ = 0; 515 __cat_ = &system_category(); 516 } 517 518 _LIBCPP_ALWAYS_INLINE 519 int value() const _NOEXCEPT {return __val_;} 520 521 _LIBCPP_ALWAYS_INLINE 522 const error_category& category() const _NOEXCEPT {return *__cat_;} 523 524 _LIBCPP_ALWAYS_INLINE 525 error_condition default_error_condition() const _NOEXCEPT 526 {return __cat_->default_error_condition(__val_);} 527 528 string message() const; 529 530 _LIBCPP_ALWAYS_INLINE 531 _LIBCPP_EXPLICIT 532 operator bool() const _NOEXCEPT {return __val_ != 0;} 533 }; 534 535 inline _LIBCPP_INLINE_VISIBILITY 536 error_code 537 make_error_code(errc __e) _NOEXCEPT 538 { 539 return error_code(static_cast<int>(__e), generic_category()); 540 } 541 542 inline _LIBCPP_INLINE_VISIBILITY 543 bool 544 operator<(const error_code& __x, const error_code& __y) _NOEXCEPT 545 { 546 return __x.category() < __y.category() 547 || (__x.category() == __y.category() && __x.value() < __y.value()); 548 } 549 550 inline _LIBCPP_INLINE_VISIBILITY 551 bool 552 operator==(const error_code& __x, const error_code& __y) _NOEXCEPT 553 { 554 return __x.category() == __y.category() && __x.value() == __y.value(); 555 } 556 557 inline _LIBCPP_INLINE_VISIBILITY 558 bool 559 operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT 560 { 561 return __x.category().equivalent(__x.value(), __y) 562 || __y.category().equivalent(__x, __y.value()); 563 } 564 565 inline _LIBCPP_INLINE_VISIBILITY 566 bool 567 operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT 568 { 569 return __y == __x; 570 } 571 572 inline _LIBCPP_INLINE_VISIBILITY 573 bool 574 operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT 575 { 576 return __x.category() == __y.category() && __x.value() == __y.value(); 577 } 578 579 inline _LIBCPP_INLINE_VISIBILITY 580 bool 581 operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT 582 {return !(__x == __y);} 583 584 inline _LIBCPP_INLINE_VISIBILITY 585 bool 586 operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT 587 {return !(__x == __y);} 588 589 inline _LIBCPP_INLINE_VISIBILITY 590 bool 591 operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT 592 {return !(__x == __y);} 593 594 inline _LIBCPP_INLINE_VISIBILITY 595 bool 596 operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT 597 {return !(__x == __y);} 598 599 template <> 600 struct _LIBCPP_VISIBLE hash<error_code> 601 : public unary_function<error_code, size_t> 602 { 603 _LIBCPP_INLINE_VISIBILITY 604 size_t operator()(const error_code& __ec) const _NOEXCEPT 605 { 606 return static_cast<size_t>(__ec.value()); 607 } 608 }; 609 610 // system_error 611 612 class _LIBCPP_VISIBLE system_error 613 : public runtime_error 614 { 615 error_code __ec_; 616 public: 617 system_error(error_code __ec, const string& __what_arg); 618 system_error(error_code __ec, const char* __what_arg); 619 system_error(error_code __ec); 620 system_error(int __ev, const error_category& __ecat, const string& __what_arg); 621 system_error(int __ev, const error_category& __ecat, const char* __what_arg); 622 system_error(int __ev, const error_category& __ecat); 623 ~system_error() _NOEXCEPT; 624 625 _LIBCPP_ALWAYS_INLINE 626 const error_code& code() const _NOEXCEPT {return __ec_;} 627 628 private: 629 static string __init(const error_code&, string); 630 }; 631 632 void __throw_system_error(int ev, const char* what_arg); 633 634 _LIBCPP_END_NAMESPACE_STD 635 636 #endif // _LIBCPP_SYSTEM_ERROR 637