Chris@102: // error_code support implementation file ----------------------------------// Chris@102: Chris@102: // Copyright Beman Dawes 2002, 2006 Chris@102: // Copyright (c) Microsoft Corporation 2014 Chris@102: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@102: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: Chris@102: // See library home page at http://www.boost.org/libs/system Chris@102: Chris@102: //----------------------------------------------------------------------------// Chris@102: Chris@102: #include Chris@102: Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: #include Chris@102: Chris@102: #include // for strerror/strerror_r Chris@102: Chris@102: # if defined( BOOST_WINDOWS_API ) Chris@102: # include Chris@102: # if !BOOST_PLAT_WINDOWS_RUNTIME Chris@102: # include Chris@102: # endif Chris@102: # ifndef ERROR_INCORRECT_SIZE Chris@102: # define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS Chris@102: # endif Chris@102: # endif Chris@102: Chris@102: //----------------------------------------------------------------------------// Chris@102: namespace boost Chris@102: { Chris@102: namespace system Chris@102: { Chris@102: Chris@102: namespace Chris@102: { Chris@102: Chris@102: // standard error categories ---------------------------------------------// Chris@102: Chris@102: class generic_error_category : public error_category Chris@102: { Chris@102: public: Chris@102: generic_error_category(){} Chris@102: const char * name() const BOOST_SYSTEM_NOEXCEPT; Chris@102: std::string message( int ev ) const; Chris@102: }; Chris@102: Chris@102: class system_error_category : public error_category Chris@102: { Chris@102: public: Chris@102: system_error_category(){} Chris@102: const char * name() const BOOST_SYSTEM_NOEXCEPT; Chris@102: std::string message( int ev ) const; Chris@102: error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT; Chris@102: }; Chris@102: Chris@102: // generic_error_category implementation ---------------------------------// Chris@102: Chris@102: const char * generic_error_category::name() const BOOST_SYSTEM_NOEXCEPT Chris@102: { Chris@102: return "generic"; Chris@102: } Chris@102: Chris@102: std::string generic_error_category::message( int ev ) const Chris@102: { Chris@102: using namespace boost::system::errc; Chris@102: #if defined(__PGI) Chris@102: using boost::system::errc::invalid_argument; Chris@102: #endif Chris@102: Chris@102: static std::string unknown_err( "Unknown error" ); Chris@102: // strerror_r is preferred because it is always thread safe, Chris@102: // however, we fallback to strerror in certain cases because: Chris@102: // -- Windows doesn't provide strerror_r. Chris@102: // -- HP and Sun do provide strerror_r on newer systems, but there is Chris@102: // no way to tell if is available at runtime and in any case their Chris@102: // versions of strerror are thread safe anyhow. Chris@102: // -- Linux only sometimes provides strerror_r. Chris@102: // -- Tru64 provides strerror_r only when compiled -pthread. Chris@102: // -- VMS doesn't provide strerror_r, but on this platform, strerror is Chris@102: // thread safe. Chris@102: # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\ Chris@102: || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\ Chris@102: || (defined(__osf__) && !defined(_REENTRANT))\ Chris@102: || (defined(__INTEGRITY))\ Chris@102: || (defined(__vms))\ Chris@102: || (defined(__QNXNTO__)) Chris@102: const char * c_str = std::strerror( ev ); Chris@102: return c_str Chris@102: ? std::string( c_str ) Chris@102: : unknown_err; Chris@102: # else // use strerror_r Chris@102: char buf[64]; Chris@102: char * bp = buf; Chris@102: std::size_t sz = sizeof(buf); Chris@102: # if defined(__CYGWIN__) || defined(__USE_GNU) Chris@102: // Oddball version of strerror_r Chris@102: const char * c_str = strerror_r( ev, bp, sz ); Chris@102: return c_str Chris@102: ? std::string( c_str ) Chris@102: : unknown_err; Chris@102: # else Chris@102: // POSIX version of strerror_r Chris@102: int result; Chris@102: for (;;) Chris@102: { Chris@102: // strerror_r returns 0 on success, otherwise ERANGE if buffer too small, Chris@102: // invalid_argument if ev not a valid error number Chris@102: # if defined (__sgi) Chris@102: const char * c_str = strerror( ev ); Chris@102: result = 0; Chris@102: return c_str Chris@102: ? std::string( c_str ) Chris@102: : unknown_err; Chris@102: # else Chris@102: result = strerror_r( ev, bp, sz ); Chris@102: # endif Chris@102: if (result == 0 ) Chris@102: break; Chris@102: else Chris@102: { Chris@102: # if defined(__linux) Chris@102: // Linux strerror_r returns -1 on error, with error number in errno Chris@102: result = errno; Chris@102: # endif Chris@102: if ( result != ERANGE ) break; Chris@102: if ( sz > sizeof(buf) ) std::free( bp ); Chris@102: sz *= 2; Chris@102: if ( (bp = static_cast(std::malloc( sz ))) == 0 ) Chris@102: return std::string( "ENOMEM" ); Chris@102: } Chris@102: } Chris@102: std::string msg; Chris@102: # ifndef BOOST_NO_EXCEPTIONS Chris@102: try Chris@102: # endif Chris@102: { Chris@102: msg = ( ( result == invalid_argument ) ? "Unknown error" : bp ); Chris@102: } Chris@102: Chris@102: # ifndef BOOST_NO_EXCEPTIONS Chris@102: // See ticket #2098 Chris@102: catch(...) Chris@102: { Chris@102: // just eat the exception Chris@102: } Chris@102: # endif Chris@102: Chris@102: if ( sz > sizeof(buf) ) std::free( bp ); Chris@102: sz = 0; Chris@102: return msg; Chris@102: # endif // else POSIX version of strerror_r Chris@102: # endif // else use strerror_r Chris@102: } Chris@102: // system_error_category implementation --------------------------------// Chris@102: Chris@102: const char * system_error_category::name() const BOOST_SYSTEM_NOEXCEPT Chris@102: { Chris@102: return "system"; Chris@102: } Chris@102: Chris@102: error_condition system_error_category::default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT Chris@102: { Chris@102: using namespace boost::system::errc; Chris@102: #if defined(__PGI) Chris@102: using boost::system::errc::invalid_argument; Chris@102: #endif Chris@102: Chris@102: # if defined(BOOST_WINDOWS_API) Chris@102: # if defined(WINAPI_FAMILY) && ((WINAPI_FAMILY & WINAPI_PARTITION_APP) != 0) Chris@102: // When using the Windows Runtime, most system errors are reported as HRESULTs. Chris@102: // We want to map the common Win32 errors to their equivalent error condition, Chris@102: // whether or not they are reported via an HRESULT. Chris@102: if ( ev < 0 ) // Check for failed HRESULTs only. Chris@102: if ( HRESULT_FACILITY( ev ) == FACILITY_WIN32 ) Chris@102: ev = HRESULT_CODE( ev ); Chris@102: # endif Chris@102: # endif Chris@102: Chris@102: switch ( ev ) Chris@102: { Chris@102: case 0: return make_error_condition( success ); Chris@102: # if defined(BOOST_POSIX_API) Chris@102: // POSIX-like O/S -> posix_errno decode table ---------------------------// Chris@102: case E2BIG: return make_error_condition( argument_list_too_long ); Chris@102: case EACCES: return make_error_condition( permission_denied ); Chris@102: case EADDRINUSE: return make_error_condition( address_in_use ); Chris@102: case EADDRNOTAVAIL: return make_error_condition( address_not_available ); Chris@102: case EAFNOSUPPORT: return make_error_condition( address_family_not_supported ); Chris@102: case EAGAIN: return make_error_condition( resource_unavailable_try_again ); Chris@102: # if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino Chris@102: case EALREADY: return make_error_condition( connection_already_in_progress ); Chris@102: # endif Chris@102: case EBADF: return make_error_condition( bad_file_descriptor ); Chris@102: case EBADMSG: return make_error_condition( bad_message ); Chris@102: case EBUSY: return make_error_condition( device_or_resource_busy ); Chris@102: case ECANCELED: return make_error_condition( operation_canceled ); Chris@102: case ECHILD: return make_error_condition( no_child_process ); Chris@102: case ECONNABORTED: return make_error_condition( connection_aborted ); Chris@102: case ECONNREFUSED: return make_error_condition( connection_refused ); Chris@102: case ECONNRESET: return make_error_condition( connection_reset ); Chris@102: case EDEADLK: return make_error_condition( resource_deadlock_would_occur ); Chris@102: case EDESTADDRREQ: return make_error_condition( destination_address_required ); Chris@102: case EDOM: return make_error_condition( argument_out_of_domain ); Chris@102: case EEXIST: return make_error_condition( file_exists ); Chris@102: case EFAULT: return make_error_condition( bad_address ); Chris@102: case EFBIG: return make_error_condition( file_too_large ); Chris@102: case EHOSTUNREACH: return make_error_condition( host_unreachable ); Chris@102: case EIDRM: return make_error_condition( identifier_removed ); Chris@102: case EILSEQ: return make_error_condition( illegal_byte_sequence ); Chris@102: case EINPROGRESS: return make_error_condition( operation_in_progress ); Chris@102: case EINTR: return make_error_condition( interrupted ); Chris@102: case EINVAL: return make_error_condition( invalid_argument ); Chris@102: case EIO: return make_error_condition( io_error ); Chris@102: case EISCONN: return make_error_condition( already_connected ); Chris@102: case EISDIR: return make_error_condition( is_a_directory ); Chris@102: case ELOOP: return make_error_condition( too_many_symbolic_link_levels ); Chris@102: case EMFILE: return make_error_condition( too_many_files_open ); Chris@102: case EMLINK: return make_error_condition( too_many_links ); Chris@102: case EMSGSIZE: return make_error_condition( message_size ); Chris@102: case ENAMETOOLONG: return make_error_condition( filename_too_long ); Chris@102: case ENETDOWN: return make_error_condition( network_down ); Chris@102: case ENETRESET: return make_error_condition( network_reset ); Chris@102: case ENETUNREACH: return make_error_condition( network_unreachable ); Chris@102: case ENFILE: return make_error_condition( too_many_files_open_in_system ); Chris@102: case ENOBUFS: return make_error_condition( no_buffer_space ); Chris@102: case ENODATA: return make_error_condition( no_message_available ); Chris@102: case ENODEV: return make_error_condition( no_such_device ); Chris@102: case ENOENT: return make_error_condition( no_such_file_or_directory ); Chris@102: case ENOEXEC: return make_error_condition( executable_format_error ); Chris@102: case ENOLCK: return make_error_condition( no_lock_available ); Chris@102: case ENOLINK: return make_error_condition( no_link ); Chris@102: case ENOMEM: return make_error_condition( not_enough_memory ); Chris@102: case ENOMSG: return make_error_condition( no_message ); Chris@102: case ENOPROTOOPT: return make_error_condition( no_protocol_option ); Chris@102: case ENOSPC: return make_error_condition( no_space_on_device ); Chris@102: case ENOSR: return make_error_condition( no_stream_resources ); Chris@102: case ENOSTR: return make_error_condition( not_a_stream ); Chris@102: case ENOSYS: return make_error_condition( function_not_supported ); Chris@102: case ENOTCONN: return make_error_condition( not_connected ); Chris@102: case ENOTDIR: return make_error_condition( not_a_directory ); Chris@102: # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value Chris@102: case ENOTEMPTY: return make_error_condition( directory_not_empty ); Chris@102: # endif // ENOTEMPTY != EEXIST Chris@102: # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips Chris@102: case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); Chris@102: # endif // ENOTRECOVERABLE != ECONNRESET Chris@102: case ENOTSOCK: return make_error_condition( not_a_socket ); Chris@102: case ENOTSUP: return make_error_condition( not_supported ); Chris@102: case ENOTTY: return make_error_condition( inappropriate_io_control_operation ); Chris@102: case ENXIO: return make_error_condition( no_such_device_or_address ); Chris@102: # if EOPNOTSUPP != ENOTSUP Chris@102: case EOPNOTSUPP: return make_error_condition( operation_not_supported ); Chris@102: # endif // EOPNOTSUPP != ENOTSUP Chris@102: case EOVERFLOW: return make_error_condition( value_too_large ); Chris@102: # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips Chris@102: case EOWNERDEAD: return make_error_condition( owner_dead ); Chris@102: # endif // EOWNERDEAD != ECONNABORTED Chris@102: case EPERM: return make_error_condition( operation_not_permitted ); Chris@102: case EPIPE: return make_error_condition( broken_pipe ); Chris@102: case EPROTO: return make_error_condition( protocol_error ); Chris@102: case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); Chris@102: case EPROTOTYPE: return make_error_condition( wrong_protocol_type ); Chris@102: case ERANGE: return make_error_condition( result_out_of_range ); Chris@102: case EROFS: return make_error_condition( read_only_file_system ); Chris@102: case ESPIPE: return make_error_condition( invalid_seek ); Chris@102: case ESRCH: return make_error_condition( no_such_process ); Chris@102: case ETIME: return make_error_condition( stream_timeout ); Chris@102: case ETIMEDOUT: return make_error_condition( timed_out ); Chris@102: case ETXTBSY: return make_error_condition( text_file_busy ); Chris@102: # if EAGAIN != EWOULDBLOCK Chris@102: case EWOULDBLOCK: return make_error_condition( operation_would_block ); Chris@102: # endif // EAGAIN != EWOULDBLOCK Chris@102: case EXDEV: return make_error_condition( cross_device_link ); Chris@102: #else Chris@102: // Windows system -> posix_errno decode table ---------------------------// Chris@102: // see WinError.h comments for descriptions of errors Chris@102: case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied ); Chris@102: case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists ); Chris@102: case ERROR_BAD_UNIT: return make_error_condition( no_such_device ); Chris@102: case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long ); Chris@102: case ERROR_BUSY: return make_error_condition( device_or_resource_busy ); Chris@102: case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy ); Chris@102: case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied ); Chris@102: case ERROR_CANTOPEN: return make_error_condition( io_error ); Chris@102: case ERROR_CANTREAD: return make_error_condition( io_error ); Chris@102: case ERROR_CANTWRITE: return make_error_condition( io_error ); Chris@102: case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied ); Chris@102: case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device ); Chris@102: case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy ); Chris@102: case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty ); Chris@102: case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid" Chris@102: case ERROR_DISK_FULL: return make_error_condition( no_space_on_device ); Chris@102: case ERROR_FILE_EXISTS: return make_error_condition( file_exists ); Chris@102: case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); Chris@102: case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device ); Chris@102: case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied ); Chris@102: case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device ); Chris@102: case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported ); Chris@102: case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument ); Chris@102: case ERROR_INVALID_NAME: return make_error_condition( invalid_argument ); Chris@102: case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available ); Chris@102: case ERROR_LOCKED: return make_error_condition( no_lock_available ); Chris@102: case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument ); Chris@102: case ERROR_NOACCESS: return make_error_condition( permission_denied ); Chris@102: case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory ); Chris@102: case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again ); Chris@102: case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link ); Chris@102: case ERROR_OPEN_FAILED: return make_error_condition( io_error ); Chris@102: case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy ); Chris@102: case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled ); Chris@102: case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory ); Chris@102: case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory ); Chris@102: case ERROR_READ_FAULT: return make_error_condition( io_error ); Chris@102: case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again ); Chris@102: case ERROR_SEEK: return make_error_condition( io_error ); Chris@102: case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied ); Chris@102: case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open ); Chris@102: case ERROR_WRITE_FAULT: return make_error_condition( io_error ); Chris@102: case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied ); Chris@102: case WSAEACCES: return make_error_condition( permission_denied ); Chris@102: case WSAEADDRINUSE: return make_error_condition( address_in_use ); Chris@102: case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available ); Chris@102: case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported ); Chris@102: case WSAEALREADY: return make_error_condition( connection_already_in_progress ); Chris@102: case WSAEBADF: return make_error_condition( bad_file_descriptor ); Chris@102: case WSAECONNABORTED: return make_error_condition( connection_aborted ); Chris@102: case WSAECONNREFUSED: return make_error_condition( connection_refused ); Chris@102: case WSAECONNRESET: return make_error_condition( connection_reset ); Chris@102: case WSAEDESTADDRREQ: return make_error_condition( destination_address_required ); Chris@102: case WSAEFAULT: return make_error_condition( bad_address ); Chris@102: case WSAEHOSTUNREACH: return make_error_condition( host_unreachable ); Chris@102: case WSAEINPROGRESS: return make_error_condition( operation_in_progress ); Chris@102: case WSAEINTR: return make_error_condition( interrupted ); Chris@102: case WSAEINVAL: return make_error_condition( invalid_argument ); Chris@102: case WSAEISCONN: return make_error_condition( already_connected ); Chris@102: case WSAEMFILE: return make_error_condition( too_many_files_open ); Chris@102: case WSAEMSGSIZE: return make_error_condition( message_size ); Chris@102: case WSAENAMETOOLONG: return make_error_condition( filename_too_long ); Chris@102: case WSAENETDOWN: return make_error_condition( network_down ); Chris@102: case WSAENETRESET: return make_error_condition( network_reset ); Chris@102: case WSAENETUNREACH: return make_error_condition( network_unreachable ); Chris@102: case WSAENOBUFS: return make_error_condition( no_buffer_space ); Chris@102: case WSAENOPROTOOPT: return make_error_condition( no_protocol_option ); Chris@102: case WSAENOTCONN: return make_error_condition( not_connected ); Chris@102: case WSAENOTSOCK: return make_error_condition( not_a_socket ); Chris@102: case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported ); Chris@102: case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); Chris@102: case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type ); Chris@102: case WSAETIMEDOUT: return make_error_condition( timed_out ); Chris@102: case WSAEWOULDBLOCK: return make_error_condition( operation_would_block ); Chris@102: #endif Chris@102: default: return error_condition( ev, system_category() ); Chris@102: } Chris@102: } Chris@102: Chris@102: # if !defined( BOOST_WINDOWS_API ) Chris@102: Chris@102: std::string system_error_category::message( int ev ) const Chris@102: { Chris@102: return generic_category().message( ev ); Chris@102: } Chris@102: # else Chris@102: Chris@102: std::string system_error_category::message( int ev ) const Chris@102: { Chris@102: #if defined(UNDER_CE) || BOOST_PLAT_WINDOWS_RUNTIME || defined(BOOST_NO_ANSI_APIS) Chris@102: std::wstring buf(128, wchar_t()); Chris@102: for (;;) Chris@102: { Chris@102: DWORD retval = ::FormatMessageW( Chris@102: FORMAT_MESSAGE_FROM_SYSTEM | Chris@102: FORMAT_MESSAGE_IGNORE_INSERTS, Chris@102: NULL, Chris@102: ev, Chris@102: MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language Chris@102: &buf[0], Chris@102: buf.size(), Chris@102: NULL Chris@102: ); Chris@102: Chris@102: if (retval > 0) Chris@102: { Chris@102: buf.resize(retval); Chris@102: break; Chris@102: } Chris@102: else if ( ::GetLastError() != ERROR_INSUFFICIENT_BUFFER ) Chris@102: { Chris@102: return std::string("Unknown error"); Chris@102: } Chris@102: else Chris@102: { Chris@102: buf.resize(buf.size() + buf.size() / 2); Chris@102: } Chris@102: } Chris@102: Chris@102: int num_chars = (buf.size() + 1) * 2; Chris@102: LPSTR narrow_buffer = (LPSTR)_alloca( num_chars ); Chris@102: if (::WideCharToMultiByte(CP_ACP, 0, buf.c_str(), -1, narrow_buffer, num_chars, NULL, NULL) == 0) Chris@102: { Chris@102: return std::string("Unknown error"); Chris@102: } Chris@102: Chris@102: std::string str( narrow_buffer ); Chris@102: #else Chris@102: LPVOID lpMsgBuf = 0; Chris@102: DWORD retval = ::FormatMessageA( Chris@102: FORMAT_MESSAGE_ALLOCATE_BUFFER | Chris@102: FORMAT_MESSAGE_FROM_SYSTEM | Chris@102: FORMAT_MESSAGE_IGNORE_INSERTS, Chris@102: NULL, Chris@102: ev, Chris@102: MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language Chris@102: (LPSTR) &lpMsgBuf, Chris@102: 0, Chris@102: NULL Chris@102: ); Chris@102: detail::local_free_on_destruction lfod(lpMsgBuf); Chris@102: if (retval == 0) Chris@102: return std::string("Unknown error"); Chris@102: Chris@102: std::string str( static_cast(lpMsgBuf) ); Chris@102: # endif Chris@102: while ( str.size() Chris@102: && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) Chris@102: str.erase( str.size()-1 ); Chris@102: if ( str.size() && str[str.size()-1] == '.' ) Chris@102: { str.erase( str.size()-1 ); } Chris@102: return str; Chris@102: } Chris@102: # endif Chris@102: Chris@102: } // unnamed namespace Chris@102: Chris@102: Chris@102: # ifndef BOOST_SYSTEM_NO_DEPRECATED Chris@102: BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code; Chris@102: // note that it doesn't matter if this Chris@102: // isn't initialized before use since Chris@102: // the only use is to take its Chris@102: // address for comparison purposes Chris@102: # endif Chris@102: Chris@102: # ifdef BOOST_ERROR_CODE_HEADER_ONLY Chris@102: # define BOOST_SYSTEM_LINKAGE inline Chris@102: # else Chris@102: # define BOOST_SYSTEM_LINKAGE BOOST_SYSTEM_DECL Chris@102: # endif Chris@102: Chris@102: BOOST_SYSTEM_LINKAGE const error_category & system_category() BOOST_SYSTEM_NOEXCEPT Chris@102: { Chris@102: static const system_error_category system_category_const; Chris@102: return system_category_const; Chris@102: } Chris@102: Chris@102: BOOST_SYSTEM_LINKAGE const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT Chris@102: { Chris@102: static const generic_error_category generic_category_const; Chris@102: return generic_category_const; Chris@102: } Chris@102: Chris@102: } // namespace system Chris@102: } // namespace boost