Error handling in posixSocket::send().
This commit is contained in:
parent
a530f25c79
commit
658fcc26b5
@ -328,13 +328,27 @@ exception* net_exception::clone() const { return new net_exception(*this); }
|
|||||||
const char* net_exception::name() const throw() { return "net_exception"; }
|
const char* net_exception::name() const throw() { return "net_exception"; }
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// socket_exception
|
||||||
|
//
|
||||||
|
|
||||||
|
socket_exception::~socket_exception() throw() {}
|
||||||
|
socket_exception::socket_exception(const string& what, const exception& other)
|
||||||
|
: net_exception(what.empty()
|
||||||
|
? "Socket error."
|
||||||
|
: "Socket error: '" + what + "'.", other) {}
|
||||||
|
|
||||||
|
exception* socket_exception::clone() const { return new socket_exception(*this); }
|
||||||
|
const char* socket_exception::name() const throw() { return "socket_exception"; }
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// connection_error
|
// connection_error
|
||||||
//
|
//
|
||||||
|
|
||||||
connection_error::~connection_error() throw() {}
|
connection_error::~connection_error() throw() {}
|
||||||
connection_error::connection_error(const string& what, const exception& other)
|
connection_error::connection_error(const string& what, const exception& other)
|
||||||
: net_exception(what.empty()
|
: socket_exception(what.empty()
|
||||||
? "Connection error."
|
? "Connection error."
|
||||||
: "Connection error: '" + what + "'.", other) {}
|
: "Connection error: '" + what + "'.", other) {}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "vmime/exception.hpp"
|
#include "vmime/exception.hpp"
|
||||||
|
|
||||||
@ -90,16 +92,34 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port
|
|||||||
m_desc = ::socket(AF_INET, SOCK_STREAM, 0);
|
m_desc = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
if (m_desc == -1)
|
if (m_desc == -1)
|
||||||
throw vmime::exceptions::connection_error("Error while creating socket.");
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throwSocketError(errno);
|
||||||
|
}
|
||||||
|
catch (exceptions::socket_exception& e)
|
||||||
|
{
|
||||||
|
throw vmime::exceptions::connection_error
|
||||||
|
("Error while creating socket.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start connection
|
// Start connection
|
||||||
if (::connect(m_desc, reinterpret_cast <sockaddr*>(&addr), sizeof(addr)) == -1)
|
if (::connect(m_desc, reinterpret_cast <sockaddr*>(&addr), sizeof(addr)) == -1)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throwSocketError(errno);
|
||||||
|
}
|
||||||
|
catch (exceptions::socket_exception& e)
|
||||||
{
|
{
|
||||||
::close(m_desc);
|
::close(m_desc);
|
||||||
m_desc = -1;
|
m_desc = -1;
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
throw vmime::exceptions::connection_error("Error while connecting socket.");
|
throw vmime::exceptions::connection_error
|
||||||
|
("Error while connecting socket.", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,16 +176,53 @@ const int posixSocket::receiveRaw(char* buffer, const int count)
|
|||||||
|
|
||||||
void posixSocket::send(const vmime::string& buffer)
|
void posixSocket::send(const vmime::string& buffer)
|
||||||
{
|
{
|
||||||
::send(m_desc, buffer.data(), buffer.length(), 0);
|
if (::send(m_desc, buffer.data(), buffer.length(), 0) == -1)
|
||||||
|
throwSocketError(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void posixSocket::sendRaw(const char* buffer, const int count)
|
void posixSocket::sendRaw(const char* buffer, const int count)
|
||||||
{
|
{
|
||||||
::send(m_desc, buffer, count, 0);
|
if (::send(m_desc, buffer, count, 0) == -1)
|
||||||
|
throwSocketError(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void posixSocket::throwSocketError(const int err)
|
||||||
|
{
|
||||||
|
string msg;
|
||||||
|
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case EACCES: msg = "EACCES: permission denied"; break;
|
||||||
|
case EAFNOSUPPORT: msg = "EAFNOSUPPORT: address family not supported"; break;
|
||||||
|
case EMFILE: msg = "EMFILE: process file table overflow"; break;
|
||||||
|
case ENFILE: msg = "ENFILE: system limit reached"; break;
|
||||||
|
case EPROTONOSUPPORT: msg = "EPROTONOSUPPORT: protocol not supported"; break;
|
||||||
|
case EAGAIN: msg = "EGAIN: blocking operation"; break;
|
||||||
|
case EBADF: msg = "EBADF: invalid descriptor"; break;
|
||||||
|
case ECONNRESET: msg = "ECONNRESET: connection reset by peer"; break;
|
||||||
|
case EFAULT: msg = "EFAULT: bad user space address"; break;
|
||||||
|
case EINTR: msg = "EINTR: signal occured before transmission"; break;
|
||||||
|
case EINVAL: msg = "EINVAL: invalid argument"; break;
|
||||||
|
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 ENOTCONN: msg = "ENOTCONN: not connected"; break;
|
||||||
|
case ECONNREFUSED: msg = "ECONNREFUSED: connection refused"; break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << ::strerror(err);
|
||||||
|
|
||||||
|
msg = oss.str();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw exceptions::socket_exception(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -359,11 +359,27 @@ public:
|
|||||||
typedef net_exception messaging_exception;
|
typedef net_exception messaging_exception;
|
||||||
|
|
||||||
|
|
||||||
|
/** Socket error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class socket_exception : public net_exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
socket_exception(const string& what = "", const exception& other = NO_EXCEPTION);
|
||||||
|
~socket_exception() throw();
|
||||||
|
|
||||||
|
exception* clone() const;
|
||||||
|
const char* name() const throw();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Error while connecting to the server: this may be a DNS resolution error
|
/** Error while connecting to the server: this may be a DNS resolution error
|
||||||
* or a connection error (for example, time-out while connecting).
|
* or a connection error (for example, time-out while connecting).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class connection_error : public net_exception
|
class connection_error : public socket_exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -49,6 +49,10 @@ public:
|
|||||||
void send(const vmime::string& buffer);
|
void send(const vmime::string& buffer);
|
||||||
void sendRaw(const char* buffer, const int count);
|
void sendRaw(const char* buffer, const int count);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
static void throwSocketError(const int err);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
char m_buffer[65536];
|
char m_buffer[65536];
|
||||||
|
Loading…
Reference in New Issue
Block a user