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