123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- //===---------------------- system_error.cpp ------------------------------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is dual licensed under the MIT and the University of Illinois Open
- // Source Licenses. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- #include "__config"
- #define _LIBCPP_BUILDING_SYSTEM_ERROR
- #include "system_error"
- #include "include/config_elast.h"
- #include "cerrno"
- #include "cstring"
- #include "cstdio"
- #include "cstdlib"
- #include "cassert"
- #include "string"
- #include "string.h"
- #if defined(__ANDROID__)
- #include <android/api-level.h>
- #endif
- _LIBCPP_BEGIN_NAMESPACE_STD
- // class error_category
- error_category::error_category() _NOEXCEPT
- {
- }
- error_category::~error_category() _NOEXCEPT
- {
- }
- error_condition
- error_category::default_error_condition(int ev) const _NOEXCEPT
- {
- return error_condition(ev, *this);
- }
- bool
- error_category::equivalent(int code, const error_condition& condition) const _NOEXCEPT
- {
- return default_error_condition(code) == condition;
- }
- bool
- error_category::equivalent(const error_code& code, int condition) const _NOEXCEPT
- {
- return *this == code.category() && code.value() == condition;
- }
- namespace {
- // GLIBC also uses 1024 as the maximum buffer size internally.
- constexpr size_t strerror_buff_size = 1024;
- string do_strerror_r(int ev);
- #if defined(__linux__) && !defined(_LIBCPP_HAS_MUSL_LIBC) \
- && (!defined(__ANDROID__) || __ANDROID_API__ >= 23) && !defined(_LIBCPP_SGX_CONFIG)
- // GNU Extended version
- string do_strerror_r(int ev) {
- char buffer[strerror_buff_size];
- char* ret = ::strerror_r(ev, buffer, strerror_buff_size);
- return string(ret);
- }
- #else
- // POSIX version
- string do_strerror_r(int ev) {
- char buffer[strerror_buff_size];
- const int old_errno = errno;
- int ret;
- if ((ret = ::strerror_r(ev, buffer, strerror_buff_size)) != 0) {
- // If `ret == -1` then the error is specified using `errno`, otherwise
- // `ret` represents the error.
- const int new_errno = ret == -1 ? errno : ret;
- errno = old_errno;
- if (new_errno == EINVAL) {
- std::snprintf(buffer, strerror_buff_size, "Unknown error %d", ev);
- return string(buffer);
- } else {
- assert(new_errno == ERANGE);
- // FIXME maybe? 'strerror_buff_size' is likely to exceed the
- // maximum error size so ERANGE shouldn't be returned.
- std::abort();
- }
- }
- return string(buffer);
- }
- #endif
- } // end namespace
- string
- __do_message::message(int ev) const
- {
- #if defined(_LIBCPP_HAS_NO_THREADS)
- return string(::strerror(ev));
- #else
- return do_strerror_r(ev);
- #endif
- }
- class _LIBCPP_HIDDEN __generic_error_category
- : public __do_message
- {
- public:
- virtual const char* name() const _NOEXCEPT;
- virtual string message(int ev) const;
- };
- const char*
- __generic_error_category::name() const _NOEXCEPT
- {
- return "generic";
- }
- string
- __generic_error_category::message(int ev) const
- {
- #ifdef _LIBCPP_ELAST
- if (ev > _LIBCPP_ELAST)
- return string("unspecified generic_category error");
- #endif // _LIBCPP_ELAST
- return __do_message::message(ev);
- }
- const error_category&
- generic_category() _NOEXCEPT
- {
- static __generic_error_category s;
- return s;
- }
- class _LIBCPP_HIDDEN __system_error_category
- : public __do_message
- {
- public:
- virtual const char* name() const _NOEXCEPT;
- virtual string message(int ev) const;
- virtual error_condition default_error_condition(int ev) const _NOEXCEPT;
- };
- const char*
- __system_error_category::name() const _NOEXCEPT
- {
- return "system";
- }
- string
- __system_error_category::message(int ev) const
- {
- #ifdef _LIBCPP_ELAST
- if (ev > _LIBCPP_ELAST)
- return string("unspecified system_category error");
- #endif // _LIBCPP_ELAST
- return __do_message::message(ev);
- }
- error_condition
- __system_error_category::default_error_condition(int ev) const _NOEXCEPT
- {
- #ifdef _LIBCPP_ELAST
- if (ev > _LIBCPP_ELAST)
- return error_condition(ev, system_category());
- #endif // _LIBCPP_ELAST
- return error_condition(ev, generic_category());
- }
- const error_category&
- system_category() _NOEXCEPT
- {
- static __system_error_category s;
- return s;
- }
- // error_condition
- string
- error_condition::message() const
- {
- return __cat_->message(__val_);
- }
- // error_code
- string
- error_code::message() const
- {
- return __cat_->message(__val_);
- }
- // system_error
- string
- system_error::__init(const error_code& ec, string what_arg)
- {
- if (ec)
- {
- if (!what_arg.empty())
- what_arg += ": ";
- what_arg += ec.message();
- }
- return what_arg;
- }
- system_error::system_error(error_code ec, const string& what_arg)
- : runtime_error(__init(ec, what_arg)),
- __ec_(ec)
- {
- }
- system_error::system_error(error_code ec, const char* what_arg)
- : runtime_error(__init(ec, what_arg)),
- __ec_(ec)
- {
- }
- system_error::system_error(error_code ec)
- : runtime_error(__init(ec, "")),
- __ec_(ec)
- {
- }
- system_error::system_error(int ev, const error_category& ecat, const string& what_arg)
- : runtime_error(__init(error_code(ev, ecat), what_arg)),
- __ec_(error_code(ev, ecat))
- {
- }
- system_error::system_error(int ev, const error_category& ecat, const char* what_arg)
- : runtime_error(__init(error_code(ev, ecat), what_arg)),
- __ec_(error_code(ev, ecat))
- {
- }
- system_error::system_error(int ev, const error_category& ecat)
- : runtime_error(__init(error_code(ev, ecat), "")),
- __ec_(error_code(ev, ecat))
- {
- }
- system_error::~system_error() _NOEXCEPT
- {
- }
- void
- __throw_system_error(int ev, const char* what_arg)
- {
- #ifndef _LIBCPP_NO_EXCEPTIONS
- throw system_error(error_code(ev, system_category()), what_arg);
- #else
- (void)ev;
- (void)what_arg;
- #endif
- }
- _LIBCPP_END_NAMESPACE_STD
|