]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/system/detail/error_code.ipp
update sources to v12.2.3
[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
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 // 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)\
89 || (defined(__linux) && (!defined(__USE_XOPEN2K)\
90 || 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 # 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 );
157 return msg;
158 # endif // else POSIX version of strerror_r
159 # endif // else use strerror_r
160 }
161 // system_error_category implementation --------------------------------------------//
162
163 const char * system_error_category::name() const BOOST_SYSTEM_NOEXCEPT
164 {
165 return "system";
166 }
167
168 error_condition system_error_category::default_error_condition( int ev ) const
169 BOOST_SYSTEM_NOEXCEPT
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
185 # endif
186
187 # if defined(BOOST_WINDOWS_API)
188
189 using namespace boost::winapi; // for error codes
190
191 # endif
192
193 switch ( ev )
194 {
195 case 0: return make_error_condition( success );
196 # if defined(BOOST_POSIX_API)
197 // POSIX-like O/S -> posix_errno decode table -------------------------------------//
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
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 );
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 {
385 boost::winapi::DWORD_ retval = boost::winapi::FormatMessageW(
386 boost::winapi::FORMAT_MESSAGE_FROM_SYSTEM_ |
387 boost::winapi::FORMAT_MESSAGE_IGNORE_INSERTS_,
388 NULL,
389 ev,
390 boost::winapi::MAKELANGID_(boost::winapi::LANG_NEUTRAL_,
391 boost::winapi::SUBLANG_DEFAULT_), // Default language
392 &buf[0],
393 static_cast<boost::winapi::DWORD_>(buf.size()),
394 NULL
395 );
396
397 if (retval > 0)
398 {
399 buf.resize(retval);
400 break;
401 }
402 else if (boost::winapi::GetLastError() !=
403 boost::winapi::ERROR_INSUFFICIENT_BUFFER_)
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;
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)
424 {
425 return std::string("Unknown error");
426 }
427
428 std::string str( narrow_buffer );
429 #else
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_,
435 NULL,
436 ev,
437 boost::winapi::MAKELANGID_(boost::winapi::LANG_NEUTRAL_,
438 boost::winapi::SUBLANG_DEFAULT_), // Default language
439 (boost::winapi::LPSTR_) &lpMsgBuf,
440 0,
441 NULL
442 );
443 detail::local_free_on_destruction lfod(lpMsgBuf);
444 if (retval == 0)
445 return std::string("Unknown error");
446
447 std::string str(static_cast<boost::winapi::LPCSTR_>(lpMsgBuf));
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
461 # ifdef BOOST_SYSTEM_ENABLE_DEPRECATED
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