| 1 | // error_code support implementation file ----------------------------------// |
| 2 | |
| 3 | // Copyright Beman Dawes 2002, 2006 |
| 4 | |
| 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 7 | |
| 8 | // See library home page at http://www.boost.org/libs/system |
| 9 | |
| 10 | //----------------------------------------------------------------------------// |
| 11 | |
| 12 | #ifndef BOOST_SYSTEM_DETAIL_INLINED_ERROR_CODE_HPP |
| 13 | #define BOOST_SYSTEM_DETAIL_INLINED_ERROR_CODE_HPP |
| 14 | |
| 15 | #include <boost/config/warning_disable.hpp> |
| 16 | |
| 17 | #include <boost/system/config.hpp> |
| 18 | #ifndef BOOST_SYSTEM_INLINED |
| 19 | #include <boost/system/error_code.hpp> |
| 20 | #endif |
| 21 | #include <boost/cerrno.hpp> |
| 22 | #include <vector> |
| 23 | #include <cstdlib> |
| 24 | #include <cassert> |
| 25 | |
| 26 | //using namespace boost::system; |
| 27 | //using namespace boost::system::errc; |
| 28 | |
| 29 | #include <cstring> // for strerror/strerror_r |
| 30 | |
| 31 | # if defined( BOOST_SYSTEM_WINDOWS_API ) |
| 32 | # include <boost/detail/win/error_handling.hpp> |
| 33 | # include "local_free_on_destruction.hpp" |
| 34 | # ifndef ERROR_INCORRECT_SIZE |
| 35 | # define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS |
| 36 | # endif |
| 37 | # endif |
| 38 | |
| 39 | //----------------------------------------------------------------------------// |
| 40 | |
| 41 | namespace boost |
| 42 | { |
| 43 | namespace system |
| 44 | { |
| 45 | namespace system_detail |
| 46 | { |
| 47 | #if defined(__PGI) |
| 48 | using boost::system::errc::invalid_argument; |
| 49 | #endif |
| 50 | // standard error categories ---------------------------------------------// |
| 51 | |
| 52 | class generic_error_category : public error_category |
| 53 | { |
| 54 | public: |
| 55 | generic_error_category(){} |
| 56 | BOOST_SYSTEM_INLINE const char * name() const; |
| 57 | BOOST_SYSTEM_INLINE std::string message( int ev ) const; |
| 58 | }; |
| 59 | |
| 60 | class system_error_category : public error_category |
| 61 | { |
| 62 | public: |
| 63 | system_error_category(){} |
| 64 | BOOST_SYSTEM_INLINE const char * name() const; |
| 65 | BOOST_SYSTEM_INLINE std::string message( int ev ) const; |
| 66 | BOOST_SYSTEM_INLINE error_condition default_error_condition( int ev ) const; |
| 67 | }; |
| 68 | |
| 69 | // generic_error_category implementation ---------------------------------// |
| 70 | |
| 71 | const char * generic_error_category::name() const |
| 72 | { |
| 73 | return "generic"; |
| 74 | } |
| 75 | |
| 76 | std::string generic_error_category::message( int ev ) const |
| 77 | { |
| 78 | static std::string unknown_err( "Unknown error" ); |
| 79 | // strerror_r is preferred because it is always thread safe, |
| 80 | // however, we fallback to strerror in certain cases because: |
| 81 | // -- Windows doesn't provide strerror_r. |
| 82 | // -- HP and Sun do provide strerror_r on newer systems, but there is |
| 83 | // no way to tell if is available at runtime and in any case their |
| 84 | // versions of strerror are thread safe anyhow. |
| 85 | // -- Linux only sometimes provides strerror_r. |
| 86 | // -- Tru64 provides strerror_r only when compiled -pthread. |
| 87 | // -- VMS doesn't provide strerror_r, but on this platform, strerror is |
| 88 | // thread safe. |
| 89 | # if defined(BOOST_SYSTEM_WINDOWS_API) || defined(__hpux) || defined(__sun)\ |
| 90 | || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\ |
| 91 | || (defined(__osf__) && !defined(_REENTRANT))\ |
| 92 | || (defined(__INTEGRITY))\ |
| 93 | || (defined(__vms))\ |
| 94 | || (defined(__QNXNTO__)) |
| 95 | const char * c_str = std::strerror( ev ); |
| 96 | return c_str |
| 97 | ? std::string( c_str ) |
| 98 | : unknown_err; |
| 99 | # else // use strerror_r |
| 100 | char buf[64]; |
| 101 | char * bp = buf; |
| 102 | std::size_t sz = sizeof(buf); |
| 103 | # if defined(__CYGWIN__) || defined(__USE_GNU) |
| 104 | // Oddball version of strerror_r |
| 105 | const char * c_str = strerror_r( ev, bp, sz ); |
| 106 | return c_str |
| 107 | ? std::string( c_str ) |
| 108 | : unknown_err; |
| 109 | # else |
| 110 | // POSIX version of strerror_r |
| 111 | int result; |
| 112 | for (;;) |
| 113 | { |
| 114 | // strerror_r returns 0 on success, otherwise ERANGE if buffer too small, |
| 115 | // invalid_argument if ev not a valid error number |
| 116 | # if defined (__sgi) |
| 117 | const char * c_str = strerror( ev ); |
| 118 | result = 0; |
| 119 | return c_str |
| 120 | ? std::string( c_str ) |
| 121 | : unknown_err; |
| 122 | # else |
| 123 | result = strerror_r( ev, bp, sz ); |
| 124 | # endif |
| 125 | if (result == 0 ) |
| 126 | break; |
| 127 | else |
| 128 | { |
| 129 | # if defined(__linux) |
| 130 | // Linux strerror_r returns -1 on error, with error number in errno |
| 131 | result = errno; |
| 132 | # endif |
| 133 | if ( result != ERANGE ) break; |
| 134 | if ( sz > sizeof(buf) ) std::free( bp ); |
| 135 | sz *= 2; |
| 136 | if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 ) |
| 137 | return std::string( "ENOMEM" ); |
| 138 | } |
| 139 | } |
| 140 | std::string msg; |
| 141 | try |
| 142 | { |
| 143 | msg = ( ( result == invalid_argument ) ? "Unknown error" : bp ); |
| 144 | } |
| 145 | |
| 146 | # ifndef BOOST_NO_EXCEPTIONS |
| 147 | // See ticket #2098 |
| 148 | catch(...) |
| 149 | { |
| 150 | // just eat the exception |
| 151 | } |
| 152 | # endif |
| 153 | |
| 154 | if ( sz > sizeof(buf) ) std::free( bp ); |
| 155 | sz = 0; |
| 156 | return msg; |
| 157 | # endif // else POSIX version of strerror_r |
| 158 | # endif // else use strerror_r |
| 159 | } |
| 160 | // system_error_category implementation --------------------------------// |
| 161 | |
| 162 | const char * system_error_category::name() const |
| 163 | { |
| 164 | return "system"; |
| 165 | } |
| 166 | |
| 167 | error_condition system_error_category::default_error_condition( int ev ) const |
| 168 | { |
| 169 | switch ( ev ) |
| 170 | { |
| 171 | case 0: return make_error_condition( errc::success ); |
| 172 | # if defined(BOOST_SYSTEM_POSIX_API) |
| 173 | // POSIX-like O/S -> posix_errno decode table ---------------------------// |
| 174 | case E2BIG: return make_error_condition( errc::argument_list_too_long ); |
| 175 | case EACCES: return make_error_condition( errc::permission_denied ); |
| 176 | case EADDRINUSE: return make_error_condition( errc::address_in_use ); |
| 177 | case EADDRNOTAVAIL: return make_error_condition( errc::address_not_available ); |
| 178 | case EAFNOSUPPORT: return make_error_condition( errc::address_family_not_supported ); |
| 179 | case EAGAIN: return make_error_condition( errc::resource_unavailable_try_again ); |
| 180 | # if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino |
| 181 | case EALREADY: return make_error_condition( errc::connection_already_in_progress ); |
| 182 | # endif |
| 183 | case EBADF: return make_error_condition( errc::bad_file_descriptor ); |
| 184 | case EBADMSG: return make_error_condition( errc::bad_message ); |
| 185 | case EBUSY: return make_error_condition( errc::device_or_resource_busy ); |
| 186 | case ECANCELED: return make_error_condition( errc::operation_canceled ); |
| 187 | case ECHILD: return make_error_condition( errc::no_child_process ); |
| 188 | case ECONNABORTED: return make_error_condition( errc::connection_aborted ); |
| 189 | case ECONNREFUSED: return make_error_condition( errc::connection_refused ); |
| 190 | case ECONNRESET: return make_error_condition( errc::connection_reset ); |
| 191 | case EDEADLK: return make_error_condition( errc::resource_deadlock_would_occur ); |
| 192 | case EDESTADDRREQ: return make_error_condition( errc::destination_address_required ); |
| 193 | case EDOM: return make_error_condition( errc::argument_out_of_domain ); |
| 194 | case EEXIST: return make_error_condition( errc::file_exists ); |
| 195 | case EFAULT: return make_error_condition( errc::bad_address ); |
| 196 | case EFBIG: return make_error_condition( errc::file_too_large ); |
| 197 | case EHOSTUNREACH: return make_error_condition( errc::host_unreachable ); |
| 198 | case EIDRM: return make_error_condition( errc::identifier_removed ); |
| 199 | case EILSEQ: return make_error_condition( errc::illegal_byte_sequence ); |
| 200 | case EINPROGRESS: return make_error_condition( errc::operation_in_progress ); |
| 201 | case EINTR: return make_error_condition( errc::interrupted ); |
| 202 | case EINVAL: return make_error_condition( errc::invalid_argument ); |
| 203 | case EIO: return make_error_condition( errc::io_error ); |
| 204 | case EISCONN: return make_error_condition( errc::already_connected ); |
| 205 | case EISDIR: return make_error_condition( errc::is_a_directory ); |
| 206 | case ELOOP: return make_error_condition( errc::too_many_symbolic_link_levels ); |
| 207 | case EMFILE: return make_error_condition( errc::too_many_files_open ); |
| 208 | case EMLINK: return make_error_condition( errc::too_many_links ); |
| 209 | case EMSGSIZE: return make_error_condition( errc::message_size ); |
| 210 | case ENAMETOOLONG: return make_error_condition( errc::filename_too_long ); |
| 211 | case ENETDOWN: return make_error_condition( errc::network_down ); |
| 212 | case ENETRESET: return make_error_condition( errc::network_reset ); |
| 213 | case ENETUNREACH: return make_error_condition( errc::network_unreachable ); |
| 214 | case ENFILE: return make_error_condition( errc::too_many_files_open_in_system ); |
| 215 | case ENOBUFS: return make_error_condition( errc::no_buffer_space ); |
| 216 | case ENODATA: return make_error_condition( errc::no_message_available ); |
| 217 | case ENODEV: return make_error_condition( errc::no_such_device ); |
| 218 | case ENOENT: return make_error_condition( errc::no_such_file_or_directory ); |
| 219 | case ENOEXEC: return make_error_condition( errc::executable_format_error ); |
| 220 | case ENOLCK: return make_error_condition( errc::no_lock_available ); |
| 221 | case ENOLINK: return make_error_condition( errc::no_link ); |
| 222 | case ENOMEM: return make_error_condition( errc::not_enough_memory ); |
| 223 | case ENOMSG: return make_error_condition( errc::no_message ); |
| 224 | case ENOPROTOOPT: return make_error_condition( errc::no_protocol_option ); |
| 225 | case ENOSPC: return make_error_condition( errc::no_space_on_device ); |
| 226 | case ENOSR: return make_error_condition( errc::no_stream_resources ); |
| 227 | case ENOSTR: return make_error_condition( errc::not_a_stream ); |
| 228 | case ENOSYS: return make_error_condition( errc::function_not_supported ); |
| 229 | case ENOTCONN: return make_error_condition( errc::not_connected ); |
| 230 | case ENOTDIR: return make_error_condition( errc::not_a_directory ); |
| 231 | # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value |
| 232 | case ENOTEMPTY: return make_error_condition( errc::directory_not_empty ); |
| 233 | # endif // ENOTEMPTY != EEXIST |
| 234 | # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips |
| 235 | case ENOTRECOVERABLE: return make_error_condition( errc::state_not_recoverable ); |
| 236 | # endif // ENOTRECOVERABLE != ECONNRESET |
| 237 | case ENOTSOCK: return make_error_condition( errc::not_a_socket ); |
| 238 | case ENOTSUP: return make_error_condition( errc::not_supported ); |
| 239 | case ENOTTY: return make_error_condition( errc::inappropriate_io_control_operation ); |
| 240 | case ENXIO: return make_error_condition( errc::no_such_device_or_address ); |
| 241 | # if EOPNOTSUPP != ENOTSUP |
| 242 | case EOPNOTSUPP: return make_error_condition( errc::operation_not_supported ); |
| 243 | # endif // EOPNOTSUPP != ENOTSUP |
| 244 | case EOVERFLOW: return make_error_condition( errc::value_too_large ); |
| 245 | # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips |
| 246 | case EOWNERDEAD: return make_error_condition( errc::owner_dead ); |
| 247 | # endif // EOWNERDEAD != ECONNABORTED |
| 248 | case EPERM: return make_error_condition( errc::operation_not_permitted ); |
| 249 | case EPIPE: return make_error_condition( errc::broken_pipe ); |
| 250 | case EPROTO: return make_error_condition( errc::protocol_error ); |
| 251 | case EPROTONOSUPPORT: return make_error_condition( errc::protocol_not_supported ); |
| 252 | case EPROTOTYPE: return make_error_condition( errc::wrong_protocol_type ); |
| 253 | case ERANGE: return make_error_condition( errc::result_out_of_range ); |
| 254 | case EROFS: return make_error_condition( errc::read_only_file_system ); |
| 255 | case ESPIPE: return make_error_condition( errc::invalid_seek ); |
| 256 | case ESRCH: return make_error_condition( errc::no_such_process ); |
| 257 | case ETIME: return make_error_condition( errc::stream_timeout ); |
| 258 | case ETIMEDOUT: return make_error_condition( errc::timed_out ); |
| 259 | case ETXTBSY: return make_error_condition( errc::text_file_busy ); |
| 260 | # if EAGAIN != EWOULDBLOCK |
| 261 | case EWOULDBLOCK: return make_error_condition( errc::operation_would_block ); |
| 262 | # endif // EAGAIN != EWOULDBLOCK |
| 263 | case EXDEV: return make_error_condition( errc::cross_device_link ); |
| 264 | #else |
| 265 | // Windows system -> posix_errno decode table ---------------------------// |
| 266 | // see WinError.h comments for descriptions of errors |
| 267 | case ERROR_ACCESS_DENIED: return make_error_condition( errc::permission_denied ); |
| 268 | case ERROR_ALREADY_EXISTS: return make_error_condition( errc::file_exists ); |
| 269 | case ERROR_BAD_UNIT: return make_error_condition( errc::no_such_device ); |
| 270 | case ERROR_BUFFER_OVERFLOW: return make_error_condition( errc::filename_too_long ); |
| 271 | case ERROR_BUSY: return make_error_condition( errc::device_or_resource_busy ); |
| 272 | case ERROR_BUSY_DRIVE: return make_error_condition( errc::device_or_resource_busy ); |
| 273 | case ERROR_CANNOT_MAKE: return make_error_condition( errc::permission_denied ); |
| 274 | case ERROR_CANTOPEN: return make_error_condition( errc::io_error ); |
| 275 | case ERROR_CANTREAD: return make_error_condition( errc::io_error ); |
| 276 | case ERROR_CANTWRITE: return make_error_condition( errc::io_error ); |
| 277 | case ERROR_CURRENT_DIRECTORY: return make_error_condition( errc::permission_denied ); |
| 278 | case ERROR_DEV_NOT_EXIST: return make_error_condition( errc::no_such_device ); |
| 279 | case ERROR_DEVICE_IN_USE: return make_error_condition( errc::device_or_resource_busy ); |
| 280 | case ERROR_DIR_NOT_EMPTY: return make_error_condition( errc::directory_not_empty ); |
| 281 | case ERROR_DIRECTORY: return make_error_condition( errc::invalid_argument ); // WinError.h: "The directory name is invalid" |
| 282 | case ERROR_DISK_FULL: return make_error_condition( errc::no_space_on_device ); |
| 283 | case ERROR_FILE_EXISTS: return make_error_condition( errc::file_exists ); |
| 284 | case ERROR_FILE_NOT_FOUND: return make_error_condition( errc::no_such_file_or_directory ); |
| 285 | case ERROR_HANDLE_DISK_FULL: return make_error_condition( errc::no_space_on_device ); |
| 286 | case ERROR_INVALID_ACCESS: return make_error_condition( errc::permission_denied ); |
| 287 | case ERROR_INVALID_DRIVE: return make_error_condition( errc::no_such_device ); |
| 288 | case ERROR_INVALID_FUNCTION: return make_error_condition( errc::function_not_supported ); |
| 289 | case ERROR_INVALID_HANDLE: return make_error_condition( errc::invalid_argument ); |
| 290 | case ERROR_INVALID_NAME: return make_error_condition( errc::invalid_argument ); |
| 291 | case ERROR_LOCK_VIOLATION: return make_error_condition( errc::no_lock_available ); |
| 292 | case ERROR_LOCKED: return make_error_condition( errc::no_lock_available ); |
| 293 | case ERROR_NEGATIVE_SEEK: return make_error_condition( errc::invalid_argument ); |
| 294 | case ERROR_NOACCESS: return make_error_condition( errc::permission_denied ); |
| 295 | case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( errc::not_enough_memory ); |
| 296 | case ERROR_NOT_READY: return make_error_condition( errc::resource_unavailable_try_again ); |
| 297 | case ERROR_NOT_SAME_DEVICE: return make_error_condition( errc::cross_device_link ); |
| 298 | case ERROR_OPEN_FAILED: return make_error_condition( errc::io_error ); |
| 299 | case ERROR_OPEN_FILES: return make_error_condition( errc::device_or_resource_busy ); |
| 300 | case ERROR_OPERATION_ABORTED: return make_error_condition( errc::operation_canceled ); |
| 301 | case ERROR_OUTOFMEMORY: return make_error_condition( errc::not_enough_memory ); |
| 302 | case ERROR_PATH_NOT_FOUND: return make_error_condition( errc::no_such_file_or_directory ); |
| 303 | case ERROR_READ_FAULT: return make_error_condition( errc::io_error ); |
| 304 | case ERROR_RETRY: return make_error_condition( errc::resource_unavailable_try_again ); |
| 305 | case ERROR_SEEK: return make_error_condition( errc::io_error ); |
| 306 | case ERROR_SHARING_VIOLATION: return make_error_condition( errc::permission_denied ); |
| 307 | case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( errc::too_many_files_open ); |
| 308 | case ERROR_WRITE_FAULT: return make_error_condition( errc::io_error ); |
| 309 | case ERROR_WRITE_PROTECT: return make_error_condition( errc::permission_denied ); |
| 310 | case WSAEACCES: return make_error_condition( errc::permission_denied ); |
| 311 | case WSAEADDRINUSE: return make_error_condition( errc::address_in_use ); |
| 312 | case WSAEADDRNOTAVAIL: return make_error_condition( errc::address_not_available ); |
| 313 | case WSAEAFNOSUPPORT: return make_error_condition( errc::address_family_not_supported ); |
| 314 | case WSAEALREADY: return make_error_condition( errc::connection_already_in_progress ); |
| 315 | case WSAEBADF: return make_error_condition( errc::bad_file_descriptor ); |
| 316 | case WSAECONNABORTED: return make_error_condition( errc::connection_aborted ); |
| 317 | case WSAECONNREFUSED: return make_error_condition( errc::connection_refused ); |
| 318 | case WSAECONNRESET: return make_error_condition( errc::connection_reset ); |
| 319 | case WSAEDESTADDRREQ: return make_error_condition( errc::destination_address_required ); |
| 320 | case WSAEFAULT: return make_error_condition( errc::bad_address ); |
| 321 | case WSAEHOSTUNREACH: return make_error_condition( errc::host_unreachable ); |
| 322 | case WSAEINPROGRESS: return make_error_condition( errc::operation_in_progress ); |
| 323 | case WSAEINTR: return make_error_condition( errc::interrupted ); |
| 324 | case WSAEINVAL: return make_error_condition( errc::invalid_argument ); |
| 325 | case WSAEISCONN: return make_error_condition( errc::already_connected ); |
| 326 | case WSAEMFILE: return make_error_condition( errc::too_many_files_open ); |
| 327 | case WSAEMSGSIZE: return make_error_condition( errc::message_size ); |
| 328 | case WSAENAMETOOLONG: return make_error_condition( errc::filename_too_long ); |
| 329 | case WSAENETDOWN: return make_error_condition( errc::network_down ); |
| 330 | case WSAENETRESET: return make_error_condition( errc::network_reset ); |
| 331 | case WSAENETUNREACH: return make_error_condition( errc::network_unreachable ); |
| 332 | case WSAENOBUFS: return make_error_condition( errc::no_buffer_space ); |
| 333 | case WSAENOPROTOOPT: return make_error_condition( errc::no_protocol_option ); |
| 334 | case WSAENOTCONN: return make_error_condition( errc::not_connected ); |
| 335 | case WSAENOTSOCK: return make_error_condition( errc::not_a_socket ); |
| 336 | case WSAEOPNOTSUPP: return make_error_condition( errc::operation_not_supported ); |
| 337 | case WSAEPROTONOSUPPORT: return make_error_condition( errc::protocol_not_supported ); |
| 338 | case WSAEPROTOTYPE: return make_error_condition( errc::wrong_protocol_type ); |
| 339 | case WSAETIMEDOUT: return make_error_condition( errc::timed_out ); |
| 340 | case WSAEWOULDBLOCK: return make_error_condition( errc::operation_would_block ); |
| 341 | #endif |
| 342 | default: return error_condition( ev, system_category() ); |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | # if !defined( BOOST_SYSTEM_WINDOWS_API ) |
| 347 | |
| 348 | std::string system_error_category::message( int ev ) const |
| 349 | { |
| 350 | return generic_category().message( ev ); |
| 351 | } |
| 352 | # else |
| 353 | |
| 354 | std::string system_error_category::message( int ev ) const |
| 355 | { |
| 356 | # ifndef BOOST_NO_ANSI_APIS |
| 357 | boost::detail::win32::LPVOID_ lpMsgBuf = 0; |
| 358 | boost::detail::win32::DWORD_ retval = boost::detail::win32::FormatMessageA( |
| 359 | boost::detail::win32::FORMAT_MESSAGE_ALLOCATE_BUFFER_ | |
| 360 | boost::detail::win32::FORMAT_MESSAGE_FROM_SYSTEM_ | |
| 361 | boost::detail::win32::FORMAT_MESSAGE_IGNORE_INSERTS_, |
| 362 | NULL, |
| 363 | ev, |
| 364 | boost::detail::win32::MAKELANGID_(boost::detail::win32::LANG_NEUTRAL_, boost::detail::win32::SUBLANG_DEFAULT_), // Default language |
| 365 | (boost::detail::win32::LPSTR_) &lpMsgBuf, |
| 366 | 0, |
| 367 | NULL |
| 368 | ); |
| 369 | detail::local_free_on_destruction lfod(lpMsgBuf); |
| 370 | if (retval == 0) |
| 371 | return std::string("Unknown error"); |
| 372 | |
| 373 | std::string str( static_cast<boost::detail::win32::LPCSTR_>(lpMsgBuf) ); |
| 374 | # else // WinCE workaround |
| 375 | boost::detail::win32::LPVOID_ lpMsgBuf = 0; |
| 376 | boost::detail::win32::DWORD retval = boost::detail::win32::FormatMessageW( |
| 377 | boost::detail::win32::FORMAT_MESSAGE_ALLOCATE_BUFFER_ | |
| 378 | boost::detail::win32::FORMAT_MESSAGE_FROM_SYSTEM_ | |
| 379 | boost::detail::win32::FORMAT_MESSAGE_IGNORE_INSERTS_, |
| 380 | NULL, |
| 381 | ev, |
| 382 | boost::detail::win32::MAKELANGID_(boost::detail::win32::LANG_NEUTRAL_, boost::detail::win32::SUBLANG_DEFAULT_), // Default language |
| 383 | (boost::detail::win32::LPWSTR_) &lpMsgBuf, |
| 384 | 0, |
| 385 | NULL |
| 386 | ); |
| 387 | detail::local_free_on_destruction lfod(lpMsgBuf); |
| 388 | if (retval == 0) |
| 389 | return std::string("Unknown error"); |
| 390 | |
| 391 | int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2; |
| 392 | boost::detail::win32::LPSTR_ narrow_buffer = (boost::detail::win32::LPSTR_)_alloca( num_chars ); |
| 393 | if (boost::detail::win32::WideCharToMultiByte(CP_ACP, 0, static_cast<boost::detail::win32::LPCWSTR_>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0) |
| 394 | return std::string("Unknown error"); |
| 395 | |
| 396 | std::string str( narrow_buffer ); |
| 397 | # endif |
| 398 | while ( str.size() |
| 399 | && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) |
| 400 | str.erase( str.size()-1 ); |
| 401 | if ( str.size() && str[str.size()-1] == '.' ) |
| 402 | { str.erase( str.size()-1 ); } |
| 403 | return str; |
| 404 | } |
| 405 | # endif |
| 406 | |
| 407 | } |
| 408 | |
| 409 | # ifndef BOOST_SYSTEM_NO_DEPRECATED |
| 410 | BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code; |
| 411 | // note that it doesn't matter if this |
| 412 | // isn't initialized before use since |
| 413 | // the only use is to take its |
| 414 | // address for comparison purposes |
| 415 | # endif |
| 416 | |
| 417 | BOOST_SYSTEM_DECL const error_category & system_category() |
| 418 | { |
| 419 | static const system_detail::system_error_category system_category_const; |
| 420 | return system_category_const; |
| 421 | } |
| 422 | |
| 423 | BOOST_SYSTEM_DECL const error_category & generic_category() |
| 424 | { |
| 425 | static const system_detail::generic_error_category generic_category_const; |
| 426 | return generic_category_const; |
| 427 | } |
| 428 | |
| 429 | } // namespace system |
| 430 | } // namespace boost |
| 431 | #endif // BOOST_SYSTEM_DETAIL_INLINED_ERROR_CODE_HPP |