error_code.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define _CRT_SECURE_NO_DEPRECATE
00019 #define _SCL_SECURE_NO_DEPRECATE
00020
00021
00022
00023 #define BOOST_SYSTEM_SOURCE
00024
00025 #include <boost/system/config.hpp>
00026 #include <boost/system/error_code.hpp>
00027 #include <boost/cerrno.hpp>
00028 #include <vector>
00029 #include <cstdlib>
00030 #include <cassert>
00031
00032 using namespace boost::system;
00033 using namespace boost::system::posix_error;
00034
00035 #include <cstring>
00036
00037 # if defined( BOOST_WINDOWS_API )
00038 # include <windows.h>
00039 # ifndef ERROR_INCORRECT_SIZE
00040 # define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
00041 # endif
00042 # endif
00043
00044
00045
00046 namespace
00047 {
00048
00049
00050 class posix_error_category : public error_category
00051 {
00052 public:
00053 posix_error_category(){}
00054 const char * name() const;
00055 std::string message( int ev ) const;
00056 };
00057
00058 class system_error_category : public error_category
00059 {
00060 public:
00061 system_error_category(){}
00062 const char * name() const;
00063 std::string message( int ev ) const;
00064 error_condition default_error_condition( int ev ) const;
00065 };
00066
00067
00068
00069 const char * posix_error_category::name() const
00070 {
00071 return "POSIX";
00072 }
00073
00074 std::string posix_error_category::message( int ev ) const
00075 {
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 # if defined(BOOST_WINDOWS_API) || defined(__hpux) || defined(__sun)\
00087 || (defined(__linux) && (!defined(__USE_XOPEN2K) || defined(BOOST_SYSTEM_USE_STRERROR)))\
00088 || (defined(__osf__) && !defined(_REENTRANT))\
00089 || (defined(__vms))
00090 const char * c_str = std::strerror( ev );
00091 return std::string( c_str ? c_str : "Unknown error" );
00092 # else
00093 char buf[64];
00094 char * bp = buf;
00095 std::size_t sz = sizeof(buf);
00096 # if defined(__CYGWIN__) || defined(__USE_GNU)
00097
00098 const char * c_str = strerror_r( ev, bp, sz );
00099 return std::string( c_str ? c_str : "Unknown error" );
00100 # else
00101
00102 int result;
00103 for (;;)
00104 {
00105
00106
00107 # if defined (__sgi)
00108 const char * c_str = strerror( ev );
00109 result = 0;
00110 return std::string( c_str ? c_str : "Unknown error" );
00111 # else
00112 result = strerror_r( ev, bp, sz );
00113 # endif
00114 if (result == 0 )
00115 break;
00116 else
00117 {
00118 # if defined(__linux)
00119
00120 result = errno;
00121 # endif
00122 if ( result != ERANGE ) break;
00123 if ( sz > sizeof(buf) ) std::free( bp );
00124 sz *= 2;
00125 if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 )
00126 return std::string( "ENOMEM" );
00127 }
00128 }
00129 try
00130 {
00131 std::string msg( ( result == invalid_argument ) ? "Unknown error" : bp );
00132 if ( sz > sizeof(buf) ) std::free( bp );
00133 sz = 0;
00134 return msg;
00135 }
00136 catch(...)
00137 {
00138 if ( sz > sizeof(buf) ) std::free( bp );
00139 throw;
00140 }
00141 # endif
00142 # endif
00143 }
00144
00145
00146 const char * system_error_category::name() const
00147 {
00148 return "system";
00149 }
00150
00151 error_condition system_error_category::default_error_condition( int ev ) const
00152 {
00153 switch ( ev )
00154 {
00155 case 0: return make_error_condition( success );
00156 # if defined(BOOST_POSIX_API)
00157
00158 case E2BIG: return make_error_condition( argument_list_too_long );
00159 case EACCES: return make_error_condition( permission_denied );
00160 case EADDRINUSE: return make_error_condition( address_in_use );
00161 case EADDRNOTAVAIL: return make_error_condition( address_not_available );
00162 case EAFNOSUPPORT: return make_error_condition( address_family_not_supported );
00163 case EAGAIN: return make_error_condition( resource_unavailable_try_again );
00164 case EALREADY: return make_error_condition( connection_already_in_progress );
00165 case EBADF: return make_error_condition( bad_file_descriptor );
00166 case EBADMSG: return make_error_condition( bad_message );
00167 case EBUSY: return make_error_condition( device_or_resource_busy );
00168 case ECANCELED: return make_error_condition( operation_canceled );
00169 case ECHILD: return make_error_condition( no_child_process );
00170 case ECONNABORTED: return make_error_condition( connection_aborted );
00171 case ECONNREFUSED: return make_error_condition( connection_refused );
00172 case ECONNRESET: return make_error_condition( connection_reset );
00173 case EDEADLK: return make_error_condition( resource_deadlock_would_occur );
00174 case EDESTADDRREQ: return make_error_condition( destination_address_required );
00175 case EDOM: return make_error_condition( argument_out_of_domain );
00176 case EEXIST: return make_error_condition( file_exists );
00177 case EFAULT: return make_error_condition( bad_address );
00178 case EFBIG: return make_error_condition( file_too_large );
00179 case EHOSTUNREACH: return make_error_condition( host_unreachable );
00180 case EIDRM: return make_error_condition( identifier_removed );
00181 case EILSEQ: return make_error_condition( illegal_byte_sequence );
00182 case EINPROGRESS: return make_error_condition( operation_in_progress );
00183 case EINTR: return make_error_condition( interrupted );
00184 case EINVAL: return make_error_condition( invalid_argument );
00185 case EIO: return make_error_condition( io_error );
00186 case EISCONN: return make_error_condition( already_connected );
00187 case EISDIR: return make_error_condition( is_a_directory );
00188 case ELOOP: return make_error_condition( too_many_synbolic_link_levels );
00189 case EMFILE: return make_error_condition( too_many_files_open );
00190 case EMLINK: return make_error_condition( too_many_links );
00191 case EMSGSIZE: return make_error_condition( message_size );
00192 case ENAMETOOLONG: return make_error_condition( filename_too_long );
00193 case ENETDOWN: return make_error_condition( network_down );
00194 case ENETRESET: return make_error_condition( network_reset );
00195 case ENETUNREACH: return make_error_condition( network_unreachable );
00196 case ENFILE: return make_error_condition( too_many_files_open_in_system );
00197 case ENOBUFS: return make_error_condition( no_buffer_space );
00198 case ENODATA: return make_error_condition( no_message_available );
00199 case ENODEV: return make_error_condition( no_such_device );
00200 case ENOENT: return make_error_condition( no_such_file_or_directory );
00201 case ENOEXEC: return make_error_condition( executable_format_error );
00202 case ENOLCK: return make_error_condition( no_lock_available );
00203 case ENOLINK: return make_error_condition( no_link );
00204 case ENOMEM: return make_error_condition( not_enough_memory );
00205 case ENOMSG: return make_error_condition( no_message );
00206 case ENOPROTOOPT: return make_error_condition( no_protocol_option );
00207 case ENOSPC: return make_error_condition( no_space_on_device );
00208 case ENOSR: return make_error_condition( no_stream_resources );
00209 case ENOSTR: return make_error_condition( not_a_stream );
00210 case ENOSYS: return make_error_condition( function_not_supported );
00211 case ENOTCONN: return make_error_condition( not_connected );
00212 case ENOTDIR: return make_error_condition( not_a_directory );
00213 # if ENOTEMPTY != EEXIST // AIX treats ENOTEMPTY and EEXIST as the same value
00214 case ENOTEMPTY: return make_error_condition( directory_not_empty );
00215 # endif // ENOTEMPTY != EEXIST
00216 case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable );
00217 case ENOTSOCK: return make_error_condition( not_a_socket );
00218 case ENOTSUP: return make_error_condition( not_supported );
00219 case ENOTTY: return make_error_condition( inappropriate_io_control_operation );
00220 case ENXIO: return make_error_condition( no_such_device_or_address );
00221 # if EOPNOTSUPP != ENOTSUP
00222 case EOPNOTSUPP: return make_error_condition( operation_not_supported );
00223 # endif // EOPNOTSUPP != ENOTSUP
00224 case EOVERFLOW: return make_error_condition( value_too_large );
00225 case EOWNERDEAD: return make_error_condition( owner_dead );
00226 case EPERM: return make_error_condition( operation_not_permitted );
00227 case EPIPE: return make_error_condition( broken_pipe );
00228 case EPROTO: return make_error_condition( protocol_error );
00229 case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
00230 case EPROTOTYPE: return make_error_condition( wrong_protocol_type );
00231 case ERANGE: return make_error_condition( result_out_of_range );
00232 case EROFS: return make_error_condition( read_only_file_system );
00233 case ESPIPE: return make_error_condition( invalid_seek );
00234 case ESRCH: return make_error_condition( no_such_process );
00235 case ETIME: return make_error_condition( stream_timeout );
00236 case ETIMEDOUT: return make_error_condition( timed_out );
00237 case ETXTBSY: return make_error_condition( text_file_busy );
00238 # if EAGAIN != EWOULDBLOCK
00239 case EWOULDBLOCK: return make_error_condition( operation_would_block );
00240 # endif // EAGAIN != EWOULDBLOCK
00241 case EXDEV: return make_error_condition( cross_device_link );
00242 #else
00243
00244
00245 case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied );
00246 case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists );
00247 case ERROR_BAD_UNIT: return make_error_condition( no_such_device );
00248 case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long );
00249 case ERROR_BUSY: return make_error_condition( device_or_resource_busy );
00250 case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy );
00251 case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied );
00252 case ERROR_CANTOPEN: return make_error_condition( io_error );
00253 case ERROR_CANTREAD: return make_error_condition( io_error );
00254 case ERROR_CANTWRITE: return make_error_condition( io_error );
00255 case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied );
00256 case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device );
00257 case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy );
00258 case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty );
00259 case ERROR_DIRECTORY: return make_error_condition( invalid_argument );
00260 case ERROR_DISK_FULL: return make_error_condition( no_space_on_device );
00261 case ERROR_FILE_EXISTS: return make_error_condition( file_exists );
00262 case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
00263 case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device );
00264 case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied );
00265 case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device );
00266 case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported );
00267 case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument );
00268 case ERROR_INVALID_NAME: return make_error_condition( invalid_argument );
00269 case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available );
00270 case ERROR_LOCKED: return make_error_condition( no_lock_available );
00271 case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument );
00272 case ERROR_NOACCESS: return make_error_condition( permission_denied );
00273 case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory );
00274 case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again );
00275 case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link );
00276 case ERROR_OPEN_FAILED: return make_error_condition( io_error );
00277 case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy );
00278 case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled );
00279 case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory );
00280 case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
00281 case ERROR_READ_FAULT: return make_error_condition( io_error );
00282 case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again );
00283 case ERROR_SEEK: return make_error_condition( io_error );
00284 case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied );
00285 case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open );
00286 case ERROR_WRITE_FAULT: return make_error_condition( io_error );
00287 case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied );
00288 case WSAEACCES: return make_error_condition( permission_denied );
00289 case WSAEADDRINUSE: return make_error_condition( address_in_use );
00290 case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available );
00291 case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported );
00292 case WSAEALREADY: return make_error_condition( connection_already_in_progress );
00293 case WSAEBADF: return make_error_condition( bad_file_descriptor );
00294 case WSAECONNABORTED: return make_error_condition( connection_aborted );
00295 case WSAECONNREFUSED: return make_error_condition( connection_refused );
00296 case WSAECONNRESET: return make_error_condition( connection_reset );
00297 case WSAEDESTADDRREQ: return make_error_condition( destination_address_required );
00298 case WSAEFAULT: return make_error_condition( bad_address );
00299 case WSAEHOSTUNREACH: return make_error_condition( host_unreachable );
00300 case WSAEINPROGRESS: return make_error_condition( operation_in_progress );
00301 case WSAEINTR: return make_error_condition( interrupted );
00302 case WSAEINVAL: return make_error_condition( invalid_argument );
00303 case WSAEISCONN: return make_error_condition( already_connected );
00304 case WSAEMFILE: return make_error_condition( too_many_files_open );
00305 case WSAEMSGSIZE: return make_error_condition( message_size );
00306 case WSAENAMETOOLONG: return make_error_condition( filename_too_long );
00307 case WSAENETDOWN: return make_error_condition( network_down );
00308 case WSAENETRESET: return make_error_condition( network_reset );
00309 case WSAENETUNREACH: return make_error_condition( network_unreachable );
00310 case WSAENOBUFS: return make_error_condition( no_buffer_space );
00311 case WSAENOPROTOOPT: return make_error_condition( no_protocol_option );
00312 case WSAENOTCONN: return make_error_condition( not_connected );
00313 case WSAENOTSOCK: return make_error_condition( not_a_socket );
00314 case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported );
00315 case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
00316 case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type );
00317 case WSAETIMEDOUT: return make_error_condition( timed_out );
00318 case WSAEWOULDBLOCK: return make_error_condition( operation_would_block );
00319 #endif
00320 default: return error_condition( ev, system_category );
00321 }
00322 }
00323
00324 # if !defined( BOOST_WINDOWS_API )
00325
00326 std::string system_error_category::message( int ev ) const
00327 {
00328 return posix_category.message( ev );
00329 }
00330 # else
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 std::string system_error_category::message( int ev ) const
00347 {
00348 # ifndef BOOST_NO_ANSI_APIS
00349 LPVOID lpMsgBuf;
00350 DWORD retval = ::FormatMessageA(
00351 FORMAT_MESSAGE_ALLOCATE_BUFFER |
00352 FORMAT_MESSAGE_FROM_SYSTEM |
00353 FORMAT_MESSAGE_IGNORE_INSERTS,
00354 NULL,
00355 ev,
00356 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00357 (LPSTR) &lpMsgBuf,
00358 0,
00359 NULL
00360 );
00361 if (retval == 0)
00362 return std::string("Unknown error");
00363
00364 std::string str( static_cast<LPCSTR>(lpMsgBuf) );
00365 ::LocalFree( lpMsgBuf );
00366 # else // WinCE workaround
00367 LPVOID lpMsgBuf;
00368 DWORD retval = ::FormatMessageW(
00369 FORMAT_MESSAGE_ALLOCATE_BUFFER |
00370 FORMAT_MESSAGE_FROM_SYSTEM |
00371 FORMAT_MESSAGE_IGNORE_INSERTS,
00372 NULL,
00373 ev,
00374 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00375 (LPWSTR) &lpMsgBuf,
00376 0,
00377 NULL
00378 );
00379 if (retval == 0)
00380 return std::string("Unknown error");
00381
00382 int num_chars = (wcslen( static_cast<LPCWSTR>(lpMsgBuf) ) + 1) * 2;
00383 LPSTR narrow_buffer = (LPSTR)_alloca( num_chars );
00384 if (::WideCharToMultiByte(CP_ACP, 0, static_cast<LPCWSTR>(lpMsgBuf), -1, narrow_buffer, num_chars, NULL, NULL) == 0)
00385 return std::string("Unknown error");
00386
00387 std::string str( narrow_buffer );
00388 ::LocalFree( lpMsgBuf );
00389 # endif
00390 while ( str.size()
00391 && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
00392 str.erase( str.size()-1 );
00393 if ( str.size() && str[str.size()-1] == '.' )
00394 { str.erase( str.size()-1 ); }
00395 return str;
00396 }
00397 # endif
00398
00399 }
00400
00401 namespace boost
00402 {
00403 namespace system
00404 {
00405
00406 BOOST_SYSTEM_DECL const error_category & get_system_category()
00407 {
00408 static const system_error_category system_category_const;
00409 return system_category_const;
00410 }
00411
00412 BOOST_SYSTEM_DECL const error_category & get_posix_category()
00413 {
00414 static const posix_error_category posix_category_const;
00415 return posix_category_const;
00416 }
00417
00418 }
00419 }