aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2016-03-25 20:50:35 +0000
committerVincent Richard <[email protected]>2016-03-25 20:50:35 +0000
commit08a3ba2ba1d753ac75698270c8bb84560ff1d825 (patch)
treee581a15812892003c7ab24ffb7f3266936b8bcbf
parentFixed location of config and lib export include files. (diff)
downloadvmime-08a3ba2ba1d753ac75698270c8bb84560ff1d825.tar.gz
vmime-08a3ba2ba1d753ac75698270c8bb84560ff1d825.zip
Misc fixes in error handling.
-rw-r--r--CMakeLists.txt2
-rw-r--r--cmake/config.hpp.cmake1
-rw-r--r--src/vmime/platforms/posix/posixSocket.cpp77
3 files changed, 64 insertions, 16 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 797a383e..4b5231e6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -978,6 +978,8 @@ CHECK_SYMBOL_EXISTS(SYS_gettid sys/syscall.h VMIME_HAVE_SYSCALL_GETTID)
CHECK_SYMBOL_EXISTS(SO_KEEPALIVE sys/socket.h VMIME_HAVE_SO_KEEPALIVE)
+CHECK_SYMBOL_EXISTS(strerror_r string.h VMIME_HAVE_STRERROR_R)
+
FIND_PACKAGE(Threads)
IF(VMIME_BUILD_SHARED_LIBRARY)
diff --git a/cmake/config.hpp.cmake b/cmake/config.hpp.cmake
index 219d1000..bb24239d 100644
--- a/cmake/config.hpp.cmake
+++ b/cmake/config.hpp.cmake
@@ -84,6 +84,7 @@ typedef unsigned @VMIME_64BIT_TYPE@ vmime_uint64;
#cmakedefine01 VMIME_HAVE_GMTIME_R
#cmakedefine01 VMIME_HAVE_LOCALTIME_S
#cmakedefine01 VMIME_HAVE_LOCALTIME_R
+#cmakedefine01 VMIME_HAVE_STRERROR_R
#cmakedefine01 VMIME_HAVE_MLANG
#cmakedefine01 VMIME_HAVE_SO_KEEPALIVE
#cmakedefine01 VMIME_SHARED_PTR_USE_CXX
diff --git a/src/vmime/platforms/posix/posixSocket.cpp b/src/vmime/platforms/posix/posixSocket.cpp
index b0e7e6fd..6ea9febe 100644
--- a/src/vmime/platforms/posix/posixSocket.cpp
+++ b/src/vmime/platforms/posix/posixSocket.cpp
@@ -114,8 +114,8 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port
m_timeoutHandler->resetTimeOut();
for (struct ::addrinfo* curAddrInfo = addrInfo ;
- sock == -1 && curAddrInfo != NULL ;
- curAddrInfo = curAddrInfo->ai_next, connectErrno = ETIMEDOUT)
+ sock == -1 && curAddrInfo != NULL ;
+ curAddrInfo = curAddrInfo->ai_next, connectErrno = ETIMEDOUT)
{
if (curAddrInfo->ai_family != AF_INET && curAddrInfo->ai_family != AF_INET6)
continue;
@@ -422,8 +422,26 @@ void posixSocket::resolve(struct ::addrinfo** addrInfo, const vmime::string& add
}
else if (gaiError != EAI_AGAIN)
{
- throw vmime::exceptions::connection_error
- ("gai_suspend() failed: " + std::string(gai_strerror(gaiError)));
+ if (gaiError == EAI_SYSTEM)
+ {
+ if (errno != 0)
+ {
+ try
+ {
+ throwSocketError(errno);
+ }
+ catch (exceptions::socket_exception& e)
+ {
+ throw vmime::exceptions::connection_error
+ ("Error while connecting socket.", e);
+ }
+ }
+ }
+ else
+ {
+ throw vmime::exceptions::connection_error
+ ("gai_suspend() failed: " + std::string(gai_strerror(gaiError)));
+ }
}
// Check for timeout
@@ -616,7 +634,7 @@ bool posixSocket::waitForData(const bool read, const bool write, const int msecs
// No data available at this time
// Check if we are timed out
if (m_timeoutHandler &&
- m_timeoutHandler->isTimeOut())
+ m_timeoutHandler->isTimeOut())
{
if (!m_timeoutHandler->handleTimeOut())
{
@@ -677,7 +695,7 @@ size_t posixSocket::receiveRaw(byte_t* buffer, const size_t count)
// Check if we are timed out
if (m_timeoutHandler &&
- m_timeoutHandler->isTimeOut())
+ m_timeoutHandler->isTimeOut())
{
if (!m_timeoutHandler->handleTimeOut())
{
@@ -767,7 +785,7 @@ size_t posixSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count)
// Check if we are timed out
if (m_timeoutHandler &&
- m_timeoutHandler->isTimeOut())
+ m_timeoutHandler->isTimeOut())
{
if (!m_timeoutHandler->handleTimeOut())
{
@@ -797,7 +815,7 @@ size_t posixSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count)
void posixSocket::throwSocketError(const int err)
{
- string msg;
+ const char* msg = NULL;
switch (err)
{
@@ -815,19 +833,46 @@ void posixSocket::throwSocketError(const int err)
case EMSGSIZE: msg = "EMSGSIZE: message cannot be sent atomically"; break;
case ENOBUFS: msg = "ENOBUFS: output queue is full"; break;
case ENOMEM: msg = "ENOMEM: out of memory"; break;
- case EPIPE:
+ case EPIPE: msg = "EPIPE: broken pipe"; break;
case ENOTCONN: msg = "ENOTCONN: not connected"; break;
case ECONNREFUSED: msg = "ECONNREFUSED: connection refused"; break;
- default:
-
- std::ostringstream oss;
- oss << ::strerror(err);
+ }
- msg = oss.str();
- break;
+ if (msg)
+ {
+ throw exceptions::socket_exception(msg);
}
+ else
+ {
+
+ // Use strerror() to get string describing error number
+
+#if VMIME_HAVE_STRERROR_R
+
+ char errbuf[512];
+
+ #if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
+
+ // XSI-compliant strerror_r()
+ strerror_r(err, errbuf, sizeof(errbuf));
+ throw exceptions::socket_exception(errbuf);
- throw exceptions::socket_exception(msg);
+ #else
+
+ // GNU-specific strerror_r()
+ const std::string strmsg(strerror_r(err, errbuf, sizeof(errbuf)));
+ throw exceptions::socket_exception(strmsg);
+
+ #endif
+
+#else // !VMIME_HAVE_STRERROR_R
+
+ const std::string strmsg(strerror(err));
+ throw exceptions::socket_exception(strmsg);
+
+#endif // VMIME_HAVE_STRERROR_R
+
+ }
}