]>
Commit | Line | Data |
---|---|---|
b32b8144 | 1 | // error_code support implementation file --------------------------------------------// |
7c673cae FG |
2 | |
3 | // Copyright Beman Dawes 2002, 2006 | |
4 | // Copyright (c) Microsoft Corporation 2014 | |
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 | ||
b32b8144 | 10 | //--------------------------------------------------------------------------------------// |
7c673cae FG |
11 | |
12 | #include <boost/config/warning_disable.hpp> | |
13 | ||
14 | #include <boost/system/config.hpp> | |
15 | #include <boost/system/error_code.hpp> | |
16 | #include <boost/cerrno.hpp> | |
17 | #include <vector> | |
18 | #include <cstdlib> | |
19 | #include <cassert> | |
20 | ||
21 | #include <cstring> // for strerror/strerror_r | |
22 | ||
23 | # if defined( BOOST_WINDOWS_API ) | |
b32b8144 FG |
24 | # include <boost/winapi/error_codes.hpp> |
25 | # include <boost/winapi/error_handling.hpp> | |
26 | # include <boost/winapi/character_code_conversion.hpp> | |
7c673cae FG |
27 | # if !BOOST_PLAT_WINDOWS_RUNTIME |
28 | # include <boost/system/detail/local_free_on_destruction.hpp> | |
29 | # endif | |
30 | # ifndef ERROR_INCORRECT_SIZE | |
31 | # define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS | |
32 | # endif | |
33 | # endif | |
34 | ||
b32b8144 | 35 | //--------------------------------------------------------------------------------------// |
7c673cae FG |
36 | namespace boost |
37 | { | |
38 | namespace system | |
39 | { | |
40 | ||
41 | namespace | |
42 | { | |
43 | ||
b32b8144 | 44 | // standard error categories -------------------------------------------------------// |
7c673cae FG |
45 | |
46 | class generic_error_category : public error_category | |
47 | { | |
48 | public: | |
49 | generic_error_category(){} | |
50 | const char * name() const BOOST_SYSTEM_NOEXCEPT; | |
51 | std::string message( int ev ) const; | |
52 | }; | |
53 | ||
54 | class system_error_category : public error_category | |
55 | { | |
56 | public: | |
57 | system_error_category(){} | |
58 | const char * name() const BOOST_SYSTEM_NOEXCEPT; | |
59 | std::string message( int ev ) const; | |
60 | error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT; | |
61 | }; | |
62 | ||
63 | // generic_error_category implementation ---------------------------------// | |
64 | ||
65 | const char * generic_error_category::name() const BOOST_SYSTEM_NOEXCEPT | |
66 | { | |
67 | return "generic"; | |
68 | } | |
69 | ||
70 | std::string generic_error_category::message( int ev ) const | |
71 | { | |
72 | using namespace boost::system::errc; | |
73 | #if defined(__PGI) | |
74 | using boost::system::errc::invalid_argument; | |
75 | #endif | |
76 | ||
77 | static std::string unknown_err( "Unknown error" ); | |
78 | // strerror_r is preferred because it is always thread safe, | |
79 | // however, we fallback to strerror in certain cases because: | |
80 | // -- Windows doesn't provide strerror_r. | |
81 | // -- HP and Sun do provide strerror_r on newer systems, but there is | |
82 | // no way to tell if is available at runtime and in any case their | |
83 | // versions of strerror are thread safe anyhow. | |
84 | // -- Linux only sometimes provides strerror_r. | |
85 | // -- Tru64 provides strerror_r only when compiled -pthread. | |
86 | // -- VMS doesn't provide strerror_r, but on this platform, strerror is | |
87 | // thread safe. | |
88 | # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\ | |
b32b8144 FG |
89 | || (defined(__linux) && (!defined(__USE_XOPEN2K)\ |
90 | || defined(BOOST_SYSTEM_USE_STRERROR)))\ | |
7c673cae FG |
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 | # ifndef BOOST_NO_EXCEPTIONS | |
142 | try | |
143 | # endif | |
144 | { | |
145 | msg = ( ( result == invalid_argument ) ? "Unknown error" : bp ); | |
146 | } | |
147 | ||
148 | # ifndef BOOST_NO_EXCEPTIONS | |
149 | // See ticket #2098 | |
150 | catch(...) | |
151 | { | |
152 | // just eat the exception | |
153 | } | |
154 | # endif | |
155 | ||
156 | if ( sz > sizeof(buf) ) std::free( bp ); | |
7c673cae FG |
157 | return msg; |
158 | # endif // else POSIX version of strerror_r | |
159 | # endif // else use strerror_r | |
160 | } | |
b32b8144 | 161 | // system_error_category implementation --------------------------------------------// |
7c673cae FG |
162 | |
163 | const char * system_error_category::name() const BOOST_SYSTEM_NOEXCEPT | |
164 | { | |
165 | return "system"; | |
166 | } | |
167 | ||
b32b8144 FG |
168 | error_condition system_error_category::default_error_condition( int ev ) const |
169 | BOOST_SYSTEM_NOEXCEPT | |
7c673cae FG |
170 | { |
171 | using namespace boost::system::errc; | |
172 | #if defined(__PGI) | |
173 | using boost::system::errc::invalid_argument; | |
174 | #endif | |
175 | ||
176 | # if defined(BOOST_WINDOWS_API) | |
177 | # if defined(WINAPI_FAMILY) && ((WINAPI_FAMILY & WINAPI_PARTITION_APP) != 0) | |
178 | // When using the Windows Runtime, most system errors are reported as HRESULTs. | |
179 | // We want to map the common Win32 errors to their equivalent error condition, | |
180 | // whether or not they are reported via an HRESULT. | |
181 | if ( ev < 0 ) // Check for failed HRESULTs only. | |
182 | if ( HRESULT_FACILITY( ev ) == FACILITY_WIN32 ) | |
183 | ev = HRESULT_CODE( ev ); | |
184 | # endif | |
b32b8144 FG |
185 | # endif |
186 | ||
187 | # if defined(BOOST_WINDOWS_API) | |
188 | ||
189 | using namespace boost::winapi; // for error codes | |
190 | ||
7c673cae FG |
191 | # endif |
192 | ||
193 | switch ( ev ) | |
194 | { | |
195 | case 0: return make_error_condition( success ); | |
196 | # if defined(BOOST_POSIX_API) | |
b32b8144 | 197 | // POSIX-like O/S -> posix_errno decode table -------------------------------------// |
7c673cae FG |
198 | case E2BIG: return make_error_condition( argument_list_too_long ); |
199 | case EACCES: return make_error_condition( permission_denied ); | |
200 | case EADDRINUSE: return make_error_condition( address_in_use ); | |
201 | case EADDRNOTAVAIL: return make_error_condition( address_not_available ); | |
202 | case EAFNOSUPPORT: return make_error_condition( address_family_not_supported ); | |
203 | case EAGAIN: return make_error_condition( resource_unavailable_try_again ); | |
204 | # if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino | |
205 | case EALREADY: return make_error_condition( connection_already_in_progress ); | |
206 | # endif | |
207 | case EBADF: return make_error_condition( bad_file_descriptor ); | |
208 | case EBADMSG: return make_error_condition( bad_message ); | |
209 | case EBUSY: return make_error_condition( device_or_resource_busy ); | |
210 | case ECANCELED: return make_error_condition( operation_canceled ); | |
211 | case ECHILD: return make_error_condition( no_child_process ); | |
212 | case ECONNABORTED: return make_error_condition( connection_aborted ); | |
213 | case ECONNREFUSED: return make_error_condition( connection_refused ); | |
214 | case ECONNRESET: return make_error_condition( connection_reset ); | |
215 | case EDEADLK: return make_error_condition( resource_deadlock_would_occur ); | |
216 | case EDESTADDRREQ: return make_error_condition( destination_address_required ); | |
217 | case EDOM: return make_error_condition( argument_out_of_domain ); | |
218 | case EEXIST: return make_error_condition( file_exists ); | |
219 | case EFAULT: return make_error_condition( bad_address ); | |
220 | case EFBIG: return make_error_condition( file_too_large ); | |
221 | case EHOSTUNREACH: return make_error_condition( host_unreachable ); | |
222 | case EIDRM: return make_error_condition( identifier_removed ); | |
223 | case EILSEQ: return make_error_condition( illegal_byte_sequence ); | |
224 | case EINPROGRESS: return make_error_condition( operation_in_progress ); | |
225 | case EINTR: return make_error_condition( interrupted ); | |
226 | case EINVAL: return make_error_condition( invalid_argument ); | |
227 | case EIO: return make_error_condition( io_error ); | |
228 | case EISCONN: return make_error_condition( already_connected ); | |
229 | case EISDIR: return make_error_condition( is_a_directory ); | |
230 | case ELOOP: return make_error_condition( too_many_symbolic_link_levels ); | |
231 | case EMFILE: return make_error_condition( too_many_files_open ); | |
232 | case EMLINK: return make_error_condition( too_many_links ); | |
233 | case EMSGSIZE: return make_error_condition( message_size ); | |
234 | case ENAMETOOLONG: return make_error_condition( filename_too_long ); | |
235 | case ENETDOWN: return make_error_condition( network_down ); | |
236 | case ENETRESET: return make_error_condition( network_reset ); | |
237 | case ENETUNREACH: return make_error_condition( network_unreachable ); | |
238 | case ENFILE: return make_error_condition( too_many_files_open_in_system ); | |
239 | case ENOBUFS: return make_error_condition( no_buffer_space ); | |
240 | case ENODATA: return make_error_condition( no_message_available ); | |
241 | case ENODEV: return make_error_condition( no_such_device ); | |
242 | case ENOENT: return make_error_condition( no_such_file_or_directory ); | |
243 | case ENOEXEC: return make_error_condition( executable_format_error ); | |
244 | case ENOLCK: return make_error_condition( no_lock_available ); | |
245 | case ENOLINK: return make_error_condition( no_link ); | |
246 | case ENOMEM: return make_error_condition( not_enough_memory ); | |
247 | case ENOMSG: return make_error_condition( no_message ); | |
248 | case ENOPROTOOPT: return make_error_condition( no_protocol_option ); | |
249 | case ENOSPC: return make_error_condition( no_space_on_device ); | |
250 | case ENOSR: return make_error_condition( no_stream_resources ); | |
251 | case ENOSTR: return make_error_condition( not_a_stream ); | |
252 | case ENOSYS: return make_error_condition( function_not_supported ); | |
253 | case ENOTCONN: return make_error_condition( not_connected ); | |
254 | case ENOTDIR: return make_error_condition( not_a_directory ); | |
255 | # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value | |
256 | case ENOTEMPTY: return make_error_condition( directory_not_empty ); | |
257 | # endif // ENOTEMPTY != EEXIST | |
258 | # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips | |
259 | case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable ); | |
260 | # endif // ENOTRECOVERABLE != ECONNRESET | |
261 | case ENOTSOCK: return make_error_condition( not_a_socket ); | |
262 | case ENOTSUP: return make_error_condition( not_supported ); | |
263 | case ENOTTY: return make_error_condition( inappropriate_io_control_operation ); | |
264 | case ENXIO: return make_error_condition( no_such_device_or_address ); | |
265 | # if EOPNOTSUPP != ENOTSUP | |
266 | case EOPNOTSUPP: return make_error_condition( operation_not_supported ); | |
267 | # endif // EOPNOTSUPP != ENOTSUP | |
268 | case EOVERFLOW: return make_error_condition( value_too_large ); | |
269 | # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips | |
270 | case EOWNERDEAD: return make_error_condition( owner_dead ); | |
271 | # endif // EOWNERDEAD != ECONNABORTED | |
272 | case EPERM: return make_error_condition( operation_not_permitted ); | |
273 | case EPIPE: return make_error_condition( broken_pipe ); | |
274 | case EPROTO: return make_error_condition( protocol_error ); | |
275 | case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported ); | |
276 | case EPROTOTYPE: return make_error_condition( wrong_protocol_type ); | |
277 | case ERANGE: return make_error_condition( result_out_of_range ); | |
278 | case EROFS: return make_error_condition( read_only_file_system ); | |
279 | case ESPIPE: return make_error_condition( invalid_seek ); | |
280 | case ESRCH: return make_error_condition( no_such_process ); | |
281 | case ETIME: return make_error_condition( stream_timeout ); | |
282 | case ETIMEDOUT: return make_error_condition( timed_out ); | |
283 | case ETXTBSY: return make_error_condition( text_file_busy ); | |
284 | # if EAGAIN != EWOULDBLOCK | |
285 | case EWOULDBLOCK: return make_error_condition( operation_would_block ); | |
286 | # endif // EAGAIN != EWOULDBLOCK | |
287 | case EXDEV: return make_error_condition( cross_device_link ); | |
288 | #else | |
289 | // Windows system -> posix_errno decode table ---------------------------// | |
290 | // see WinError.h comments for descriptions of errors | |
b32b8144 FG |
291 | case ERROR_ACCESS_DENIED_: return make_error_condition( permission_denied ); |
292 | case ERROR_ALREADY_EXISTS_: return make_error_condition( file_exists ); | |
293 | case ERROR_BAD_UNIT_: return make_error_condition( no_such_device ); | |
294 | case ERROR_BUFFER_OVERFLOW_: return make_error_condition( filename_too_long ); | |
295 | case ERROR_BUSY_: return make_error_condition( device_or_resource_busy ); | |
296 | case ERROR_BUSY_DRIVE_: return make_error_condition( device_or_resource_busy ); | |
297 | case ERROR_CANNOT_MAKE_: return make_error_condition( permission_denied ); | |
298 | case ERROR_CANTOPEN_: return make_error_condition( io_error ); | |
299 | case ERROR_CANTREAD_: return make_error_condition( io_error ); | |
300 | case ERROR_CANTWRITE_: return make_error_condition( io_error ); | |
301 | case ERROR_CURRENT_DIRECTORY_: return make_error_condition( permission_denied ); | |
302 | case ERROR_DEV_NOT_EXIST_: return make_error_condition( no_such_device ); | |
303 | case ERROR_DEVICE_IN_USE_: return make_error_condition( device_or_resource_busy ); | |
304 | case ERROR_DIR_NOT_EMPTY_: return make_error_condition( directory_not_empty ); | |
305 | case ERROR_DIRECTORY_: return make_error_condition( invalid_argument );\ | |
306 | // WinError.h: "The directory name is invalid" | |
307 | case ERROR_DISK_FULL_: return make_error_condition( no_space_on_device ); | |
308 | case ERROR_FILE_EXISTS_: return make_error_condition( file_exists ); | |
309 | case ERROR_FILE_NOT_FOUND_: return make_error_condition( no_such_file_or_directory ); | |
310 | case ERROR_HANDLE_DISK_FULL_: return make_error_condition( no_space_on_device ); | |
311 | case ERROR_INVALID_ACCESS_: return make_error_condition( permission_denied ); | |
312 | case ERROR_INVALID_DRIVE_: return make_error_condition( no_such_device ); | |
313 | case ERROR_INVALID_FUNCTION_: return make_error_condition( function_not_supported ); | |
314 | case ERROR_INVALID_HANDLE_: return make_error_condition( invalid_argument ); | |
315 | case ERROR_INVALID_NAME_: return make_error_condition( invalid_argument ); | |
316 | case ERROR_LOCK_VIOLATION_: return make_error_condition( no_lock_available ); | |
317 | case ERROR_LOCKED_: return make_error_condition( no_lock_available ); | |
318 | case ERROR_NEGATIVE_SEEK_: return make_error_condition( invalid_argument ); | |
319 | case ERROR_NOACCESS_: return make_error_condition( permission_denied ); | |
320 | case ERROR_NOT_ENOUGH_MEMORY_: return make_error_condition( not_enough_memory ); | |
321 | case ERROR_NOT_READY_: return make_error_condition( resource_unavailable_try_again ); | |
322 | case ERROR_NOT_SAME_DEVICE_: return make_error_condition( cross_device_link ); | |
323 | case ERROR_OPEN_FAILED_: return make_error_condition( io_error ); | |
324 | case ERROR_OPEN_FILES_: return make_error_condition( device_or_resource_busy ); | |
325 | case ERROR_OPERATION_ABORTED_: return make_error_condition( operation_canceled ); | |
326 | case ERROR_OUTOFMEMORY_: return make_error_condition( not_enough_memory ); | |
327 | case ERROR_PATH_NOT_FOUND_: return make_error_condition( no_such_file_or_directory ); | |
328 | case ERROR_READ_FAULT_: return make_error_condition( io_error ); | |
329 | case ERROR_RETRY_: return make_error_condition( resource_unavailable_try_again ); | |
330 | case ERROR_SEEK_: return make_error_condition( io_error ); | |
331 | case ERROR_SHARING_VIOLATION_: return make_error_condition( permission_denied ); | |
332 | case ERROR_TOO_MANY_OPEN_FILES_: return make_error_condition( too_many_files_open ); | |
333 | case ERROR_WRITE_FAULT_: return make_error_condition( io_error ); | |
334 | case ERROR_WRITE_PROTECT_: return make_error_condition( permission_denied ); | |
335 | case WSAEACCES_: return make_error_condition( permission_denied ); | |
336 | case WSAEADDRINUSE_: return make_error_condition( address_in_use ); | |
337 | case WSAEADDRNOTAVAIL_: return make_error_condition( address_not_available ); | |
338 | case WSAEAFNOSUPPORT_: return make_error_condition( address_family_not_supported ); | |
339 | case WSAEALREADY_: return make_error_condition( connection_already_in_progress ); | |
340 | case WSAEBADF_: return make_error_condition( bad_file_descriptor ); | |
341 | case WSAECONNABORTED_: return make_error_condition( connection_aborted ); | |
342 | case WSAECONNREFUSED_: return make_error_condition( connection_refused ); | |
343 | case WSAECONNRESET_: return make_error_condition( connection_reset ); | |
344 | case WSAEDESTADDRREQ_: return make_error_condition( destination_address_required ); | |
345 | case WSAEFAULT_: return make_error_condition( bad_address ); | |
346 | case WSAEHOSTUNREACH_: return make_error_condition( host_unreachable ); | |
347 | case WSAEINPROGRESS_: return make_error_condition( operation_in_progress ); | |
348 | case WSAEINTR_: return make_error_condition( interrupted ); | |
349 | case WSAEINVAL_: return make_error_condition( invalid_argument ); | |
350 | case WSAEISCONN_: return make_error_condition( already_connected ); | |
351 | case WSAEMFILE_: return make_error_condition( too_many_files_open ); | |
352 | case WSAEMSGSIZE_: return make_error_condition( message_size ); | |
353 | case WSAENAMETOOLONG_: return make_error_condition( filename_too_long ); | |
354 | case WSAENETDOWN_: return make_error_condition( network_down ); | |
355 | case WSAENETRESET_: return make_error_condition( network_reset ); | |
356 | case WSAENETUNREACH_: return make_error_condition( network_unreachable ); | |
357 | case WSAENOBUFS_: return make_error_condition( no_buffer_space ); | |
358 | case WSAENOPROTOOPT_: return make_error_condition( no_protocol_option ); | |
359 | case WSAENOTCONN_: return make_error_condition( not_connected ); | |
360 | case WSAENOTSOCK_: return make_error_condition( not_a_socket ); | |
361 | case WSAEOPNOTSUPP_: return make_error_condition( operation_not_supported ); | |
362 | case WSAEPROTONOSUPPORT_: return make_error_condition( protocol_not_supported ); | |
363 | case WSAEPROTOTYPE_: return make_error_condition( wrong_protocol_type ); | |
364 | case WSAETIMEDOUT_: return make_error_condition( timed_out ); | |
365 | case WSAEWOULDBLOCK_: return make_error_condition( operation_would_block ); | |
7c673cae FG |
366 | #endif |
367 | default: return error_condition( ev, system_category() ); | |
368 | } | |
369 | } | |
370 | ||
371 | # if !defined( BOOST_WINDOWS_API ) | |
372 | ||
373 | std::string system_error_category::message( int ev ) const | |
374 | { | |
375 | return generic_category().message( ev ); | |
376 | } | |
377 | # else | |
378 | ||
379 | std::string system_error_category::message( int ev ) const | |
380 | { | |
381 | #if defined(UNDER_CE) || BOOST_PLAT_WINDOWS_RUNTIME || defined(BOOST_NO_ANSI_APIS) | |
382 | std::wstring buf(128, wchar_t()); | |
383 | for (;;) | |
384 | { | |
b32b8144 FG |
385 | boost::winapi::DWORD_ retval = boost::winapi::FormatMessageW( |
386 | boost::winapi::FORMAT_MESSAGE_FROM_SYSTEM_ | | |
387 | boost::winapi::FORMAT_MESSAGE_IGNORE_INSERTS_, | |
7c673cae FG |
388 | NULL, |
389 | ev, | |
b32b8144 FG |
390 | boost::winapi::MAKELANGID_(boost::winapi::LANG_NEUTRAL_, |
391 | boost::winapi::SUBLANG_DEFAULT_), // Default language | |
7c673cae | 392 | &buf[0], |
b32b8144 | 393 | static_cast<boost::winapi::DWORD_>(buf.size()), |
7c673cae FG |
394 | NULL |
395 | ); | |
396 | ||
397 | if (retval > 0) | |
398 | { | |
399 | buf.resize(retval); | |
400 | break; | |
401 | } | |
b32b8144 FG |
402 | else if (boost::winapi::GetLastError() != |
403 | boost::winapi::ERROR_INSUFFICIENT_BUFFER_) | |
7c673cae FG |
404 | { |
405 | return std::string("Unknown error"); | |
406 | } | |
407 | else | |
408 | { | |
409 | buf.resize(buf.size() + buf.size() / 2); | |
410 | } | |
411 | } | |
412 | ||
413 | int num_chars = (buf.size() + 1) * 2; | |
b32b8144 FG |
414 | |
415 | boost::winapi::LPSTR_ narrow_buffer = | |
416 | #if defined(__GNUC__) | |
417 | (boost::winapi::LPSTR_)__builtin_alloca(num_chars); | |
418 | #else | |
419 | (boost::winapi::LPSTR_)_alloca(num_chars); | |
420 | #endif | |
421 | ||
422 | if (boost::winapi::WideCharToMultiByte(boost::winapi::CP_ACP_, 0, | |
423 | buf.c_str(), -1, narrow_buffer, num_chars, NULL, NULL) == 0) | |
7c673cae FG |
424 | { |
425 | return std::string("Unknown error"); | |
426 | } | |
427 | ||
428 | std::string str( narrow_buffer ); | |
429 | #else | |
b32b8144 FG |
430 | boost::winapi::LPVOID_ lpMsgBuf = 0; |
431 | boost::winapi::DWORD_ retval = boost::winapi::FormatMessageA( | |
432 | boost::winapi::FORMAT_MESSAGE_ALLOCATE_BUFFER_ | | |
433 | boost::winapi::FORMAT_MESSAGE_FROM_SYSTEM_ | | |
434 | boost::winapi::FORMAT_MESSAGE_IGNORE_INSERTS_, | |
7c673cae FG |
435 | NULL, |
436 | ev, | |
b32b8144 FG |
437 | boost::winapi::MAKELANGID_(boost::winapi::LANG_NEUTRAL_, |
438 | boost::winapi::SUBLANG_DEFAULT_), // Default language | |
439 | (boost::winapi::LPSTR_) &lpMsgBuf, | |
7c673cae FG |
440 | 0, |
441 | NULL | |
442 | ); | |
443 | detail::local_free_on_destruction lfod(lpMsgBuf); | |
444 | if (retval == 0) | |
445 | return std::string("Unknown error"); | |
446 | ||
b32b8144 | 447 | std::string str(static_cast<boost::winapi::LPCSTR_>(lpMsgBuf)); |
7c673cae FG |
448 | # endif |
449 | while ( str.size() | |
450 | && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) | |
451 | str.erase( str.size()-1 ); | |
452 | if ( str.size() && str[str.size()-1] == '.' ) | |
453 | { str.erase( str.size()-1 ); } | |
454 | return str; | |
455 | } | |
456 | # endif | |
457 | ||
458 | } // unnamed namespace | |
459 | ||
460 | ||
b32b8144 | 461 | # ifdef BOOST_SYSTEM_ENABLE_DEPRECATED |
7c673cae FG |
462 | BOOST_SYSTEM_DECL error_code throws; // "throw on error" special error_code; |
463 | // note that it doesn't matter if this | |
464 | // isn't initialized before use since | |
465 | // the only use is to take its | |
466 | // address for comparison purposes | |
467 | # endif | |
468 | ||
469 | # ifdef BOOST_ERROR_CODE_HEADER_ONLY | |
470 | # define BOOST_SYSTEM_LINKAGE inline | |
471 | # else | |
472 | # define BOOST_SYSTEM_LINKAGE BOOST_SYSTEM_DECL | |
473 | # endif | |
474 | ||
475 | BOOST_SYSTEM_LINKAGE const error_category & system_category() BOOST_SYSTEM_NOEXCEPT | |
476 | { | |
477 | static const system_error_category system_category_const; | |
478 | return system_category_const; | |
479 | } | |
480 | ||
481 | BOOST_SYSTEM_LINKAGE const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT | |
482 | { | |
483 | static const generic_error_category generic_category_const; | |
484 | return generic_category_const; | |
485 | } | |
486 | ||
487 | } // namespace system | |
488 | } // namespace boost |