1*46035553Spatrick //===---------------------- system_error.cpp ------------------------------===// 2*46035553Spatrick // 3*46035553Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*46035553Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*46035553Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*46035553Spatrick // 7*46035553Spatrick //===----------------------------------------------------------------------===// 8*46035553Spatrick 9*46035553Spatrick #include "__config" 10*46035553Spatrick 11*46035553Spatrick #include "system_error" 12*46035553Spatrick 13*46035553Spatrick #include "include/config_elast.h" 14*46035553Spatrick #include "cerrno" 15*46035553Spatrick #include "cstring" 16*46035553Spatrick #include "cstdio" 17*46035553Spatrick #include "cstdlib" 18*46035553Spatrick #include "string" 19*46035553Spatrick #include "string.h" 20*46035553Spatrick #include "__debug" 21*46035553Spatrick 22*46035553Spatrick #if defined(__ANDROID__) 23*46035553Spatrick #include <android/api-level.h> 24*46035553Spatrick #endif 25*46035553Spatrick 26*46035553Spatrick _LIBCPP_BEGIN_NAMESPACE_STD 27*46035553Spatrick 28*46035553Spatrick // class error_category 29*46035553Spatrick 30*46035553Spatrick #if defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) 31*46035553Spatrick error_category::error_category() _NOEXCEPT 32*46035553Spatrick { 33*46035553Spatrick } 34*46035553Spatrick #endif 35*46035553Spatrick 36*46035553Spatrick error_category::~error_category() _NOEXCEPT 37*46035553Spatrick { 38*46035553Spatrick } 39*46035553Spatrick 40*46035553Spatrick error_condition 41*46035553Spatrick error_category::default_error_condition(int ev) const _NOEXCEPT 42*46035553Spatrick { 43*46035553Spatrick return error_condition(ev, *this); 44*46035553Spatrick } 45*46035553Spatrick 46*46035553Spatrick bool 47*46035553Spatrick error_category::equivalent(int code, const error_condition& condition) const _NOEXCEPT 48*46035553Spatrick { 49*46035553Spatrick return default_error_condition(code) == condition; 50*46035553Spatrick } 51*46035553Spatrick 52*46035553Spatrick bool 53*46035553Spatrick error_category::equivalent(const error_code& code, int condition) const _NOEXCEPT 54*46035553Spatrick { 55*46035553Spatrick return *this == code.category() && code.value() == condition; 56*46035553Spatrick } 57*46035553Spatrick 58*46035553Spatrick #if !defined(_LIBCPP_HAS_NO_THREADS) 59*46035553Spatrick namespace { 60*46035553Spatrick 61*46035553Spatrick // GLIBC also uses 1024 as the maximum buffer size internally. 62*46035553Spatrick constexpr size_t strerror_buff_size = 1024; 63*46035553Spatrick 64*46035553Spatrick string do_strerror_r(int ev); 65*46035553Spatrick 66*46035553Spatrick #if defined(_LIBCPP_MSVCRT_LIKE) 67*46035553Spatrick string do_strerror_r(int ev) { 68*46035553Spatrick char buffer[strerror_buff_size]; 69*46035553Spatrick if (::strerror_s(buffer, strerror_buff_size, ev) == 0) 70*46035553Spatrick return string(buffer); 71*46035553Spatrick std::snprintf(buffer, strerror_buff_size, "unknown error %d", ev); 72*46035553Spatrick return string(buffer); 73*46035553Spatrick } 74*46035553Spatrick #else 75*46035553Spatrick 76*46035553Spatrick // Only one of the two following functions will be used, depending on 77*46035553Spatrick // the return type of strerror_r: 78*46035553Spatrick 79*46035553Spatrick // For the GNU variant, a char* return value: 80*46035553Spatrick __attribute__((unused)) const char * 81*46035553Spatrick handle_strerror_r_return(char *strerror_return, char *buffer) { 82*46035553Spatrick // GNU always returns a string pointer in its return value. The 83*46035553Spatrick // string might point to either the input buffer, or a static 84*46035553Spatrick // buffer, but we don't care which. 85*46035553Spatrick return strerror_return; 86*46035553Spatrick } 87*46035553Spatrick 88*46035553Spatrick // For the POSIX variant: an int return value. 89*46035553Spatrick __attribute__((unused)) const char * 90*46035553Spatrick handle_strerror_r_return(int strerror_return, char *buffer) { 91*46035553Spatrick // The POSIX variant either: 92*46035553Spatrick // - fills in the provided buffer and returns 0 93*46035553Spatrick // - returns a positive error value, or 94*46035553Spatrick // - returns -1 and fills in errno with an error value. 95*46035553Spatrick if (strerror_return == 0) 96*46035553Spatrick return buffer; 97*46035553Spatrick 98*46035553Spatrick // Only handle EINVAL. Other errors abort. 99*46035553Spatrick int new_errno = strerror_return == -1 ? errno : strerror_return; 100*46035553Spatrick if (new_errno == EINVAL) 101*46035553Spatrick return ""; 102*46035553Spatrick 103*46035553Spatrick _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerror_r"); 104*46035553Spatrick // FIXME maybe? 'strerror_buff_size' is likely to exceed the 105*46035553Spatrick // maximum error size so ERANGE shouldn't be returned. 106*46035553Spatrick std::abort(); 107*46035553Spatrick } 108*46035553Spatrick 109*46035553Spatrick // This function handles both GNU and POSIX variants, dispatching to 110*46035553Spatrick // one of the two above functions. 111*46035553Spatrick string do_strerror_r(int ev) { 112*46035553Spatrick char buffer[strerror_buff_size]; 113*46035553Spatrick // Preserve errno around the call. (The C++ standard requires that 114*46035553Spatrick // system_error functions not modify errno). 115*46035553Spatrick const int old_errno = errno; 116*46035553Spatrick const char *error_message = handle_strerror_r_return( 117*46035553Spatrick ::strerror_r(ev, buffer, strerror_buff_size), buffer); 118*46035553Spatrick // If we didn't get any message, print one now. 119*46035553Spatrick if (!error_message[0]) { 120*46035553Spatrick std::snprintf(buffer, strerror_buff_size, "Unknown error %d", ev); 121*46035553Spatrick error_message = buffer; 122*46035553Spatrick } 123*46035553Spatrick errno = old_errno; 124*46035553Spatrick return string(error_message); 125*46035553Spatrick } 126*46035553Spatrick #endif 127*46035553Spatrick } // end namespace 128*46035553Spatrick #endif 129*46035553Spatrick 130*46035553Spatrick string 131*46035553Spatrick __do_message::message(int ev) const 132*46035553Spatrick { 133*46035553Spatrick #if defined(_LIBCPP_HAS_NO_THREADS) 134*46035553Spatrick return string(::strerror(ev)); 135*46035553Spatrick #else 136*46035553Spatrick return do_strerror_r(ev); 137*46035553Spatrick #endif 138*46035553Spatrick } 139*46035553Spatrick 140*46035553Spatrick class _LIBCPP_HIDDEN __generic_error_category 141*46035553Spatrick : public __do_message 142*46035553Spatrick { 143*46035553Spatrick public: 144*46035553Spatrick virtual const char* name() const _NOEXCEPT; 145*46035553Spatrick virtual string message(int ev) const; 146*46035553Spatrick }; 147*46035553Spatrick 148*46035553Spatrick const char* 149*46035553Spatrick __generic_error_category::name() const _NOEXCEPT 150*46035553Spatrick { 151*46035553Spatrick return "generic"; 152*46035553Spatrick } 153*46035553Spatrick 154*46035553Spatrick string 155*46035553Spatrick __generic_error_category::message(int ev) const 156*46035553Spatrick { 157*46035553Spatrick #ifdef _LIBCPP_ELAST 158*46035553Spatrick if (ev > _LIBCPP_ELAST) 159*46035553Spatrick return string("unspecified generic_category error"); 160*46035553Spatrick #endif // _LIBCPP_ELAST 161*46035553Spatrick return __do_message::message(ev); 162*46035553Spatrick } 163*46035553Spatrick 164*46035553Spatrick const error_category& 165*46035553Spatrick generic_category() _NOEXCEPT 166*46035553Spatrick { 167*46035553Spatrick static __generic_error_category s; 168*46035553Spatrick return s; 169*46035553Spatrick } 170*46035553Spatrick 171*46035553Spatrick class _LIBCPP_HIDDEN __system_error_category 172*46035553Spatrick : public __do_message 173*46035553Spatrick { 174*46035553Spatrick public: 175*46035553Spatrick virtual const char* name() const _NOEXCEPT; 176*46035553Spatrick virtual string message(int ev) const; 177*46035553Spatrick virtual error_condition default_error_condition(int ev) const _NOEXCEPT; 178*46035553Spatrick }; 179*46035553Spatrick 180*46035553Spatrick const char* 181*46035553Spatrick __system_error_category::name() const _NOEXCEPT 182*46035553Spatrick { 183*46035553Spatrick return "system"; 184*46035553Spatrick } 185*46035553Spatrick 186*46035553Spatrick string 187*46035553Spatrick __system_error_category::message(int ev) const 188*46035553Spatrick { 189*46035553Spatrick #ifdef _LIBCPP_ELAST 190*46035553Spatrick if (ev > _LIBCPP_ELAST) 191*46035553Spatrick return string("unspecified system_category error"); 192*46035553Spatrick #endif // _LIBCPP_ELAST 193*46035553Spatrick return __do_message::message(ev); 194*46035553Spatrick } 195*46035553Spatrick 196*46035553Spatrick error_condition 197*46035553Spatrick __system_error_category::default_error_condition(int ev) const _NOEXCEPT 198*46035553Spatrick { 199*46035553Spatrick #ifdef _LIBCPP_ELAST 200*46035553Spatrick if (ev > _LIBCPP_ELAST) 201*46035553Spatrick return error_condition(ev, system_category()); 202*46035553Spatrick #endif // _LIBCPP_ELAST 203*46035553Spatrick return error_condition(ev, generic_category()); 204*46035553Spatrick } 205*46035553Spatrick 206*46035553Spatrick const error_category& 207*46035553Spatrick system_category() _NOEXCEPT 208*46035553Spatrick { 209*46035553Spatrick static __system_error_category s; 210*46035553Spatrick return s; 211*46035553Spatrick } 212*46035553Spatrick 213*46035553Spatrick // error_condition 214*46035553Spatrick 215*46035553Spatrick string 216*46035553Spatrick error_condition::message() const 217*46035553Spatrick { 218*46035553Spatrick return __cat_->message(__val_); 219*46035553Spatrick } 220*46035553Spatrick 221*46035553Spatrick // error_code 222*46035553Spatrick 223*46035553Spatrick string 224*46035553Spatrick error_code::message() const 225*46035553Spatrick { 226*46035553Spatrick return __cat_->message(__val_); 227*46035553Spatrick } 228*46035553Spatrick 229*46035553Spatrick // system_error 230*46035553Spatrick 231*46035553Spatrick string 232*46035553Spatrick system_error::__init(const error_code& ec, string what_arg) 233*46035553Spatrick { 234*46035553Spatrick if (ec) 235*46035553Spatrick { 236*46035553Spatrick if (!what_arg.empty()) 237*46035553Spatrick what_arg += ": "; 238*46035553Spatrick what_arg += ec.message(); 239*46035553Spatrick } 240*46035553Spatrick return what_arg; 241*46035553Spatrick } 242*46035553Spatrick 243*46035553Spatrick system_error::system_error(error_code ec, const string& what_arg) 244*46035553Spatrick : runtime_error(__init(ec, what_arg)), 245*46035553Spatrick __ec_(ec) 246*46035553Spatrick { 247*46035553Spatrick } 248*46035553Spatrick 249*46035553Spatrick system_error::system_error(error_code ec, const char* what_arg) 250*46035553Spatrick : runtime_error(__init(ec, what_arg)), 251*46035553Spatrick __ec_(ec) 252*46035553Spatrick { 253*46035553Spatrick } 254*46035553Spatrick 255*46035553Spatrick system_error::system_error(error_code ec) 256*46035553Spatrick : runtime_error(__init(ec, "")), 257*46035553Spatrick __ec_(ec) 258*46035553Spatrick { 259*46035553Spatrick } 260*46035553Spatrick 261*46035553Spatrick system_error::system_error(int ev, const error_category& ecat, const string& what_arg) 262*46035553Spatrick : runtime_error(__init(error_code(ev, ecat), what_arg)), 263*46035553Spatrick __ec_(error_code(ev, ecat)) 264*46035553Spatrick { 265*46035553Spatrick } 266*46035553Spatrick 267*46035553Spatrick system_error::system_error(int ev, const error_category& ecat, const char* what_arg) 268*46035553Spatrick : runtime_error(__init(error_code(ev, ecat), what_arg)), 269*46035553Spatrick __ec_(error_code(ev, ecat)) 270*46035553Spatrick { 271*46035553Spatrick } 272*46035553Spatrick 273*46035553Spatrick system_error::system_error(int ev, const error_category& ecat) 274*46035553Spatrick : runtime_error(__init(error_code(ev, ecat), "")), 275*46035553Spatrick __ec_(error_code(ev, ecat)) 276*46035553Spatrick { 277*46035553Spatrick } 278*46035553Spatrick 279*46035553Spatrick system_error::~system_error() _NOEXCEPT 280*46035553Spatrick { 281*46035553Spatrick } 282*46035553Spatrick 283*46035553Spatrick void 284*46035553Spatrick __throw_system_error(int ev, const char* what_arg) 285*46035553Spatrick { 286*46035553Spatrick #ifndef _LIBCPP_NO_EXCEPTIONS 287*46035553Spatrick throw system_error(error_code(ev, system_category()), what_arg); 288*46035553Spatrick #else 289*46035553Spatrick (void)ev; 290*46035553Spatrick (void)what_arg; 291*46035553Spatrick _VSTD::abort(); 292*46035553Spatrick #endif 293*46035553Spatrick } 294*46035553Spatrick 295*46035553Spatrick _LIBCPP_END_NAMESPACE_STD 296