Since I hadn't, I decided that I should. The change in implementation to use strerror_s() (when in the presence of the "safe string" library) goes along the lines of the following
char buff[1001];
if(0 != ::strerror_s(buff,
STLSOFT_NUM_ELEMENTS(buff) - 1, errno))
{
buff[0] = '\0';
}
else
{
buff[STLSOFT_NUM_ELEMENTS(buff) - 1] = '\0';
}
The dumb part of the strerror_s() function is that it doesn't tell you how many characters were received. This means that you cannot rely on having elicited the full message unless ::strlen() over the returned string is less than (buffer size - 1). So, the above code could return a partial error string (although the likelihood of that is, of course, vanishingly small).
Instead, what I've done is used an auto_buffer to provide resizable storage, and then strerror_s() is called in a loop until either it fails, or no more storage can be allocated, or the length of the returned string is less than (buffer size - 1). The code looks like the following:
stlsoft::auto_bufferbuff(128);
for(;;)
{
int n = ::strerror_s(&buff[0], buff.size() - 1, error);
buff[buff.size() - 1u] = '\0';
if(0 == n)
{
size_t cch = ::strlen(buff.data());
if(cch < buff.size() - 2u)
{
m_length = cch;
buff.resize(cch + 1u);
break;
}
}
if(!buff.resize(1u + buff.size() * 2u))
{
buff.resize(1u);
break;
}
}
There's another problem with the class template, but that'll have to wait until a later time to discuss ...
No comments:
Post a Comment