1 // error_code support implementation file ----------------------------------//
3 // Copyright Beman Dawes 2002, 2006
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)
8 // See library home page at http://www.boost.org/libs/system
10 //----------------------------------------------------------------------------//
12 #include <boost/config/warning_disable.hpp>
14 // define BOOST_SYSTEM_SOURCE so that <boost/system/config.hpp> knows
15 // the library is being built (possibly exporting rather than importing code)
16 #define BOOST_SYSTEM_SOURCE
18 #include <boost/system/config.hpp>
19 #include <boost/system/error_code.hpp>
20 #include <boost/cerrno.hpp>
25 using namespace boost::system
;
26 using namespace boost::system::errc
;
28 #include <cstring> // for strerror/strerror_r
30 # if defined( BOOST_WINDOWS_API )
32 # include "local_free_on_destruction.hpp"
33 # ifndef ERROR_INCORRECT_SIZE
34 # define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
38 //----------------------------------------------------------------------------//
43 using boost::system::errc::invalid_argument
;
45 // standard error categories ---------------------------------------------//
47 class generic_error_category
: public error_category
50 generic_error_category(){}
51 const char * name() const;
52 std::string
message( int ev
) const;
55 class system_error_category
: public error_category
58 system_error_category(){}
59 const char * name() const;
60 std::string
message( int ev
) const;
61 error_condition
default_error_condition( int ev
) const;
64 // generic_error_category implementation ---------------------------------//
66 const char * generic_error_category::name() const
71 std::string
generic_error_category::message( int ev
) const
73 static std::string
unknown_err( "Unknown error" );
74 // strerror_r is preferred because it is always thread safe,
75 // however, we fallback to strerror in certain cases because:
76 // -- Windows doesn't provide strerror_r.
77 // -- HP and Sundo provide strerror_r on newer systems, but there is
78 // no way to tell if is available at runtime and in any case their
79 // versions of strerror are thread safe anyhow.
80 // -- Linux only sometimes provides strerror_r.
81 // -- Tru64 provides strerror_r only when compiled -pthread.
82 // -- VMS doesn't provide strerror_r, but on this platform, strerror is
84 # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\
85 || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\
86 || (defined(__osf__) && !defined(_REENTRANT))\
88 || (defined(__QNXNTO__))
89 const char * c_str
= std::strerror( ev
);
91 ? std::string( c_str
)
93 # else // use strerror_r
96 std::size_t sz
= sizeof(buf
);
97 # if defined(__CYGWIN__) || defined(__USE_GNU)
98 // Oddball version of strerror_r
99 const char * c_str
= strerror_r( ev
, bp
, sz
);
101 ? std::string( c_str
)
104 // POSIX version of strerror_r
108 // strerror_r returns 0 on success, otherwise ERANGE if buffer too small,
109 // invalid_argument if ev not a valid error number
111 const char * c_str
= strerror( ev
);
114 ? std::string( c_str
)
117 result
= strerror_r( ev
, bp
, sz
);
123 # if defined(__linux)
124 // Linux strerror_r returns -1 on error, with error number in errno
127 if ( result
!= ERANGE
) break;
128 if ( sz
> sizeof(buf
) ) std::free( bp
);
130 if ( (bp
= static_cast<char*>(std::malloc( sz
))) == 0 )
131 return std::string( "ENOMEM" );
137 msg
= ( ( result
== invalid_argument
) ? "Unknown error" : bp
);
140 # ifndef BOOST_NO_EXCEPTIONS
144 // just eat the exception
148 if ( sz
> sizeof(buf
) ) std::free( bp
);
151 # endif // else POSIX version of strerror_r
152 # endif // else use strerror_r
154 // system_error_category implementation --------------------------------//
156 const char * system_error_category::name() const
161 error_condition
system_error_category::default_error_condition( int ev
) const
165 case 0: return make_error_condition( success
);
166 # if defined(BOOST_POSIX_API)
167 // POSIX-like O/S -> posix_errno decode table ---------------------------//
168 case E2BIG
: return make_error_condition( argument_list_too_long
);
169 case EACCES
: return make_error_condition( permission_denied
);
170 case EADDRINUSE
: return make_error_condition( address_in_use
);
171 case EADDRNOTAVAIL
: return make_error_condition( address_not_available
);
172 case EAFNOSUPPORT
: return make_error_condition( address_family_not_supported
);
173 case EAGAIN
: return make_error_condition( resource_unavailable_try_again
);
174 # if EALREADY != EBUSY // EALREADY and EBUSY are the same on QNX Neutrino
175 case EALREADY
: return make_error_condition( connection_already_in_progress
);
177 case EBADF
: return make_error_condition( bad_file_descriptor
);
178 case EBADMSG
: return make_error_condition( bad_message
);
179 case EBUSY
: return make_error_condition( device_or_resource_busy
);
180 case ECANCELED
: return make_error_condition( operation_canceled
);
181 case ECHILD
: return make_error_condition( no_child_process
);
182 case ECONNABORTED
: return make_error_condition( connection_aborted
);
183 case ECONNREFUSED
: return make_error_condition( connection_refused
);
184 case ECONNRESET
: return make_error_condition( connection_reset
);
185 case EDEADLK
: return make_error_condition( resource_deadlock_would_occur
);
186 case EDESTADDRREQ
: return make_error_condition( destination_address_required
);
187 case EDOM
: return make_error_condition( argument_out_of_domain
);
188 case EEXIST
: return make_error_condition( file_exists
);
189 case EFAULT
: return make_error_condition( bad_address
);
190 case EFBIG
: return make_error_condition( file_too_large
);
191 case EHOSTUNREACH
: return make_error_condition( host_unreachable
);
192 case EIDRM
: return make_error_condition( identifier_removed
);
193 case EILSEQ
: return make_error_condition( illegal_byte_sequence
);
194 case EINPROGRESS
: return make_error_condition( operation_in_progress
);
195 case EINTR
: return make_error_condition( interrupted
);
196 case EINVAL
: return make_error_condition( invalid_argument
);
197 case EIO
: return make_error_condition( io_error
);
198 case EISCONN
: return make_error_condition( already_connected
);
199 case EISDIR
: return make_error_condition( is_a_directory
);
200 case ELOOP
: return make_error_condition( too_many_symbolic_link_levels
);
201 case EMFILE
: return make_error_condition( too_many_files_open
);
202 case EMLINK
: return make_error_condition( too_many_links
);
203 case EMSGSIZE
: return make_error_condition( message_size
);
204 case ENAMETOOLONG
: return make_error_condition( filename_too_long
);
205 case ENETDOWN
: return make_error_condition( network_down
);
206 case ENETRESET
: return make_error_condition( network_reset
);
207 case ENETUNREACH
: return make_error_condition( network_unreachable
);
208 case ENFILE
: return make_error_condition( too_many_files_open_in_system
);
209 case ENOBUFS
: return make_error_condition( no_buffer_space
);
210 case ENODATA
: return make_error_condition( no_message_available
);
211 case ENODEV
: return make_error_condition( no_such_device
);
212 case ENOENT
: return make_error_condition( no_such_file_or_directory
);
213 case ENOEXEC
: return make_error_condition( executable_format_error
);
214 case ENOLCK
: return make_error_condition( no_lock_available
);
215 case ENOLINK
: return make_error_condition( no_link
);
216 case ENOMEM
: return make_error_condition( not_enough_memory
);
217 case ENOMSG
: return make_error_condition( no_message
);
218 case ENOPROTOOPT
: return make_error_condition( no_protocol_option
);
219 case ENOSPC
: return make_error_condition( no_space_on_device
);
220 case ENOSR
: return make_error_condition( no_stream_resources
);
221 case ENOSTR
: return make_error_condition( not_a_stream
);
222 case ENOSYS
: return make_error_condition( function_not_supported
);
223 case ENOTCONN
: return make_error_condition( not_connected
);
224 case ENOTDIR
: return make_error_condition( not_a_directory
);
225 # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value
226 case ENOTEMPTY
: return make_error_condition( directory_not_empty
);
227 # endif // ENOTEMPTY != EEXIST
228 # if ENOTRECOVERABLE != ECONNRESET // the same on some Broadcom chips
229 case ENOTRECOVERABLE
: return make_error_condition( state_not_recoverable
);
230 # endif // ENOTRECOVERABLE != ECONNRESET
231 case ENOTSOCK
: return make_error_condition( not_a_socket
);
232 case ENOTSUP
: return make_error_condition( not_supported
);
233 case ENOTTY
: return make_error_condition( inappropriate_io_control_operation
);
234 case ENXIO
: return make_error_condition( no_such_device_or_address
);
235 # if EOPNOTSUPP != ENOTSUP
236 case EOPNOTSUPP
: return make_error_condition( operation_not_supported
);
237 # endif // EOPNOTSUPP != ENOTSUP
238 case EOVERFLOW
: return make_error_condition( value_too_large
);
239 # if EOWNERDEAD != ECONNABORTED // the same on some Broadcom chips
240 case EOWNERDEAD
: return make_error_condition( owner_dead
);
241 # endif // EOWNERDEAD != ECONNABORTED
242 case EPERM
: return make_error_condition( operation_not_permitted
);
243 case EPIPE
: return make_error_condition( broken_pipe
);
244 case EPROTO
: return make_error_condition( protocol_error
);
245 case EPROTONOSUPPORT
: return make_error_condition( protocol_not_supported
);
246 case EPROTOTYPE
: return make_error_condition( wrong_protocol_type
);
247 case ERANGE
: return make_error_condition( result_out_of_range
);
248 case EROFS
: return make_error_condition( read_only_file_system
);
249 case ESPIPE
: return make_error_condition( invalid_seek
);
250 case ESRCH
: return make_error_condition( no_such_process
);
251 case ETIME
: return make_error_condition( stream_timeout
);
252 case ETIMEDOUT
: return make_error_condition( timed_out
);
253 case ETXTBSY
: return make_error_condition( text_file_busy
);
254 # if EAGAIN != EWOULDBLOCK
255 case EWOULDBLOCK
: return make_error_condition( operation_would_block
);
256 # endif // EAGAIN != EWOULDBLOCK
257 case EXDEV
: return make_error_condition( cross_device_link
);
259 // Windows system -> posix_errno decode table ---------------------------//
260 // see WinError.h comments for descriptions of errors
261 case ERROR_ACCESS_DENIED
: return make_error_condition( permission_denied
);
262 case ERROR_ALREADY_EXISTS
: return make_error_condition( file_exists
);
263 case ERROR_BAD_UNIT
: return make_error_condition( no_such_device
);
264 case ERROR_BUFFER_OVERFLOW
: return make_error_condition( filename_too_long
);
265 case ERROR_BUSY
: return make_error_condition( device_or_resource_busy
);
266 case ERROR_BUSY_DRIVE
: return make_error_condition( device_or_resource_busy
);
267 case ERROR_CANNOT_MAKE
: return make_error_condition( permission_denied
);
268 case ERROR_CANTOPEN
: return make_error_condition( io_error
);
269 case ERROR_CANTREAD
: return make_error_condition( io_error
);
270 case ERROR_CANTWRITE
: return make_error_condition( io_error
);
271 case ERROR_CURRENT_DIRECTORY
: return make_error_condition( permission_denied
);
272 case ERROR_DEV_NOT_EXIST
: return make_error_condition( no_such_device
);
273 case ERROR_DEVICE_IN_USE
: return make_error_condition( device_or_resource_busy
);
274 case ERROR_DIR_NOT_EMPTY
: return make_error_condition( directory_not_empty
);
275 case ERROR_DIRECTORY
: return make_error_condition( invalid_argument
); // WinError.h: "The directory name is invalid"
276 case ERROR_DISK_FULL
: return make_error_condition( no_space_on_device
);
277 case ERROR_FILE_EXISTS
: return make_error_condition( file_exists
);
278 case ERROR_FILE_NOT_FOUND
: return make_error_condition( no_such_file_or_directory
);
279 case ERROR_HANDLE_DISK_FULL
: return make_error_condition( no_space_on_device
);
280 case ERROR_INVALID_ACCESS
: return make_error_condition( permission_denied
);
281 case ERROR_INVALID_DRIVE
: return make_error_condition( no_such_device
);
282 case ERROR_INVALID_FUNCTION
: return make_error_condition( function_not_supported
);
283 case ERROR_INVALID_HANDLE
: return make_error_condition( invalid_argument
);
284 case ERROR_INVALID_NAME
: return make_error_condition( invalid_argument
);
285 case ERROR_LOCK_VIOLATION
: return make_error_condition( no_lock_available
);
286 case ERROR_LOCKED
: return make_error_condition( no_lock_available
);
287 case ERROR_NEGATIVE_SEEK
: return make_error_condition( invalid_argument
);
288 case ERROR_NOACCESS
: return make_error_condition( permission_denied
);
289 case ERROR_NOT_ENOUGH_MEMORY
: return make_error_condition( not_enough_memory
);
290 case ERROR_NOT_READY
: return make_error_condition( resource_unavailable_try_again
);
291 case ERROR_NOT_SAME_DEVICE
: return make_error_condition( cross_device_link
);
292 case ERROR_OPEN_FAILED
: return make_error_condition( io_error
);
293 case ERROR_OPEN_FILES
: return make_error_condition( device_or_resource_busy
);
294 case ERROR_OPERATION_ABORTED
: return make_error_condition( operation_canceled
);
295 case ERROR_OUTOFMEMORY
: return make_error_condition( not_enough_memory
);
296 case ERROR_PATH_NOT_FOUND
: return make_error_condition( no_such_file_or_directory
);
297 case ERROR_READ_FAULT
: return make_error_condition( io_error
);
298 case ERROR_RETRY
: return make_error_condition( resource_unavailable_try_again
);
299 case ERROR_SEEK
: return make_error_condition( io_error
);
300 case ERROR_SHARING_VIOLATION
: return make_error_condition( permission_denied
);
301 case ERROR_TOO_MANY_OPEN_FILES
: return make_error_condition( too_many_files_open
);
302 case ERROR_WRITE_FAULT
: return make_error_condition( io_error
);
303 case ERROR_WRITE_PROTECT
: return make_error_condition( permission_denied
);
304 case WSAEACCES
: return make_error_condition( permission_denied
);
305 case WSAEADDRINUSE
: return make_error_condition( address_in_use
);
306 case WSAEADDRNOTAVAIL
: return make_error_condition( address_not_available
);
307 case WSAEAFNOSUPPORT
: return make_error_condition( address_family_not_supported
);
308 case WSAEALREADY
: return make_error_condition( connection_already_in_progress
);
309 case WSAEBADF
: return make_error_condition( bad_file_descriptor
);
310 case WSAECONNABORTED
: return make_error_condition( connection_aborted
);
311 case WSAECONNREFUSED
: return make_error_condition( connection_refused
);
312 case WSAECONNRESET
: return make_error_condition( connection_reset
);
313 case WSAEDESTADDRREQ
: return make_error_condition( destination_address_required
);
314 case WSAEFAULT
: return make_error_condition( bad_address
);
315 case WSAEHOSTUNREACH
: return make_error_condition( host_unreachable
);
316 case WSAEINPROGRESS
: return make_error_condition( operation_in_progress
);
317 case WSAEINTR
: return make_error_condition( interrupted
);
318 case WSAEINVAL
: return make_error_condition( invalid_argument
);
319 case WSAEISCONN
: return make_error_condition( already_connected
);
320 case WSAEMFILE
: return make_error_condition( too_many_files_open
);
321 case WSAEMSGSIZE
: return make_error_condition( message_size
);
322 case WSAENAMETOOLONG
: return make_error_condition( filename_too_long
);
323 case WSAENETDOWN
: return make_error_condition( network_down
);
324 case WSAENETRESET
: return make_error_condition( network_reset
);
325 case WSAENETUNREACH
: return make_error_condition( network_unreachable
);
326 case WSAENOBUFS
: return make_error_condition( no_buffer_space
);
327 case WSAENOPROTOOPT
: return make_error_condition( no_protocol_option
);
328 case WSAENOTCONN
: return make_error_condition( not_connected
);
329 case WSAENOTSOCK
: return make_error_condition( not_a_socket
);
330 case WSAEOPNOTSUPP
: return make_error_condition( operation_not_supported
);
331 case WSAEPROTONOSUPPORT
: return make_error_condition( protocol_not_supported
);
332 case WSAEPROTOTYPE
: return make_error_condition( wrong_protocol_type
);
333 case WSAETIMEDOUT
: return make_error_condition( timed_out
);
334 case WSAEWOULDBLOCK
: return make_error_condition( operation_would_block
);
336 default: return error_condition( ev
, system_category() );
340 # if !defined( BOOST_WINDOWS_API )
342 std::string
system_error_category::message( int ev
) const
344 return generic_category().message( ev
);
348 std::string
system_error_category::message( int ev
) const
350 # ifndef BOOST_NO_ANSI_APIS
352 DWORD retval
= ::FormatMessageA(
353 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
354 FORMAT_MESSAGE_FROM_SYSTEM
|
355 FORMAT_MESSAGE_IGNORE_INSERTS
,
358 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), // Default language
363 detail::local_free_on_destruction
lfod(lpMsgBuf
);
365 return std::string("Unknown error");
367 std::string
str( static_cast<LPCSTR
>(lpMsgBuf
) );
368 # else // WinCE workaround
370 DWORD retval
= ::FormatMessageW(
371 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
372 FORMAT_MESSAGE_FROM_SYSTEM
|
373 FORMAT_MESSAGE_IGNORE_INSERTS
,
376 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), // Default language
381 detail::local_free_on_destruction
lfod(lpMsgBuf
);
383 return std::string("Unknown error");
385 int num_chars
= (wcslen( static_cast<LPCWSTR
>(lpMsgBuf
) ) + 1) * 2;
386 LPSTR narrow_buffer
= (LPSTR
)_alloca( num_chars
);
387 if (::WideCharToMultiByte(CP_ACP
, 0, static_cast<LPCWSTR
>(lpMsgBuf
), -1, narrow_buffer
, num_chars
, NULL
, NULL
) == 0)
388 return std::string("Unknown error");
390 std::string
str( narrow_buffer
);
393 && (str
[str
.size()-1] == '\n' || str
[str
.size()-1] == '\r') )
394 str
.erase( str
.size()-1 );
395 if ( str
.size() && str
[str
.size()-1] == '.' )
396 { str
.erase( str
.size()-1 ); }
401 } // unnamed namespace
408 # ifndef BOOST_SYSTEM_NO_DEPRECATED
409 BOOST_SYSTEM_DECL error_code throws
; // "throw on error" special error_code;
410 // note that it doesn't matter if this
411 // isn't initialized before use since
412 // the only use is to take its
413 // address for comparison purposes
416 BOOST_SYSTEM_DECL
const error_category
& system_category()
418 static const system_error_category system_category_const
;
419 return system_category_const
;
422 BOOST_SYSTEM_DECL
const error_category
& generic_category()
424 static const generic_error_category generic_category_const
;
425 return generic_category_const
;
428 } // namespace system