another attempt at strerror_r(), using C++ power

This commit is contained in:
Guenter Obiltschnig 2017-02-14 14:49:15 +01:00
parent 1435c9ad97
commit 3de2358bdf

View File

@ -26,6 +26,8 @@ namespace Poco {
#ifdef POCO_OS_FAMILY_WINDOWS
DWORD Error::last()
{
return GetLastError();
@ -49,35 +51,68 @@ namespace Poco {
return errMsg;
}
#else
int Error::last()
{
return errno;
}
class StrErrorHelper
/// This little hack magically handles all variants
/// of strerror_r() (POSIX and GLIBC) and strerror().
{
public:
explicit StrErrorHelper(int err)
{
_buffer[0] = 0;
#if (_XOPEN_SOURCE >= 600) || POCO_ANDROID || __APPLE__
setMessage(strerror_r(err, _buffer, sizeof(_buffer)));
#elif _GNU_SOURCE
setMessage(strerror_r(err, _buffer, sizeof(_buffer)));
#else
setMessage(strerror(err));
#endif
}
~StrErrorHelper()
{
}
const std::string& message() const
{
return _message;
}
protected:
void setMessage(int rc)
/// Handles POSIX variant
{
_message = _buffer;
}
void setMessage(const char* msg)
/// Handles GLIBC variant
{
_message = msg;
}
private:
char _buffer[256];
std::string _message;
};
std::string Error::getMessage(int errorCode)
{
/* Reentrant version of `strerror'.
There are 2 flavors of `strerror_r', GNU which returns the string
and may or may not use the supplied temporary buffer and POSIX one
which fills the string into the buffer.
To use the POSIX version, -D_XOPEN_SOURCE=600 or -D_POSIX_C_SOURCE=200112L
without -D_GNU_SOURCE is needed, otherwise the GNU version is
preferred.
*/
#if (_XOPEN_SOURCE >= 600) || POCO_ANDROID
char errmsg[256] = "";
strerror_r(errorCode, errmsg, 256);
return errmsg;
#elif defined _GNU_SOURCE
char errmsg[256] = "";
return std::string(strerror_r(errorCode, errmsg, 256));
#else
return std::string(strerror(errorCode));
#endif
StrErrorHelper helper(errorCode);
return helper.message();
}
#endif