system: reduce chance of message() throwing in response to ticket #2098

[SVN r49093]
This commit is contained in:
Beman Dawes
2008-10-01 18:57:48 +00:00
parent 84ff2d0f04
commit 463cefcf94

View File

@@ -61,11 +61,12 @@ namespace
const char * generic_error_category::name() const
{
return "GENERIC";
return "generic";
}
std::string generic_error_category::message( int ev ) const
{
static std::string unknown_err( "Unknown error" );
// strerror_r is preferred because it is always thread safe,
// however, we fallback to strerror in certain cases because:
// -- Windows doesn't provide strerror_r.
@@ -81,15 +82,19 @@ namespace
|| (defined(__osf__) && !defined(_REENTRANT))\
|| (defined(__vms))
const char * c_str = std::strerror( ev );
return std::string( c_str ? c_str : "Unknown error" );
# else
return c_str
? std::string( c_str )
: unknown_err;
# else // use strerror_r
char buf[64];
char * bp = buf;
std::size_t sz = sizeof(buf);
# if defined(__CYGWIN__) || defined(__USE_GNU)
// Oddball version of strerror_r
const char * c_str = strerror_r( ev, bp, sz );
return std::string( c_str ? c_str : "Unknown error" );
return c_str
? std::string( c_str )
: unknown_err;
# else
// POSIX version of strerror_r
int result;
@@ -100,7 +105,9 @@ namespace
# if defined (__sgi)
const char * c_str = strerror( ev );
result = 0;
return std::string( c_str ? c_str : "Unknown error" );
return c_str
? std::string( c_str )
: unknown_err;
# else
result = strerror_r( ev, bp, sz );
# endif
@@ -113,26 +120,27 @@ namespace
result = errno;
# endif
if ( result != ERANGE ) break;
if ( sz > sizeof(buf) ) std::free( bp );
sz *= 2;
if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 )
return std::string( "ENOMEM" );
if ( sz > sizeof(buf) ) std::free( bp );
sz *= 2;
if ( (bp = static_cast<char*>(std::malloc( sz ))) == 0 )
return std::string( "ENOMEM" );
}
}
std::string msg();
try
{
std::string msg( ( result == invalid_argument ) ? "Unknown error" : bp );
if ( sz > sizeof(buf) ) std::free( bp );
sz = 0;
return msg;
msg = ( ( result == invalid_argument ) ? "Unknown error" : bp );
}
catch(...)
{
if ( sz > sizeof(buf) ) std::free( bp );
throw;
// just eat the exception
}
# endif
# endif
if ( sz > sizeof(buf) ) std::free( bp );
sz = 0;
return msg;
# endif // else POSIX version of strerror_r
# endif // else use strerror_r
}
// system_error_category implementation --------------------------------//