mirror of https://github.com/Icinga/icinga2.git
Add more information to exceptions.
This commit is contained in:
parent
0029bc30b7
commit
d8edd98e41
|
@ -127,13 +127,21 @@ void CompatComponent::CommandPipeThread(const String& commandPath)
|
|||
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;
|
||||
|
@ -142,14 +150,20 @@ void CompatComponent::CommandPipeThread(const String& commandPath)
|
|||
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];
|
||||
|
@ -640,10 +654,18 @@ void CompatComponent::StatusTimerHandler(void)
|
|||
#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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,13 +29,13 @@ REGISTER_COMPONENT("livestatus", LivestatusComponent);
|
|||
*/
|
||||
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();
|
||||
|
|
|
@ -188,8 +188,12 @@ String Application::GetExePath(const String& argv0)
|
|||
|
||||
#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] != '/')
|
||||
|
@ -229,8 +233,12 @@ String Application::GetExePath(const String& argv0)
|
|||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
|
|
|
@ -495,8 +495,12 @@ void DynamicObject::DumpObjects(const String& filename)
|
|||
_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));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -23,111 +23,6 @@ using namespace icinga;
|
|||
|
||||
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 *))
|
||||
|
|
|
@ -28,150 +28,65 @@ namespace icinga
|
|||
*
|
||||
* @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
|
||||
{
|
||||
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)
|
||||
{ }
|
||||
typedef boost::error_info<struct errinfo_win32_error_, int> errinfo_win32_error;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
inline std::string to_string(const errinfo_win32_error& e)
|
||||
{
|
||||
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
|
||||
class openssl_error : virtual public std::exception, virtual public boost::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 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)
|
||||
{ }
|
||||
stringstream tmp;
|
||||
int code = e.value();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
const char *message = ERR_error_string(code, NULL);
|
||||
|
||||
/**
|
||||
* An OpenSSL error encapsulated in an exception.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class I2_BASE_API OpenSSLException : public Exception
|
||||
{
|
||||
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)
|
||||
{ }
|
||||
if (message == NULL)
|
||||
message = "Unknown error.";
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
tmp << code << ", \"" << message << "\"";
|
||||
return tmp.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,10 @@ using std::type_info;
|
|||
#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>
|
||||
|
@ -163,6 +167,9 @@ using boost::tie;
|
|||
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;
|
||||
|
|
|
@ -34,11 +34,17 @@ void Process::Initialize(void)
|
|||
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. */
|
||||
|
@ -56,8 +62,11 @@ void Process::Initialize(void)
|
|||
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);
|
||||
|
@ -84,8 +93,11 @@ void Process::WorkerThreadProc(int taskFd)
|
|||
|
||||
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;
|
||||
|
||||
|
@ -104,8 +116,11 @@ void Process::WorkerThreadProc(int taskFd)
|
|||
|
||||
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;
|
||||
|
@ -133,7 +148,9 @@ void Process::WorkerThreadProc(int taskFd)
|
|||
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) {
|
||||
|
@ -197,8 +214,11 @@ void Process::QueueTask(void)
|
|||
* 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,11 +231,17 @@ void Process::InitTask(void)
|
|||
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]);
|
||||
|
@ -269,8 +295,11 @@ void Process::InitTask(void)
|
|||
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
|
||||
|
@ -331,8 +360,11 @@ bool Process::RunTask(void)
|
|||
|
||||
(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);
|
||||
|
|
|
@ -137,20 +137,6 @@ int Socket::GetError(void) const
|
|||
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.
|
||||
*/
|
||||
|
@ -158,7 +144,14 @@ void Socket::HandleException(void)
|
|||
{
|
||||
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 */
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,9 +165,16 @@ String Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len)
|
|||
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;
|
||||
|
@ -193,8 +193,16 @@ String Socket::GetClientAddress(void)
|
|||
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);
|
||||
}
|
||||
|
@ -211,30 +219,20 @@ String Socket::GetPeerAddress(void)
|
|||
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.
|
||||
|
@ -272,8 +270,16 @@ void Socket::ReadThreadProc(void)
|
|||
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();
|
||||
|
@ -330,8 +336,16 @@ void Socket::WriteThreadProc(void)
|
|||
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();
|
||||
|
@ -451,8 +465,16 @@ void Socket::Write(const void *buffer, size_t size)
|
|||
*/
|
||||
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);
|
||||
|
@ -500,8 +522,16 @@ void Socket::HandleWritableClient(void)
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -528,8 +558,16 @@ void Socket::HandleReadableClient(void)
|
|||
#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;
|
||||
|
||||
|
@ -563,8 +601,16 @@ void Socket::HandleReadableServer(void)
|
|||
|
||||
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);
|
||||
|
|
|
@ -61,7 +61,6 @@ protected:
|
|||
void SetConnected(bool connected);
|
||||
|
||||
int GetError(void) const;
|
||||
static int GetLastSocketError(void);
|
||||
|
||||
mutable boost::mutex m_SocketMutex;
|
||||
|
||||
|
@ -107,14 +106,7 @@ private:
|
|||
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 { };
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,16 @@ void TcpSocket::Bind(String node, String service, int family)
|
|||
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;
|
||||
|
||||
|
@ -114,8 +122,16 @@ void TcpSocket::Connect(const String& node, const String& service)
|
|||
|
||||
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;
|
||||
|
||||
|
|
|
@ -48,8 +48,11 @@ void TlsStream::Start(void)
|
|||
|
||||
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."));
|
||||
|
@ -153,7 +156,9 @@ void TlsStream::HandleIO(void)
|
|||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +183,9 @@ void TlsStream::HandleIO(void)
|
|||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +222,9 @@ void TlsStream::HandleIO(void)
|
|||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,11 @@ UnixSocket::UnixSocket(void)
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
@ -42,8 +45,11 @@ void UnixSocket::Bind(const String& path)
|
|||
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)
|
||||
|
@ -54,7 +60,10 @@ 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 */
|
||||
|
|
|
@ -69,16 +69,24 @@ void Utility::Daemonize(void) {
|
|||
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);
|
||||
|
@ -92,8 +100,11 @@ void Utility::Daemonize(void) {
|
|||
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
|
||||
}
|
||||
|
||||
|
@ -127,20 +138,36 @@ shared_ptr<SSL_CTX> Utility::MakeSSLContext(const String& pubkey, const String&
|
|||
|
||||
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);
|
||||
|
||||
|
@ -160,9 +187,11 @@ String Utility::GetCertificateCN(const shared_ptr<X509>& certificate)
|
|||
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;
|
||||
}
|
||||
|
@ -178,18 +207,25 @@ shared_ptr<X509> Utility::GetX509Certificate(const String& pemfile)
|
|||
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);
|
||||
|
||||
|
@ -319,8 +355,11 @@ double Utility::GetTime(void)
|
|||
#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 */
|
||||
|
@ -444,7 +483,10 @@ bool Utility::Glob(const String& pathSpec, const function<void (const String&)>&
|
|||
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) {
|
||||
|
@ -467,24 +509,36 @@ bool Utility::Glob(const String& pathSpec, const function<void (const String&)>&
|
|||
#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 */
|
||||
|
||||
|
@ -512,13 +566,19 @@ String Utility::FormatDateTime(const char *format, double ts)
|
|||
#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);
|
||||
|
|
|
@ -228,7 +228,7 @@ void Endpoint::UnregisterTopicHandler(const String&, const function<Endpoint::Ca
|
|||
//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)
|
||||
|
|
Loading…
Reference in New Issue