aboutsummaryrefslogtreecommitdiff
path: root/src/netbase.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2014-05-08 14:15:19 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2014-05-23 09:45:04 +0200
commita60838d09aed4d976e9343e8329d61afff204435 (patch)
treebb7d9b040b6d8b77c3d57fd8abd903ae02d19231 /src/netbase.cpp
parent8cd900711c0396ac3a96ffd40f43f0e9ec76fadb (diff)
downloadbitcoin-a60838d09aed4d976e9343e8329d61afff204435.tar.xz
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.
Diffstat (limited to 'src/netbase.cpp')
-rw-r--r--src/netbase.cpp41
1 files changed, 37 insertions, 4 deletions
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 82a681281d..e24a0a195c 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -361,7 +361,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;
}
@@ -372,13 +372,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;
}
@@ -389,7 +389,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;
}
@@ -1237,3 +1237,36 @@ bool operator!=(const CSubNet& a, const CSubNet& b)
{
return !(a==b);
}
+
+#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