| | 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 |