Replace non-threadsafe strerror

Log the name of the error as well as the error code if a network problem
happens. This makes network troubleshooting more convenient.

Use thread-safe strerror_r and the WIN32 equivalent FormatMessage.

Conflicts:
	src/netbase.cpp

Rebased-By: Wladimir van der Laan <laanwj@gmail.com>
Rebased-From: a60838d
This commit is contained in:
Wladimir J. van der Laan 2014-05-08 14:15:19 +02:00
parent 2585310a22
commit e0036e9f0e
No known key found for this signature in database
GPG key ID: 74810B012346C9A6
4 changed files with 54 additions and 16 deletions

View file

@ -363,7 +363,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
}
if (nRet == SOCKET_ERROR)
{
LogPrintf("select() for %s failed: %i\n", addrConnect.ToString(), WSAGetLastError());
LogPrintf("select() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
closesocket(hSocket);
return false;
}
@ -374,13 +374,13 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
#endif
{
LogPrintf("getsockopt() for %s failed: %i\n", addrConnect.ToString(), WSAGetLastError());
LogPrintf("getsockopt() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
closesocket(hSocket);
return false;
}
if (nRet != 0)
{
LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), strerror(nRet));
LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet));
closesocket(hSocket);
return false;
}
@ -391,7 +391,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
else
#endif
{
LogPrintf("connect() to %s failed: %i\n", addrConnect.ToString(), WSAGetLastError());
LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
closesocket(hSocket);
return false;
}
@ -1122,3 +1122,37 @@ void CService::SetPort(unsigned short portIn)
{
port = portIn;
}
#ifdef WIN32
std::string NetworkErrorString(int err)
{
char buf[256];
buf[0] = 0;
if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
buf, sizeof(buf), NULL))
{
return strprintf("%s (%d)", buf, err);
}
else
{
return strprintf("Unknown error (%d)", err);
}
}
#else
std::string NetworkErrorString(int err)
{
char buf[256];
const char *s = buf;
buf[0] = 0;
/* Too bad there are two incompatible implementations of the
* thread-safe strerror. */
#ifdef STRERROR_R_CHAR_P /* GNU variant can return a pointer outside the passed buffer */
s = strerror_r(err, buf, sizeof(buf));
#else /* POSIX variant always returns message in buffer */
(void) strerror_r(err, buf, sizeof(buf));
#endif
return strprintf("%s (%d)", s, err);
}
#endif