system_error.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. //===---------------------- system_error.cpp ------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "__config"
  10. #define _LIBCPP_BUILDING_SYSTEM_ERROR
  11. #include "system_error"
  12. #include "include/config_elast.h"
  13. #include "cerrno"
  14. #include "cstring"
  15. #include "cstdio"
  16. #include "cstdlib"
  17. #include "cassert"
  18. #include "string"
  19. #include "string.h"
  20. #if defined(__ANDROID__)
  21. #include <android/api-level.h>
  22. #endif
  23. _LIBCPP_BEGIN_NAMESPACE_STD
  24. // class error_category
  25. error_category::error_category() _NOEXCEPT
  26. {
  27. }
  28. error_category::~error_category() _NOEXCEPT
  29. {
  30. }
  31. error_condition
  32. error_category::default_error_condition(int ev) const _NOEXCEPT
  33. {
  34. return error_condition(ev, *this);
  35. }
  36. bool
  37. error_category::equivalent(int code, const error_condition& condition) const _NOEXCEPT
  38. {
  39. return default_error_condition(code) == condition;
  40. }
  41. bool
  42. error_category::equivalent(const error_code& code, int condition) const _NOEXCEPT
  43. {
  44. return *this == code.category() && code.value() == condition;
  45. }
  46. namespace {
  47. // GLIBC also uses 1024 as the maximum buffer size internally.
  48. constexpr size_t strerror_buff_size = 1024;
  49. string do_strerror_r(int ev);
  50. #if defined(__linux__) && !defined(_LIBCPP_HAS_MUSL_LIBC) \
  51. && (!defined(__ANDROID__) || __ANDROID_API__ >= 23) && !defined(_LIBCPP_SGX_CONFIG)
  52. // GNU Extended version
  53. string do_strerror_r(int ev) {
  54. char buffer[strerror_buff_size];
  55. char* ret = ::strerror_r(ev, buffer, strerror_buff_size);
  56. return string(ret);
  57. }
  58. #else
  59. // POSIX version
  60. string do_strerror_r(int ev) {
  61. char buffer[strerror_buff_size];
  62. const int old_errno = errno;
  63. int ret;
  64. if ((ret = ::strerror_r(ev, buffer, strerror_buff_size)) != 0) {
  65. // If `ret == -1` then the error is specified using `errno`, otherwise
  66. // `ret` represents the error.
  67. const int new_errno = ret == -1 ? errno : ret;
  68. errno = old_errno;
  69. if (new_errno == EINVAL) {
  70. std::snprintf(buffer, strerror_buff_size, "Unknown error %d", ev);
  71. return string(buffer);
  72. } else {
  73. assert(new_errno == ERANGE);
  74. // FIXME maybe? 'strerror_buff_size' is likely to exceed the
  75. // maximum error size so ERANGE shouldn't be returned.
  76. std::abort();
  77. }
  78. }
  79. return string(buffer);
  80. }
  81. #endif
  82. } // end namespace
  83. string
  84. __do_message::message(int ev) const
  85. {
  86. #if defined(_LIBCPP_HAS_NO_THREADS)
  87. return string(::strerror(ev));
  88. #else
  89. return do_strerror_r(ev);
  90. #endif
  91. }
  92. class _LIBCPP_HIDDEN __generic_error_category
  93. : public __do_message
  94. {
  95. public:
  96. virtual const char* name() const _NOEXCEPT;
  97. virtual string message(int ev) const;
  98. };
  99. const char*
  100. __generic_error_category::name() const _NOEXCEPT
  101. {
  102. return "generic";
  103. }
  104. string
  105. __generic_error_category::message(int ev) const
  106. {
  107. #ifdef _LIBCPP_ELAST
  108. if (ev > _LIBCPP_ELAST)
  109. return string("unspecified generic_category error");
  110. #endif // _LIBCPP_ELAST
  111. return __do_message::message(ev);
  112. }
  113. const error_category&
  114. generic_category() _NOEXCEPT
  115. {
  116. static __generic_error_category s;
  117. return s;
  118. }
  119. class _LIBCPP_HIDDEN __system_error_category
  120. : public __do_message
  121. {
  122. public:
  123. virtual const char* name() const _NOEXCEPT;
  124. virtual string message(int ev) const;
  125. virtual error_condition default_error_condition(int ev) const _NOEXCEPT;
  126. };
  127. const char*
  128. __system_error_category::name() const _NOEXCEPT
  129. {
  130. return "system";
  131. }
  132. string
  133. __system_error_category::message(int ev) const
  134. {
  135. #ifdef _LIBCPP_ELAST
  136. if (ev > _LIBCPP_ELAST)
  137. return string("unspecified system_category error");
  138. #endif // _LIBCPP_ELAST
  139. return __do_message::message(ev);
  140. }
  141. error_condition
  142. __system_error_category::default_error_condition(int ev) const _NOEXCEPT
  143. {
  144. #ifdef _LIBCPP_ELAST
  145. if (ev > _LIBCPP_ELAST)
  146. return error_condition(ev, system_category());
  147. #endif // _LIBCPP_ELAST
  148. return error_condition(ev, generic_category());
  149. }
  150. const error_category&
  151. system_category() _NOEXCEPT
  152. {
  153. static __system_error_category s;
  154. return s;
  155. }
  156. // error_condition
  157. string
  158. error_condition::message() const
  159. {
  160. return __cat_->message(__val_);
  161. }
  162. // error_code
  163. string
  164. error_code::message() const
  165. {
  166. return __cat_->message(__val_);
  167. }
  168. // system_error
  169. string
  170. system_error::__init(const error_code& ec, string what_arg)
  171. {
  172. if (ec)
  173. {
  174. if (!what_arg.empty())
  175. what_arg += ": ";
  176. what_arg += ec.message();
  177. }
  178. return what_arg;
  179. }
  180. system_error::system_error(error_code ec, const string& what_arg)
  181. : runtime_error(__init(ec, what_arg)),
  182. __ec_(ec)
  183. {
  184. }
  185. system_error::system_error(error_code ec, const char* what_arg)
  186. : runtime_error(__init(ec, what_arg)),
  187. __ec_(ec)
  188. {
  189. }
  190. system_error::system_error(error_code ec)
  191. : runtime_error(__init(ec, "")),
  192. __ec_(ec)
  193. {
  194. }
  195. system_error::system_error(int ev, const error_category& ecat, const string& what_arg)
  196. : runtime_error(__init(error_code(ev, ecat), what_arg)),
  197. __ec_(error_code(ev, ecat))
  198. {
  199. }
  200. system_error::system_error(int ev, const error_category& ecat, const char* what_arg)
  201. : runtime_error(__init(error_code(ev, ecat), what_arg)),
  202. __ec_(error_code(ev, ecat))
  203. {
  204. }
  205. system_error::system_error(int ev, const error_category& ecat)
  206. : runtime_error(__init(error_code(ev, ecat), "")),
  207. __ec_(error_code(ev, ecat))
  208. {
  209. }
  210. system_error::~system_error() _NOEXCEPT
  211. {
  212. }
  213. void
  214. __throw_system_error(int ev, const char* what_arg)
  215. {
  216. #ifndef _LIBCPP_NO_EXCEPTIONS
  217. throw system_error(error_code(ev, system_category()), what_arg);
  218. #else
  219. (void)ev;
  220. (void)what_arg;
  221. #endif
  222. }
  223. _LIBCPP_END_NAMESPACE_STD