if (S_ISFIFO(statbuf.st_mode) && access(commandPath.CStr(), R_OK) >= 0) {
fifo_ok = true;
} else {
- if (unlink(commandPath.CStr()) < 0)
- BOOST_THROW_EXCEPTION(PosixException("unlink() failed", errno));
+ if (unlink(commandPath.CStr()) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("unlink")
+ << errinfo_errno(errno)
+ << errinfo_file_name(commandPath));
+ }
}
}
- if (!fifo_ok && mkfifo(commandPath.CStr(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0)
- BOOST_THROW_EXCEPTION(PosixException("mkfifo() failed", errno));
+ if (!fifo_ok && mkfifo(commandPath.CStr(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("mkfifo")
+ << errinfo_errno(errno)
+ << errinfo_file_name(commandPath));
+ }
for (;;) {
int fd;
fd = open(commandPath.CStr(), O_RDONLY);
} while (fd < 0 && errno == EINTR);
- if (fd < 0)
- BOOST_THROW_EXCEPTION(PosixException("open() failed", errno));
+ if (fd < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("open")
+ << errinfo_errno(errno)
+ << errinfo_file_name(commandPath));
+ }
FILE *fp = fdopen(fd, "r");
if (fp == NULL) {
- close(fd);
- BOOST_THROW_EXCEPTION(PosixException("fdopen() failed", errno));
+ (void) close(fd);
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("fdopen")
+ << errinfo_errno(errno));
}
char line[2048];
#endif /* _WIN32 */
statusfp.close();
- if (rename(statuspathtmp.CStr(), statuspath.CStr()) < 0)
- BOOST_THROW_EXCEPTION(PosixException("rename() failed", errno));
+ if (rename(statuspathtmp.CStr(), statuspath.CStr()) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("rename")
+ << errinfo_errno(errno)
+ << errinfo_file_name(statuspathtmp));
+ }
objectfp.close();
- if (rename(objectspathtmp.CStr(), objectspath.CStr()) < 0)
- BOOST_THROW_EXCEPTION(PosixException("rename() failed", errno));
+ if (rename(objectspathtmp.CStr(), objectspath.CStr()) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("rename")
+ << errinfo_errno(errno)
+ << errinfo_file_name(objectspathtmp));
+ }
}
*/
void LivestatusComponent::Start(void)
{
-#ifndef _WIN32
- UnixSocket::Ptr socket = boost::make_shared<UnixSocket>();
- socket->Bind(GetSocketPath());
-#else /* _WIN32 */
+//#ifndef _WIN32
+// UnixSocket::Ptr socket = boost::make_shared<UnixSocket>();
+// socket->Bind(GetSocketPath());
+//#else /* _WIN32 */
TcpSocket::Ptr socket = boost::make_shared<TcpSocket>();
- socket->Bind("6557", AF_INET);
-#endif /* _WIN32 */
+ socket->Bind("6558", AF_INET);
+//#endif /* _WIN32 */
socket->OnNewClient.connect(boost::bind(&LivestatusComponent::NewClientHandler, this, _2));
socket->Listen();
#ifndef _WIN32
char buffer[MAXPATHLEN];
- if (getcwd(buffer, sizeof(buffer)) == NULL)
- BOOST_THROW_EXCEPTION(PosixException("getcwd failed", errno));
+ if (getcwd(buffer, sizeof(buffer)) == NULL) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("getcwd")
+ << errinfo_errno(errno));
+ }
+
String workingDirectory = buffer;
if (argv0[0] != '/')
}
}
- if (realpath(executablePath.CStr(), buffer) == NULL)
- BOOST_THROW_EXCEPTION(PosixException("realpath failed", errno));
+ if (realpath(executablePath.CStr(), buffer) == NULL) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("realpath")
+ << errinfo_errno(errno)
+ << errinfo_file_name(executablePath));
+ }
return buffer;
#else /* _WIN32 */
_unlink(filename.CStr());
#endif /* _WIN32 */
- if (rename(tempFilename.CStr(), filename.CStr()) < 0)
- BOOST_THROW_EXCEPTION(PosixException("rename() failed", errno));
+ if (rename(tempFilename.CStr(), filename.CStr()) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("rename")
+ << errinfo_errno(errno)
+ << errinfo_file_name(tempFilename));
+ }
}
/*
boost::thread_specific_ptr<StackTrace> Exception::m_LastStackTrace;
-/**
- * Retrieves the error code for the exception.
- *
- * @returns The error code.
- */
-int Exception::GetCode(void) const
-{
- return m_Code;
-}
-
-/**
- * Sets the error code for the exception.
- *
- * @param code The error code.
- */
-void Exception::SetCode(int code)
-{
- m_Code = code;
-}
-
-/**
- * Retrieves the description for the exception.
- *
- * @returns The description.
- */
-String Exception::GetMessage(void) const
-{
- return m_Message;
-}
-
-/**
- * Retrieves the description for the exception.
- *
- * @returns The description.
- */
-const char *Exception::what(void) const throw()
-{
- return m_Message.CStr();
-}
-
-/**
- * Sets the description for the exception.
- *
- * @param message The description.
- */
-void Exception::SetMessage(String message)
-{
- m_Message = message;
-}
-
-#ifdef _WIN32
-/**
- * Formats an Win32 error code.
- *
- * @param code The error code.
- * @returns A String describing the error.
- */
-String Win32Exception::FormatErrorCode(int code)
-{
- char *message;
- String result = "Unknown error.";
-
- DWORD rc = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, (char *)&message,
- 0, NULL);
-
- if (rc != 0) {
- result = String(message);
- LocalFree(message);
-
- /* remove trailing new-line characters */
- boost::algorithm::trim_right(result);
- }
-
- return result;
-}
-#endif /* _WIN32 */
-
-/**
- * Formats a Posix error code.
- *
- * @param code The error code.
- * @returns A String describing the error.
- */
-String PosixException::FormatErrorCode(int code)
-{
- return strerror(code);
-}
-
-/**
- * Formats an OpenSSL error code.
- *
- * @param code The error code.
- * @returns A String describing the error.
- */
-String OpenSSLException::FormatErrorCode(int code)
-{
- const char *message = ERR_error_string(code, NULL);
-
- if (message == NULL)
- message = "Unknown error.";
-
- return message;
-}
-
#ifndef _WIN32
extern "C"
void __cxa_throw(void *obj, void *pvtinfo, void (*dest)(void *))
*
* @ingroup base
*/
-class I2_BASE_API Exception : public virtual exception
+class I2_BASE_API Exception //: public virtual exception
{
public:
- Exception(void)
- : m_Message(), m_Code(0)
- { }
-
- Exception(String message)
- : m_Message(message), m_Code(0)
- { }
-
- Exception(String message, int code)
- : m_Message(message), m_Code(code)
- { }
-
- /**
- * Destructor for the Exception class. Must be virtual for RTTI to work.
- */
- virtual ~Exception(void) throw()
- { }
-
- int GetCode(void) const;
- String GetMessage(void) const;
-
- virtual const char *what(void) const throw();
-
static StackTrace *GetLastStackTrace(void);
static void SetLastStackTrace(const StackTrace& trace);
-protected:
- void SetCode(int code);
- void SetMessage(String message);
-
private:
- String m_Message;
- int m_Code;
-
static boost::thread_specific_ptr<StackTrace> m_LastStackTrace;
};
typedef boost::error_info<StackTrace, StackTrace> StackTraceErrorInfo;
-#define DEFINE_EXCEPTION_CLASS(klass) \
- class klass : public Exception \
- { \
- public: \
- inline klass(void) : Exception() \
- { } \
- \
- inline klass(String message) \
- : Exception(message) \
- { } \
- }
-
-/**
- * An exception that is thrown when a certain feature
- * is not implemented.
- *
- * @ingroup base
- */
-DEFINE_EXCEPTION_CLASS(NotImplementedException);
+class I2_BASE_API posix_error : virtual public std::exception, virtual public boost::exception { };
#ifdef _WIN32
-/**
- * A Win32 error encapsulated in an exception.
- *
- * @ingroup base
- */
-class I2_BASE_API Win32Exception : public Exception
+typedef boost::error_info<struct errinfo_win32_error_, int> errinfo_win32_error;
+
+inline std::string to_string(const errinfo_win32_error& e)
{
-public:
- /**
- * Constructor for the Win32Exception class.
- *
- * @param message An error message.
- * @param errorCode A Win32 error code.
- */
- inline Win32Exception(const String& message, int errorCode)
- : Exception(message + ": " + FormatErrorCode(errorCode), errorCode)
- { }
-
- /**
- * Returns a String that describes the Win32 error.
- *
- * @param code The Win32 error code.
- * @returns A description of the error.
- */
- static String FormatErrorCode(int code);
-};
+ stringstream tmp;
+ int code = e.value();
+
+ char *message;
+ String result = "Unknown error.";
+
+ DWORD rc = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, (char *)&message,
+ 0, NULL);
+
+ if (rc != 0) {
+ result = String(message);
+ LocalFree(message);
+
+ /* remove trailing new-line characters */
+ boost::algorithm::trim_right(result);
+ }
+
+ tmp << code << ", \"" << result << "\"";
+ return tmp.str();
+}
#endif /* _WIN32 */
-/**
- * A Posix error encapsulated in an exception.
- *
- * @ingroup base
- */
-class I2_BASE_API PosixException : public Exception
-{
-public:
- /**
- * Constructor for the PosixException class.
- *
- * @param message An error message.
- * @param errorCode A Posix (errno) error code.
- */
- inline PosixException(const String& message, int errorCode)
- : Exception(message + ": " + FormatErrorCode(errorCode), errorCode)
- { }
-
- /**
- * Returns a String that describes the Posix error.
- *
- * @param code The Posix error code.
- * @returns A description of the error.
- */
- static String FormatErrorCode(int code);
-};
+class openssl_error : virtual public std::exception, virtual public boost::exception { };
-/**
- * An OpenSSL error encapsulated in an exception.
- *
- * @ingroup base
- */
-class I2_BASE_API OpenSSLException : public Exception
+typedef boost::error_info<struct errinfo_openssl_error_, int> errinfo_openssl_error;
+
+inline std::string to_string(const errinfo_openssl_error& e)
{
-public:
- /**
- * Constructor for the OpenSSLException class.
- *
- * @param message An error message.
- * @param errorCode An OpenSSL error code.
- */
- inline OpenSSLException(const String& message, int errorCode)
- : Exception(message + ": " + FormatErrorCode(errorCode), errorCode)
- { }
-
- /**
- * Returns a String that describes the OpenSSL error.
- *
- * @param code The OpenSSL error code.
- * @returns A description of the error.
- */
- static String FormatErrorCode(int code);
-};
+ stringstream tmp;
+ int code = e.value();
+
+ const char *message = ERR_error_string(code, NULL);
+
+ if (message == NULL)
+ message = "Unknown error.";
+
+ tmp << code << ", \"" << message << "\"";
+ return tmp.str();
+}
}
#include <boost/uuid/uuid_io.hpp>
#include <boost/program_options.hpp>
#include <boost/exception/diagnostic_information.hpp>
+#include <boost/exception/error_info.hpp>
+#include <boost/exception/errinfo_api_function.hpp>
+#include <boost/exception/errinfo_errno.hpp>
+#include <boost/exception/errinfo_file_name.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/key_extractors.hpp>
using boost::rethrow_exception;
using boost::current_exception;
using boost::diagnostic_information;
+using boost::errinfo_api_function;
+using boost::errinfo_errno;
+using boost::errinfo_file_name;
using boost::multi_index_container;
using boost::multi_index::indexed_by;
using boost::multi_index::identity;
int fds[2];
#if HAVE_PIPE2
- if (pipe2(fds, O_CLOEXEC) < 0)
- BOOST_THROW_EXCEPTION(PosixException("pipe2() failed.", errno));
+ if (pipe2(fds, O_CLOEXEC) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("pipe2")
+ << errinfo_errno(errno));
+ }
#else /* HAVE_PIPE2 */
- if (pipe(fds) < 0)
- BOOST_THROW_EXCEPTION(PosixException("pipe() failed.", errno));
+ if (pipe(fds) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("pipe")
+ << errinfo_errno(errno));
+ }
/* Don't bother setting fds[0] to clo-exec as we'll only
* use it in the following dup() call. */
for (unsigned int i = 0; i < threads; i++) {
int childTaskFd = dup(fds[0]);
- if (childTaskFd < 0)
- BOOST_THROW_EXCEPTION(PosixException("dup() failed.", errno));
+ if (childTaskFd < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("dup")
+ << errinfo_errno(errno));
+ }
Utility::SetNonBlocking(childTaskFd);
Utility::SetCloExec(childTaskFd);
pfds = (pollfd *)realloc(pfds, (1 + tasks.size()) * sizeof(pollfd));
- if (pfds == NULL)
- BOOST_THROW_EXCEPTION(PosixException("realloc() failed.", errno));
+ if (pfds == NULL) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("realloc")
+ << errinfo_errno(errno));
+ }
int idx = 0;
int rc = poll(pfds, idx, -1);
- if (rc < 0 && errno != EINTR)
- BOOST_THROW_EXCEPTION(PosixException("poll() failed.", errno));
+ if (rc < 0 && errno != EINTR) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("poll")
+ << errinfo_errno(errno));
+ }
if (rc == 0)
continue;
if (errno == EAGAIN)
break; /* Someone else was faster and took our task. */
- BOOST_THROW_EXCEPTION(PosixException("read() failed.", errno));
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("read")
+ << errinfo_errno(errno));
}
while (have > 0) {
* This little gem which is commonly known as the "self-pipe trick"
* takes care of waking up the select() call in the worker thread.
*/
- if (write(m_TaskFd, "T", 1) < 0)
- BOOST_THROW_EXCEPTION(PosixException("write() failed.", errno));
+ if (write(m_TaskFd, "T", 1) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("write")
+ << errinfo_errno(errno));
+ }
}
}
int fds[2];
#if HAVE_PIPE2
- if (pipe2(fds, O_NONBLOCK | O_CLOEXEC) < 0)
- BOOST_THROW_EXCEPTION(PosixException("pipe2() failed.", errno));
+ if (pipe2(fds, O_NONBLOCK | O_CLOEXEC) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("pipe2")
+ << errinfo_errno(errno));
+ }
#else /* HAVE_PIPE2 */
- if (pipe(fds) < 0)
- BOOST_THROW_EXCEPTION(PosixException("pipe() failed.", errno));
+ if (pipe(fds) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("pipe")
+ << errinfo_errno(errno));
+ }
Utility::SetNonBlocking(fds[0]);
Utility::SetCloExec(fds[0]);
m_Pid = fork();
#endif /* HAVE_WORKING_VFORK */
- if (m_Pid < 0)
- BOOST_THROW_EXCEPTION(PosixException("fork() failed.", errno));
+ if (m_Pid < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("fork")
+ << errinfo_errno(errno));
+ }
if (m_Pid == 0) {
// child process
(void) close(m_FD);
- if (waitpid(m_Pid, &status, 0) != m_Pid)
- BOOST_THROW_EXCEPTION(PosixException("waitpid() failed.", errno));
+ if (waitpid(m_Pid, &status, 0) != m_Pid) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("waitpid")
+ << errinfo_errno(errno));
+ }
if (WIFEXITED(status)) {
exitcode = WEXITSTATUS(status);
return 0;
}
-/**
- * Retrieves the last socket error.
- *
- * @returns An error code.
- */
-int Socket::GetLastSocketError(void)
-{
-#ifdef _WIN32
- return WSAGetLastError();
-#else /* _WIN32 */
- return errno;
-#endif /* _WIN32 */
-}
-
/**
* Processes errors that have occured for the socket.
*/
{
ObjectLock olock(this);
- BOOST_THROW_EXCEPTION(SocketException("select() returned fd in except fdset", GetError()));
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("select")
+#ifndef _WIN32
+ << errinfo_errno(GetError())
+#else /* _WIN32 */
+ << errinfo_win32_error(GetError())
+#endif /* _WIN32 */
+ );
}
/**
char service[NI_MAXSERV];
if (getnameinfo(address, len, host, sizeof(host), service,
- sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV) < 0)
- BOOST_THROW_EXCEPTION(SocketException("getnameinfo() failed",
- GetLastSocketError()));
+ sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV) < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("getnameinfo")
+ #ifndef _WIN32
+ << errinfo_errno(errno)
+ #else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+ #endif /* _WIN32 */
+ );
+ }
stringstream s;
s << "[" << host << "]:" << service;
sockaddr_storage sin;
socklen_t len = sizeof(sin);
- if (getsockname(GetFD(), (sockaddr *)&sin, &len) < 0)
- BOOST_THROW_EXCEPTION(SocketException("getsockname() failed", GetError()));
+ if (getsockname(GetFD(), (sockaddr *)&sin, &len) < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("getsockname")
+ #ifndef _WIN32
+ << errinfo_errno(errno)
+ #else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+ #endif /* _WIN32 */
+ );
+ }
return GetAddressFromSockaddr((sockaddr *)&sin, len);
}
sockaddr_storage sin;
socklen_t len = sizeof(sin);
- if (getpeername(GetFD(), (sockaddr *)&sin, &len) < 0)
- BOOST_THROW_EXCEPTION(SocketException("getpeername() failed", GetError()));
+ if (getpeername(GetFD(), (sockaddr *)&sin, &len) < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("getpeername")
+ #ifndef _WIN32
+ << errinfo_errno(errno)
+ #else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+ #endif /* _WIN32 */
+ );
+ }
return GetAddressFromSockaddr((sockaddr *)&sin, len);
}
-/**
- * Constructor for the SocketException class.
- *
- * @param message The error message.
- * @param errorCode The error code.
- */
-SocketException::SocketException(const String& message, int errorCode)
-{
-#ifdef _WIN32
- String details = Win32Exception::FormatErrorCode(errorCode);
-#else /* _WIN32 */
- String details = PosixException::FormatErrorCode(errorCode);
-#endif /* _WIN32 */
-
- String msg = message + ": " + details;
- SetMessage(msg.CStr());
-}
-
/**
* Read thread procedure for sockets. This function waits until the
* socket is readable and processes inbound data.
return;
try {
- if (rc < 0)
- BOOST_THROW_EXCEPTION(SocketException("select() failed", GetError()));
+ if (rc < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("select")
+ #ifndef _WIN32
+ << errinfo_errno(errno)
+ #else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+ #endif /* _WIN32 */
+ );
+ }
if (FD_ISSET(fd, &readfds))
HandleReadable();
return;
try {
- if (rc < 0)
- BOOST_THROW_EXCEPTION(SocketException("select() failed", GetError()));
+ if (rc < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("select")
+ #ifndef _WIN32
+ << errinfo_errno(errno)
+ #else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+ #endif /* _WIN32 */
+ );
+ }
if (FD_ISSET(fd, &writefds))
HandleWritable();
*/
void Socket::Listen(void)
{
- if (listen(GetFD(), SOMAXCONN) < 0)
- BOOST_THROW_EXCEPTION(SocketException("listen() failed", GetError()));
+ if (listen(GetFD(), SOMAXCONN) < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("listen")
+ #ifndef _WIN32
+ << errinfo_errno(errno)
+ #else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+ #endif /* _WIN32 */
+ );
+ }
{
ObjectLock olock(this);
rc = send(GetFD(), data, count, 0);
- if (rc <= 0)
- BOOST_THROW_EXCEPTION(SocketException("send() failed", GetError()));
+ if (rc <= 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("send")
+ #ifndef _WIN32
+ << errinfo_errno(errno)
+ #else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+ #endif /* _WIN32 */
+ );
+ }
m_SendQueue->Read(NULL, rc);
}
#endif /* _WIN32 */
break;
- if (rc < 0)
- BOOST_THROW_EXCEPTION(SocketException("recv() failed", GetError()));
+ if (rc < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("recv")
+ #ifndef _WIN32
+ << errinfo_errno(errno)
+ #else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+ #endif /* _WIN32 */
+ );
+ }
new_data = true;
fd = accept(GetFD(), (sockaddr *)&addr, &addrlen);
- if (fd < 0)
- BOOST_THROW_EXCEPTION(SocketException("accept() failed", GetError()));
+ if (fd < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("accept")
+ #ifndef _WIN32
+ << errinfo_errno(errno)
+ #else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+ #endif /* _WIN32 */
+ );
+ }
Socket::Ptr client = boost::make_shared<Socket>();
client->SetFD(fd);
void SetConnected(bool connected);
int GetError(void) const;
- static int GetLastSocketError(void);
mutable boost::mutex m_SocketMutex;
bool WantsToRead(void) const;
};
-/**
- * A socket exception.
- */
-class SocketException : public Exception
-{
-public:
- SocketException(const String& message, int errorCode);
-};
+class socket_error : virtual public std::exception, virtual public boost::exception { };
}
hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(node.IsEmpty() ? NULL : node.CStr(),
- service.CStr(), &hints, &result) < 0)
- BOOST_THROW_EXCEPTION(SocketException("getaddrinfo() failed", GetLastSocketError()));
+ service.CStr(), &hints, &result) < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("getaddrinfo")
+#ifndef _WIN32
+ << errinfo_errno(errno)
+#else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+#endif /* _WIN32 */
+ );
+ }
int fd = INVALID_SOCKET;
int rc = getaddrinfo(node.CStr(), service.CStr(), &hints, &result);
- if (rc < 0)
- BOOST_THROW_EXCEPTION(SocketException("getaddrinfo() failed", GetLastSocketError()));
+ if (rc < 0) {
+ BOOST_THROW_EXCEPTION(socket_error()
+ << errinfo_api_function("getaddrinfo")
+#ifndef _WIN32
+ << errinfo_errno(errno)
+#else /* _WIN32 */
+ << errinfo_win32_error(WSAGetLastError())
+#endif /* _WIN32 */
+ );
+ }
int fd = INVALID_SOCKET;
m_SSLContext.reset();
- if (!m_SSL)
- BOOST_THROW_EXCEPTION(OpenSSLException("SSL_new failed", ERR_get_error()));
+ if (!m_SSL) {
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("SSL_new")
+ << errinfo_openssl_error(ERR_get_error()));
+ }
if (!GetClientCertificate())
BOOST_THROW_EXCEPTION(logic_error("No X509 client certificate was specified."));
return;
default:
I2Stream_check_exception(m_BIO);
- BOOST_THROW_EXCEPTION(OpenSSLException("SSL_do_handshake failed", ERR_get_error()));
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("SSL_do_handshake")
+ << errinfo_openssl_error(ERR_get_error()));
}
}
}
return;
default:
I2Stream_check_exception(m_BIO);
- BOOST_THROW_EXCEPTION(OpenSSLException("SSL_read failed", ERR_get_error()));
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("SSL_read")
+ << errinfo_openssl_error(ERR_get_error()));
}
}
}
return;
default:
I2Stream_check_exception(m_BIO);
- BOOST_THROW_EXCEPTION(OpenSSLException("SSL_write failed", ERR_get_error()));
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("SSL_write")
+ << errinfo_openssl_error(ERR_get_error()));
}
}
}
{
int fd = socket(AF_UNIX, SOCK_STREAM, PF_UNIX);
- if (fd < 0)
- BOOST_THROW_EXCEPTION(PosixException("socket() failed", errno));
+ if (fd < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("socket")
+ << errinfo_errno(errno));
+ }
SetFD(fd);
}
strncpy(sun.sun_path, path.CStr(), sizeof(sun.sun_path));
sun.sun_path[sizeof(sun.sun_path) - 1] = '\0';
- if (bind(GetFD(), (sockaddr *)&sun, SUN_LEN(&sun)) < 0)
- BOOST_THROW_EXCEPTION(PosixException("bind() failed", errno));
+ if (bind(GetFD(), (sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("bind")
+ << errinfo_errno(errno));
+ }
}
void UnixSocket::Connect(const String& path)
strncpy(sun.sun_path, path.CStr(), sizeof(sun.sun_path));
sun.sun_path[sizeof(sun.sun_path) - 1] = '\0';
- if (connect(GetFD(), (sockaddr *)&sun, SUN_LEN(&sun)) < 0 && errno != EINPROGRESS)
- BOOST_THROW_EXCEPTION(PosixException("connect() failed", errno));
+ if (connect(GetFD(), (sockaddr *)&sun, SUN_LEN(&sun)) < 0 && errno != EINPROGRESS) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("connect")
+ << errinfo_errno(errno));
+ }
}
#endif /* _WIN32 */
int fd;
pid = fork();
- if (pid < 0)
- BOOST_THROW_EXCEPTION(PosixException("fork() failed", errno));
+
+ if (pid < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("fork")
+ << errinfo_errno(errno));
+ }
if (pid)
_exit(0);
fd = open("/dev/null", O_RDWR);
- if (fd < 0)
- BOOST_THROW_EXCEPTION(PosixException("open() failed", errno));
+ if (fd < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("open")
+ << errinfo_errno(errno)
+ << errinfo_file_name("/dev/null"));
+ }
if (fd != STDIN_FILENO)
dup2(fd, STDIN_FILENO);
if (fd > STDERR_FILENO)
close(fd);
- if (setsid() < 0)
- BOOST_THROW_EXCEPTION(PosixException("setsid() failed", errno));
+ if (setsid() < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("setsid")
+ << errinfo_errno(errno));
+ }
#endif
}
SSL_CTX_set_mode(sslContext.get(), SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
- if (!SSL_CTX_use_certificate_chain_file(sslContext.get(), pubkey.CStr()))
- BOOST_THROW_EXCEPTION(OpenSSLException("Could not load public X509 key file", ERR_get_error()));
+ if (!SSL_CTX_use_certificate_chain_file(sslContext.get(), pubkey.CStr())) {
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("SSL_CTX_use_certificate_chain_file")
+ << errinfo_openssl_error(ERR_get_error())
+ << errinfo_file_name(pubkey));
+ }
- if (!SSL_CTX_use_PrivateKey_file(sslContext.get(), privkey.CStr(), SSL_FILETYPE_PEM))
- BOOST_THROW_EXCEPTION(OpenSSLException("Could not load private X509 key file", ERR_get_error()));
+ if (!SSL_CTX_use_PrivateKey_file(sslContext.get(), privkey.CStr(), SSL_FILETYPE_PEM)) {
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("SSL_CTX_use_PrivateKey_file")
+ << errinfo_openssl_error(ERR_get_error())
+ << errinfo_file_name(privkey));
+ }
- if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.CStr(), NULL))
- BOOST_THROW_EXCEPTION(OpenSSLException("Could not load public CA key file", ERR_get_error()));
+ if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.CStr(), NULL)) {
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("SSL_CTX_load_verify_locations")
+ << errinfo_openssl_error(ERR_get_error())
+ << errinfo_file_name(cakey));
+ }
STACK_OF(X509_NAME) *cert_names;
cert_names = SSL_load_client_CA_file(cakey.CStr());
- if (cert_names == NULL)
- BOOST_THROW_EXCEPTION(OpenSSLException("SSL_load_client_CA_file() failed", ERR_get_error()));
+ if (cert_names == NULL) {
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("SSL_load_client_CA_file")
+ << errinfo_openssl_error(ERR_get_error())
+ << errinfo_file_name(cakey));
+ }
SSL_CTX_set_client_CA_list(sslContext.get(), cert_names);
int rc = X509_NAME_get_text_by_NID(X509_get_subject_name(certificate.get()),
NID_commonName, buffer, sizeof(buffer));
- if (rc == -1)
- BOOST_THROW_EXCEPTION(OpenSSLException("X509 certificate has no CN"
- " attribute", ERR_get_error()));
+ if (rc == -1) {
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("X509_NAME_get_text_by_NID")
+ << errinfo_openssl_error(ERR_get_error()));
+ }
return buffer;
}
X509 *cert;
BIO *fpcert = BIO_new(BIO_s_file());
- if (fpcert == NULL)
- BOOST_THROW_EXCEPTION(OpenSSLException("BIO_new failed",
- ERR_get_error()));
+ if (fpcert == NULL) {
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("BIO_new")
+ << errinfo_openssl_error(ERR_get_error()));
+ }
- if (BIO_read_filename(fpcert, pemfile.CStr()) < 0)
- BOOST_THROW_EXCEPTION(OpenSSLException("BIO_read_filename failed",
- ERR_get_error()));
+ if (BIO_read_filename(fpcert, pemfile.CStr()) < 0) {
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("BIO_read_filename")
+ << errinfo_openssl_error(ERR_get_error())
+ << errinfo_file_name(pemfile));
+ }
cert = PEM_read_bio_X509_AUX(fpcert, NULL, NULL, NULL);
- if (cert == NULL)
- BOOST_THROW_EXCEPTION(OpenSSLException("PEM_read_bio_X509_AUX failed",
- ERR_get_error()));
+ if (cert == NULL) {
+ BOOST_THROW_EXCEPTION(openssl_error()
+ << errinfo_api_function("PEM_read_bio_X509_AUX")
+ << errinfo_openssl_error(ERR_get_error()));
+ }
BIO_free(fpcert);
#else /* _WIN32 */
struct timeval tv;
- if (gettimeofday(&tv, NULL) < 0)
- BOOST_THROW_EXCEPTION(PosixException("gettimeofday() failed", errno));
+ if (gettimeofday(&tv, NULL) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("gettimeofday")
+ << errinfo_errno(errno));
+ }
return tv.tv_sec + tv.tv_usec / 1000000.0;
#endif /* _WIN32 */
if (rc == GLOB_NOMATCH)
return false;
- BOOST_THROW_EXCEPTION(PosixException("glob() failed", errno));
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("glob")
+ << errinfo_errno(errno)
+ << errinfo_file_name(pathSpec));
}
if (gr.gl_pathc == 0) {
#ifndef _WIN32
void Utility::SetNonBlocking(int fd)
{
- int flags;
- flags = fcntl(fd, F_GETFL, 0);
- if (flags < 0)
- BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+ int flags = fcntl(fd, F_GETFL, 0);
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
- BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+ if (flags < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("fcntl")
+ << errinfo_errno(errno));
+ }
+
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("fcntl")
+ << errinfo_errno(errno));
+ }
}
void Utility::SetCloExec(int fd)
{
- int flags;
- flags = fcntl(fd, F_GETFD, 0);
- if (flags < 0)
- BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+ int flags = fcntl(fd, F_GETFD, 0);
- if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
- BOOST_THROW_EXCEPTION(PosixException("fcntl failed", errno));
+ if (flags < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("fcntl")
+ << errinfo_errno(errno));
+ }
+
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("fcntl")
+ << errinfo_errno(errno));
+ }
}
#endif /* _WIN32 */
#ifdef _MSC_VER
tm *temp = localtime(&tempts);
- if (temp == NULL)
- BOOST_THROW_EXCEPTION(PosixException("localtime() failed", errno));
+ if (temp == NULL) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("localtime")
+ << errinfo_errno(errno));
+ }
tmthen = *temp;
#else /* _MSC_VER */
- if (localtime_r(&tempts, &tmthen) == NULL)
- BOOST_THROW_EXCEPTION(PosixException("localtime_r() failed.", errno));
+ if (localtime_r(&tempts, &tmthen) == NULL) {
+ BOOST_THROW_EXCEPTION(posix_error()
+ << errinfo_api_function("localtime_r")
+ << errinfo_errno(errno));
+ }
#endif /* _MSC_VER */
strftime(timestamp, sizeof(timestamp), format, &tmthen);
//m_TopicHandlers[method] -= callback;
//UnregisterSubscription(method);
- BOOST_THROW_EXCEPTION(NotImplementedException());
+ BOOST_THROW_EXCEPTION(runtime_error("Not implemented."));
}
void Endpoint::ProcessRequest(const Endpoint::Ptr& sender, const RequestMessage& request)