#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
-#define CheckError(op,args) if (op args < 0) throw SystemException(# op, errno)
+#define CheckError(op,args) if (op args < 0) throwErrno(# op, errno)
///////////////////////////////////////////////////////////////////////////
// senf::ClockService::Impl
{
try {
if (event != senf::Scheduler::EV_READ)
- throw SystemException(EPIPE);
+ throwErrno(EPIPE);
std::string rcv;
handle.read(rcv, maxSize_ - data_.size());
data_.append(rcv);
prefix_ void senf::ReadHelper<Handle>::throw_error()
const
{
- if (errno_ != 0) throw SystemException(errno_);
+ if (errno_ != 0) throwErrno(errno_);
}
///////////////////////////////cti.e///////////////////////////////////////
eventTime_(0), eventEarly_(ClockService::milliseconds(11)), eventAdjust_(0)
{
if (epollFd_<0)
- throw SystemException(errno);
+ throwErrno();
if (::pipe(sigpipe_) < 0)
- throw SystemException(errno);
+ throwErrno();
int flags (::fcntl(sigpipe_[1],F_GETFL));
if (flags < 0)
- throw SystemException(errno);
+ throwErrno();
flags |= O_NONBLOCK;
if (::fcntl(sigpipe_[1], F_SETFL, flags) < 0)
- throw SystemException(errno);
+ throwErrno();
::epoll_event ev;
::memset(&ev, 0, sizeof(ev));
ev.events = EV_READ;
ev.data.fd = sigpipe_[0];
if (::epoll_ctl(epollFd_, EPOLL_CTL_ADD, sigpipe_[0], &ev) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::Scheduler::registerSignal(unsigned signal, SimpleCallback const & cb)
if (signal == SIGCHLD)
sa.sa_flags |= SA_NOCLDSTOP;
if (::sigaction(signal, &sa, 0) < 0)
- throw SystemException(errno);
+ throwErrno();
}
}
}
if (events<0)
if (errno != EINTR)
- throw SystemException(errno);
+ throwErrno();
eventTime_ = ClockService::now();
bool complete_ (false);
try {
if (event != senf::Scheduler::EV_WRITE)
- throw senf::SystemException(EPIPE);
+ throwErrno(EPIPE);
offset_ = handle.write(std::make_pair(offset_,data_.end()));
if (offset_ == data_.end()) {
data_.erase();
const
{
if (errno_ != 0)
- throw senf::SystemException(errno_);
+ throwErrno(errno_);
}
unsigned size;
socklen_t len (sizeof(size));
if (::getsockopt(handle.fd(),SOL_SOCKET,SO_RCVBUF,&size,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
// Linux doubles the bufer size on setting the RCVBUF to cater for internal
// headers. We fix this up here .. (see lkml FAQ)
return size/2;
prefix_ void senf::SocketBufferingPolicy::rcvbuf(FileHandle handle, unsigned size)
{
if (::setsockopt(handle.fd(),SOL_SOCKET,SO_RCVBUF,&size,sizeof(size)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ unsigned senf::SocketBufferingPolicy::sndbuf(FileHandle handle)
unsigned size;
socklen_t len (sizeof(size));
if (::getsockopt(handle.fd(),SOL_SOCKET,SO_SNDBUF,&size,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
// Linux doubles the bufer size on setting the SNDBUF to cater for internal
// headers. We fix this up here .. (see lkml FAQ)
return size/2;
prefix_ void senf::SocketBufferingPolicy::sndbuf(FileHandle handle, unsigned size)
{
if (::setsockopt(handle.fd(),SOL_SOCKET,SO_SNDBUF,&size,sizeof(size)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
///////////////////////////////cc.e////////////////////////////////////////
case EINTR:
break;
default:
- throw SystemException(errno);
+ throwErrno();
}
} while (rv<0);
return rv;
prefix_ void senf::FileBody::v_close()
{
if (::close(fd_) != 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::FileBody::v_terminate()
const
{
int flags = ::fcntl(fd(),F_GETFL);
- if (flags < 0) throw SystemException(errno);
+ if (flags < 0) throwErrno();
return ! (flags & O_NONBLOCK);
}
prefix_ void senf::FileBody::blocking(bool status)
{
int flags = ::fcntl(fd(),F_GETFL);
- if (flags < 0) throw SystemException(errno);
+ if (flags < 0) throwErrno();
if (status) flags &= ~O_NONBLOCK;
else flags |= O_NONBLOCK;
- if (::fcntl(fd(), F_SETFL, flags) < 0) throw SystemException(errno);
+ if (::fcntl(fd(), F_SETFL, flags) < 0) throwErrno();
}
/* We don't take POLLIN/POLLOUT as argument to avoid having to include
case EINTR:
break;
default:
- throw SystemException(errno);
+ throwErrno();
}
} while (rv<0);
return rv>0;
prefix_ void senf::FileBody::close()
{
if (!valid())
- throw SystemException(EBADF);
+ throwErrno(EBADF);
v_close();
fd_ = -1;
}
{
int rv = ::open(name.c_str(),O_RDWR|O_NONBLOCK) ;
if (rv<0)
- throw senf::SystemException(errno);
+ senf::throwErrno();
fd(rv);
}
};
socklen_t len = sizeof(ling);
::memset(&ling,sizeof(ling),0);
if (::getsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
return std::make_pair(ling.l_onoff, ling.l_linger);
}
ling.l_onoff = enable;
ling.l_linger = timeout;
if (::setsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ struct timeval senf::BSDSocketProtocol::timestamp()
{
struct timeval tv;
if (::ioctl(body().fd(), SIOCGSTAMP, &tv) < 0)
- throw SystemException(errno);
+ throwErrno();
return tv;
}
int value;
socklen_t len (sizeof(value));
if (::getsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
return value;
}
{
int ivalue (value);
if (::setsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
///////////////////////////////cc.e////////////////////////////////////////
"/dev/dvb/adapter%d/demux%d") % adapter % device);
int fd = open(devDemux.c_str(), O_RDONLY | O_NONBLOCK);
if (fd < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(fd);
}
const
{
if (::ioctl(body().fd(), DMX_SET_FILTER, filter) < 0)
- throw SystemException(errno);
+ throwErrno();
}
// ----------------------------------------------------------------
"/dev/dvb/adapter%d/demux%d") % adapter % device);
int fd = open(devDemux.c_str(), O_RDONLY | O_NONBLOCK);
if (fd < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(fd);
}
const
{
if (::ioctl(body().fd(), DMX_SET_PES_FILTER, filter) < 0)
- throw SystemException(errno);
+ throwErrno();
}
// ----------------------------------------------------------------
"/dev/dvb/adapter%d/dvr%d") % adapter % device);
int fd = open(devDvr.c_str(), O_RDONLY | O_NONBLOCK);
if (fd < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(fd);
}
const
{
if (::ioctl(body().fd(), DMX_SET_BUFFER_SIZE, size) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::DVBDemuxProtocol::startFiltering()
const
{
if (::ioctl(body().fd(), DMX_START) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::DVBDemuxProtocol::stopFiltering()
const
{
if (::ioctl(body().fd(), DMX_STOP) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ bool senf::DVBDemuxProtocol::eof()
"/dev/dvb/adapter%d/frontend%d") % adapter % device);
int fd = open(devFrontend.c_str(), O_RDONLY | O_NONBLOCK);
if (fd < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(fd);
}
const
{
if (::ioctl(body().fd(), FE_READ_SIGNAL_STRENGTH, strength) < 0)
- throw SystemException(errno);
+ throwErrno();
}
///////////////////////////////cc.e////////////////////////////////////////
unsigned len)
{
if (::getsockname(handle.fd(),addr,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::GenericAddressingPolicy_Base::do_peer(FileHandle handle,
unsigned len)
{
if (::getpeername(handle.fd(),addr,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::GenericAddressingPolicy_Base::do_bind(FileHandle handle,
unsigned len)
{
if (::bind(handle.fd(),addr,len) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::GenericAddressingPolicy_Base::do_connect(FileHandle handle,
int err = 0;
socklen_t len = sizeof(err);
if (::getsockopt(handle.fd(),SOL_SOCKET,SO_ERROR,&err,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
if (err != 0)
- throw SystemException(err);
+ throwErrno(err);
return;
}
case EINTR:
break;
default:
- throw SystemException(errno);
+ throwErrno();
}
else
return;
{
int sock = ::socket(PF_INET,SOCK_DGRAM,0);
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
{
int sock = ::socket(PF_INET6,SOCK_DGRAM,0);
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
const
{
if (::connect(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::IPv4Protocol::bind(INet4SocketAddress const & address)
const
{
if (::bind(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
- throw SystemException(errno);
+ throwErrno();
}
const
{
if (::connect(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::IPv6Protocol::bind(INet6SocketAddress const & address)
const
{
if (::bind(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
- throw SystemException(errno);
+ throwErrno();
}
///////////////////////////////cc.e////////////////////////////////////////
int value;
socklen_t len (sizeof(value));
if (::getsockopt(body().fd(),SOL_TCP,TCP_NODELAY,&value,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
return value;
}
{
int ivalue (value);
if (::setsockopt(body().fd(),SOL_TCP,TCP_NODELAY,&ivalue,sizeof(ivalue)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ unsigned senf::TCPProtocol::siocinq()
{
int n;
if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
- throw SystemException(errno);
+ throwErrno();
return n;
}
{
int n;
if (::ioctl(body().fd(),SIOCOUTQ,&n) < 0)
- throw SystemException(errno);
+ throwErrno();
return n;
}
{
int sock = ::socket(PF_INET,SOCK_STREAM,0);
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
{
int sock = ::socket(PF_INET,SOCK_STREAM,0);
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
bind(address);
reuseaddr(true);
if (::listen(body().fd(),backlog) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ std::auto_ptr<senf::SocketProtocol> senf::TCPv4SocketProtocol::clone()
{
int sock = ::socket(PF_INET6,SOCK_STREAM,0);
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
{
int sock = ::socket(PF_INET6,SOCK_STREAM,0);
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
bind(address);
reuseaddr(true);
if (::listen(body().fd(),backlog) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ std::auto_ptr<senf::SocketProtocol> senf::TCPv6SocketProtocol::clone()
{
int n;
if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
- throw senf::SystemException(errno);
+ throwErrno();
return n;
}
int value;
socklen_t len (sizeof(value));
if (::getsockopt(body().fd(),SOL_IP,IP_MULTICAST_LOOP,&value,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
return value;
}
{
int ivalue (value);
if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::UDPProtocol::mcAddMembership(INet4SocketAddress const & mcAddr)
mreqn.imr_address.s_addr = htons(INADDR_ANY);
mreqn.imr_ifindex = 0;
if (::setsockopt(body().fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::UDPProtocol::mcAddMembership(INet4SocketAddress const & mcAddr,
mreqn.imr_address = reinterpret_cast<struct sockaddr_in const *>(localAddr.sockaddr_p())->sin_addr;
mreqn.imr_ifindex = 0;
if (::setsockopt(body().fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::UDPProtocol::mcDropMembership(INet4SocketAddress const & mcAddr)
mreqn.imr_address.s_addr = htons(INADDR_ANY);
mreqn.imr_ifindex = 0;
if (::setsockopt(body().fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::UDPProtocol::mcDropMembership(INet4SocketAddress const & mcAddr,
mreqn.imr_address = reinterpret_cast<struct sockaddr_in const *>(localAddr.sockaddr_p())->sin_addr;
mreqn.imr_ifindex = 0;
if (::setsockopt(body().fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::UDPProtocol::mcIface(std::string const & iface)
if (!iface.empty()) {
mreqn.imr_ifindex = if_nametoindex(iface.c_str());
if (mreqn.imr_ifindex == 0)
- throw SystemException(EINVAL);
+ throwErrno(EINVAL);
}
if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_IF,&mreqn,sizeof(mreqn)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ unsigned senf::UDPProtocol::mcTTL()
int value;
socklen_t len (sizeof(value));
if (::getsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,&len) < 0)
- throw SystemException(errno);
+ throwErrno();
return value;
}
const
{
if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
{
int sock = ::socket(PF_INET,SOCK_DGRAM,0);
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
{
int sock = ::socket(PF_INET6,SOCK_DGRAM,0);
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
protocol = ETH_P_ALL;
int sock = ::socket(PF_PACKET, socktype, htons(protocol));
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
return 0;
ssize_t l = ::recv(body().fd(),0,0,MSG_PEEK | MSG_TRUNC);
if (l < 0)
- throw SystemException(errno);
+ throwErrno();
return l;
}
struct packet_mreq mreq;
mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
if (mreq.mr_ifindex == 0)
- throw senf::SystemException(EINVAL);
+ senf::throwErrno(EINVAL);
mreq.mr_type = PACKET_MR_MULTICAST;
mreq.mr_alen = 6;
std::copy(address.begin(), address.end(), &mreq.mr_address[0]);
if (::setsockopt(fd, SOL_PACKET,
add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
&mreq, sizeof(mreq)) < 0)
- throw senf::SystemException(errno);
+ senf::throwErrno();
}
}
{
int sock = ::socket(PF_UNIX,SOCK_DGRAM,0);
if (sock < 0)
- throw SystemException(errno);
+ throwErrno();
body().fd(sock);
}
{
int n;
if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
- throw senf::SystemException(errno);
+ throwErrno();
return n;
}
const
{
if(::connect(body().fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::UNProtocol::bind(UNSocketAddress const & address)
const
{
if(::bind(body().fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0)
- throw SystemException(errno);
+ throwErrno();
}
rv = 0;
break;
default:
- throw SystemException(errno);
+ throwErrno();
}
} while (rv<0);
return rv;
rv = 0;
break;
default:
- throw SystemException(errno);
+ throwErrno();
}
} while (rv<0);
return rv;
rv = 0;
break;
default:
- throw SystemException(errno);
+ throwErrno();
}
} while (rv<0);
return rv;
rv = 0;
break;
default:
- throw SystemException(errno);
+ throwErrno();
}
} while (rv<0);
return rv;
const
{
if (::shutdown(body().fd(),SHUT_RDWR) < 0)
- throw SystemException(errno);
+ throwErrno();
if (::close(body().fd()) < 0)
- throw SystemException(errno);
+ throwErrno();
}
prefix_ void senf::SocketProtocol::terminate()
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
-prefix_ void senf::SystemException::init()
-{
- // We normallyl don't want to consume memory in an exception,
- // however all other solutions to format the message are terribly
- // ugly (since thay must use a static and shared buffer ...)
- std::stringstream s;
- if (where_)
- s << where_ << ": ";
- s << "(" << code_ << ") " << description();
- buffer_ = s.str();
-}
-
-prefix_ void senf::throwErrno(char const * where, int code)
+prefix_ void senf::throwErrno(std::string const & where, int code)
{
switch (code) {
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
-prefix_ senf::SystemException::SystemException()
- : where_(0), code_(errno)
-{
- init();
-}
-
-prefix_ senf::SystemException::SystemException(int code)
- : where_(0), code_(code)
-{
- init();
-}
-
-prefix_ senf::SystemException::SystemException(char const * where)
- : where_(where), code_(errno)
-{
- init();
-}
+prefix_ senf::SystemException::SystemException(SystemException const & other)
+ : std::stringstream(other.str(),std::ios::out), code_(other.code_)
+{}
-prefix_ senf::SystemException::SystemException(char const * where, int code)
- : where_(where), code_(code)
+prefix_ senf::SystemException::SystemException(std::string const & where, int code)
+ : std::stringstream(std::ios::out), code_(code)
{
- init();
+ if (! where.empty())
+ (*this) << where << ": ";
+ (*this) << "(" << code_ << ") " << description();
}
prefix_ char const * senf::SystemException::what()
const throw()
{
+ /// \fixme Replace the 'stringstream' base-class with our own stream with a specialized
+ /// streambuf which allows to efficiently access the contents as a C string.
+ buffer_ = this->str();
return buffer_.c_str();
}
-prefix_ char const * senf::SystemException::where()
- const
-{
- return where_;
-}
-
prefix_ int senf::SystemException::code()
const
{
prefix_ void senf::throwErrno()
{
- throwErrno(0, errno);
+ throwErrno("", errno);
}
-prefix_ void senf::throwErrno(char const * where)
+prefix_ void senf::throwErrno(std::string const & where)
{
throwErrno(where, errno);
}
prefix_ void senf::throwErrno(int code)
{
- throwErrno(0, code);
+ throwErrno("", code);
}
///////////////////////////////cci.e///////////////////////////////////////
///////////////////////////////cti.p///////////////////////////////////////
template <int Code>
-prefix_ senf::ErrnoException<Code>::ErrnoException()
- : SystemException(fixed_code)
+prefix_ senf::ErrnoException<Code>::ErrnoException(std::string const & where)
+ : SystemException(where,fixed_code)
{}
+// I for some reason need to explicitly define this constructor even though it's defined identically
+// to the default version (even though SyntaxException has a custom copy constructor, the
+// non-existent std::stringstream copy constructor will be called otherwise). I believe this is a
+// g++ bug.
template <int Code>
-prefix_ senf::ErrnoException<Code>::ErrnoException(char const * where)
- : SystemException(where,fixed_code)
+prefix_ senf::ErrnoException<Code>::ErrnoException(ErrnoException const & other)
+ : SystemException(other)
{}
/////////////////////////////cti.e///////////////////////////////////////
// Custom includes
#include <exception>
#include <string>
+#include <iostream>
+#include <sstream>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/cat.hpp>
+#include <boost/utility.hpp>
//#include "Exception.mpp"
///////////////////////////////hh.p////////////////////////////////////////
/** \brief Exception handling standard UNIX errors (errno)
- This exception is thrown to signal generic \c errno failures. In addition to the \c errno
- number (the code()), this class manages optional origin information. This parameter should
- be provided to further describe, in what context the exception was created.
+ This exception is thrown to signal generic \c errno failures.
- This exception should not be used directly. Instead the derived class ErrnoException should
- be thrown via one of the senf::throwErrno() helpers.
+ This exception cannot be thrown directly. Instead the derived class ErrnoException should be
+ thrown via one of the senf::throwErrno helpers.
+
+ The error message associated with the SystemException may be extended arbitrarily by using
+ the exception like a stream:
+ \code
+ try {
+ // This throw would normally be within some function called from here.
+ senf::throwErrno("::open()");
+
+ // Or you may want to use a more descriptive argument string:
+ senf::throwErrno("::open(\"" + filename + "\")");
+
+ // Or even use boost::format here
+ senf::throwErrno((boost::format("::open(\"%s\")") % filename).str());
+ }
+ catch (SystemException & e) {
+ // You can add further error information later by catching and re-throwing the exception
+ e << " [while operating on user '" << user << "']";
+ throw;
+ }
+ \endcode
\see ErrnoException
\ingroup exception
*/
- class SystemException : public std::exception
+ class SystemException : public std::exception, public std::stringstream
{
public:
- SystemException(); ///< SystemException without error location infor
- /**< The error code is taken from the current value of the
- global \c errno variable */
-
- explicit SystemException(int code); ///< SystemException without error location info
- /**< \param[in] code error number (the \c errno value) */
-
- explicit SystemException(char const * where); ///< SystemException with error location info
- /**< The error code is taken from the current value of the
- global \c errno variable
- \param[in] where description of error origin */
-
- SystemException(char const * where, int code); ///< SystemException with error location info
- /**< \param[in] where description of error origin
- \param[in] code error number (the \c errno value) */
-
virtual char const * what() const throw(); ///< Return verbose error description
- char const * where() const; ///< Error origin
int code() const; ///< Error code (\c errno number)
char const * description() const; ///< Error description (strerror() value)
virtual ~SystemException() throw();
- private:
- void init();
+ protected:
+ SystemException(std::string const & where, int code);
+ SystemException(SystemException const & other);
- char const * const where_;
+ private:
int const code_; // This must be const to make the derived ErrnoException
// class a valid derived class.
- std::string buffer_;
+ mutable std::string buffer_;
+
+ friend void throwErrno(std::string const &, int);
};
/** \brief Error specific system exception
if ((fd = ::open(filename, O_RDWR)) < 0)
senf::throwErrno("open()");
\endcode
+
+ \see SystemException
+
\ingroup exception
*/
template <int Code>
public:
static int const fixed_code = Code;
- ErrnoException(); ///< ErrnoException without error location information
- explicit ErrnoException(char const * where);
+ explicit ErrnoException(std::string const & where);
///< ErrnoException with error location information
+
+ ErrnoException(ErrnoException const & other);
};
/** \brief Throw ErrnoException based on current \c errno value (with location info)
\ingroup exception
*/
- void throwErrno(char const * where);
+ void throwErrno(std::string const & where);
/** \brief Throw ErrnoException based on given \c errno value
\ingroup exception
/** \brief Throw ErrnoException based on given \c errno value (with location info)
\ingroup exception
*/
- void throwErrno(char const * where, int code);
+ void throwErrno(std::string const & where, int code);
enum NoThrow_t { nothrow };
#include "../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp>
+#include <boost/format.hpp>
+#include <errno.h>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
BOOST_AUTO_UNIT_TEST(errnoException)
-{}
+{
+ BOOST_CHECK_THROW( senf::throwErrno(), senf::SystemException );
+ BOOST_CHECK_THROW( senf::throwErrno(ENOENT), senf::SystemException );
+ BOOST_CHECK_THROW( senf::throwErrno(""), senf::SystemException );
+ BOOST_CHECK_THROW( senf::throwErrno("", ENOENT), senf::SystemException );
+
+ try {
+ try {
+ senf::throwErrno("::open()", ENOENT);
+ }
+ catch(senf::SystemException & e) {
+ e << ": x=" << 1 << boost::format(", y=%d") % 2;
+ throw;
+ }
+ }
+ catch (senf::SystemException & e) {
+ BOOST_CHECK_EQUAL( e.code(), ENOENT );
+ BOOST_CHECK_EQUAL( e.what(), "::open(): (2) No such file or directory: x=1, y=2" );
+ }
+}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
+// compile-command: "scons -u all_tests"
// End:
<div id="subtitle">
<ul>
<li><a href="@TOPDIR@/doc/html/xref.html">Open Issues</a></li>
- <li><a class="ext" href="http://svn.berlios.de/wsvn/senf/?op=log&rev=0&sc=0&isdir=1">SVN ChangeLog</a></li>
- <li><a class="ext" href="http://developer.berlios.de/projects/senf">SENF @ BerliOS</a></li>
+ <li><a class="ext" href="http://developer.berlios.de/bugs/?group_id=7489">Bug Tracker</a></li>
+ <li><a class="ext" href="http://svn.berlios.de/viewcvs/senf/trunk/">Browse SVN</a></li>
+ <li><a class="ext" href="http://svn.berlios.de/wsvn/senf/?op=log&rev=0&sc=0&isdir=1">ChangeLog</a></li>
+ <li><a class="ext" href="http://developer.berlios.de/projects/senf">BerliOS</a></li>
<li><a class="ext" href="http://openfacts.berlios.de/index-en.phtml?title=SENF+Network+Framework">Wiki</a></li>
<li><a href="@TOPDIR@/doc/html/index.html">Home</a></li>
</ul>