From: g0dil Date: Fri, 23 Nov 2007 17:34:30 +0000 (+0000) Subject: Utils: Implement more flexible SystemException X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=34378cabd0ef59515f60b8e535d50fd5488c84e2;p=senf.git Utils: Implement more flexible SystemException Replace all 'throw SystemException(...)' commands with 'throwErrno(...)' Add additional links to documentation header git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@533 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Scheduler/ClockService.cc b/Scheduler/ClockService.cc index 21a34b4..953c70f 100644 --- a/Scheduler/ClockService.cc +++ b/Scheduler/ClockService.cc @@ -37,7 +37,7 @@ #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 diff --git a/Scheduler/ReadHelper.ct b/Scheduler/ReadHelper.ct index 6e388f3..1be8a8d 100644 --- a/Scheduler/ReadHelper.ct +++ b/Scheduler/ReadHelper.ct @@ -71,7 +71,7 @@ prefix_ void senf::ReadHelper::process(Handle handle, { try { if (event != senf::Scheduler::EV_READ) - throw SystemException(EPIPE); + throwErrno(EPIPE); std::string rcv; handle.read(rcv, maxSize_ - data_.size()); data_.append(rcv); diff --git a/Scheduler/ReadHelper.cti b/Scheduler/ReadHelper.cti index 92d1264..88fadbb 100644 --- a/Scheduler/ReadHelper.cti +++ b/Scheduler/ReadHelper.cti @@ -94,7 +94,7 @@ template prefix_ void senf::ReadHelper::throw_error() const { - if (errno_ != 0) throw SystemException(errno_); + if (errno_ != 0) throwErrno(errno_); } ///////////////////////////////cti.e/////////////////////////////////////// diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc index 1afc018..90ba9ef 100644 --- a/Scheduler/Scheduler.cc +++ b/Scheduler/Scheduler.cc @@ -58,24 +58,24 @@ prefix_ senf::Scheduler::Scheduler() 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) @@ -181,7 +181,7 @@ prefix_ void senf::Scheduler::registerSigHandlers() if (signal == SIGCHLD) sa.sa_flags |= SA_NOCLDSTOP; if (::sigaction(signal, &sa, 0) < 0) - throw SystemException(errno); + throwErrno(); } } } @@ -254,7 +254,7 @@ prefix_ void senf::Scheduler::process() if (events<0) if (errno != EINTR) - throw SystemException(errno); + throwErrno(); eventTime_ = ClockService::now(); diff --git a/Scheduler/WriteHelper.ct b/Scheduler/WriteHelper.ct index 898a549..afc09c6 100644 --- a/Scheduler/WriteHelper.ct +++ b/Scheduler/WriteHelper.ct @@ -78,7 +78,7 @@ prefix_ void senf::WriteHelper::process(Handle handle, 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(); diff --git a/Scheduler/WriteHelper.cti b/Scheduler/WriteHelper.cti index a6a928a..2fd9fe9 100644 --- a/Scheduler/WriteHelper.cti +++ b/Scheduler/WriteHelper.cti @@ -62,7 +62,7 @@ prefix_ void senf::WriteHelper::throw_error() const { if (errno_ != 0) - throw senf::SystemException(errno_); + throwErrno(errno_); } diff --git a/Socket/BufferingPolicy.cc b/Socket/BufferingPolicy.cc index c0983b9..19cb69f 100644 --- a/Socket/BufferingPolicy.cc +++ b/Socket/BufferingPolicy.cc @@ -42,7 +42,7 @@ prefix_ unsigned senf::SocketBufferingPolicy::rcvbuf(FileHandle handle) 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; @@ -51,7 +51,7 @@ prefix_ unsigned senf::SocketBufferingPolicy::rcvbuf(FileHandle handle) 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) @@ -59,7 +59,7 @@ 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; @@ -69,7 +69,7 @@ prefix_ unsigned senf::SocketBufferingPolicy::sndbuf(FileHandle handle) 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//////////////////////////////////////// diff --git a/Socket/CommunicationPolicy.cc b/Socket/CommunicationPolicy.cc index 407dc54..3d67fb4 100644 --- a/Socket/CommunicationPolicy.cc +++ b/Socket/CommunicationPolicy.cc @@ -58,7 +58,7 @@ prefix_ int senf::ConnectedCommunicationPolicy::do_accept(FileHandle handle, case EINTR: break; default: - throw SystemException(errno); + throwErrno(); } } while (rv<0); return rv; diff --git a/Socket/FileHandle.cc b/Socket/FileHandle.cc index 9110b6b..7aa9e24 100644 --- a/Socket/FileHandle.cc +++ b/Socket/FileHandle.cc @@ -41,7 +41,7 @@ prefix_ void senf::FileBody::v_close() { if (::close(fd_) != 0) - throw SystemException(errno); + throwErrno(); } prefix_ void senf::FileBody::v_terminate() @@ -65,17 +65,17 @@ prefix_ bool senf::FileBody::blocking() 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 @@ -96,7 +96,7 @@ prefix_ bool senf::FileBody::pollCheck(int fd, bool incoming, bool block) case EINTR: break; default: - throw SystemException(errno); + throwErrno(); } } while (rv<0); return rv>0; diff --git a/Socket/FileHandle.cci b/Socket/FileHandle.cci index 312bc4e..62b9304 100644 --- a/Socket/FileHandle.cci +++ b/Socket/FileHandle.cci @@ -54,7 +54,7 @@ prefix_ senf::FileBody::~FileBody() prefix_ void senf::FileBody::close() { if (!valid()) - throw SystemException(EBADF); + throwErrno(EBADF); v_close(); fd_ = -1; } diff --git a/Socket/FileHandle.test.cc b/Socket/FileHandle.test.cc index 2b9395b..19fd1d7 100644 --- a/Socket/FileHandle.test.cc +++ b/Socket/FileHandle.test.cc @@ -51,7 +51,7 @@ namespace { { int rv = ::open(name.c_str(),O_RDWR|O_NONBLOCK) ; if (rv<0) - throw senf::SystemException(errno); + senf::throwErrno(); fd(rv); } }; diff --git a/Socket/Protocols/BSDSocketProtocol.cc b/Socket/Protocols/BSDSocketProtocol.cc index cd30a73..56fd6a4 100644 --- a/Socket/Protocols/BSDSocketProtocol.cc +++ b/Socket/Protocols/BSDSocketProtocol.cc @@ -43,7 +43,7 @@ prefix_ std::pair senf::BSDSocketProtocol::linger() 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); } @@ -54,7 +54,7 @@ prefix_ void senf::BSDSocketProtocol::linger(bool enable, unsigned timeout) 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() @@ -62,7 +62,7 @@ prefix_ struct timeval senf::BSDSocketProtocol::timestamp() { struct timeval tv; if (::ioctl(body().fd(), SIOCGSTAMP, &tv) < 0) - throw SystemException(errno); + throwErrno(); return tv; } @@ -74,7 +74,7 @@ prefix_ bool senf::AddressableBSDSocketProtocol::reuseaddr() int value; socklen_t len (sizeof(value)); if (::getsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0) - throw SystemException(errno); + throwErrno(); return value; } @@ -83,7 +83,7 @@ prefix_ void senf::AddressableBSDSocketProtocol::reuseaddr(bool value) { int ivalue (value); if (::setsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0) - throw SystemException(errno); + throwErrno(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/Protocols/DVB/DVBDemuxHandles.cc b/Socket/Protocols/DVB/DVBDemuxHandles.cc index 13c70dd..c24a40f 100644 --- a/Socket/Protocols/DVB/DVBDemuxHandles.cc +++ b/Socket/Protocols/DVB/DVBDemuxHandles.cc @@ -47,7 +47,7 @@ prefix_ void senf::DVBDemuxSectionProtocol::init_client(unsigned short adapter, "/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); } @@ -67,7 +67,7 @@ prefix_ void senf::DVBDemuxSectionProtocol::setSectionFilter(struct dmx_sct_filt const { if (::ioctl(body().fd(), DMX_SET_FILTER, filter) < 0) - throw SystemException(errno); + throwErrno(); } // ---------------------------------------------------------------- @@ -79,7 +79,7 @@ prefix_ void senf::DVBDemuxPESProtocol::init_client(unsigned short adapter, unsi "/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); } @@ -99,7 +99,7 @@ prefix_ void senf::DVBDemuxPESProtocol::setPESFilter(struct dmx_pes_filter_param const { if (::ioctl(body().fd(), DMX_SET_PES_FILTER, filter) < 0) - throw SystemException(errno); + throwErrno(); } // ---------------------------------------------------------------- @@ -111,7 +111,7 @@ prefix_ void senf::DVBDvrProtocol::init_client(unsigned short adapter, unsigned "/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); } diff --git a/Socket/Protocols/DVB/DVBDemuxProtocol.cc b/Socket/Protocols/DVB/DVBDemuxProtocol.cc index d4172b3..1a2c70e 100644 --- a/Socket/Protocols/DVB/DVBDemuxProtocol.cc +++ b/Socket/Protocols/DVB/DVBDemuxProtocol.cc @@ -42,21 +42,21 @@ prefix_ void senf::DVBDemuxProtocol::setBufferSize(unsigned long size) 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() diff --git a/Socket/Protocols/DVB/DVBFrontendHandle.cc b/Socket/Protocols/DVB/DVBFrontendHandle.cc index a90eca4..7b121eb 100644 --- a/Socket/Protocols/DVB/DVBFrontendHandle.cc +++ b/Socket/Protocols/DVB/DVBFrontendHandle.cc @@ -47,7 +47,7 @@ prefix_ void senf::DVBFrontendProtocol::init_client(uint8_t adapter, boost::uint "/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); } @@ -74,7 +74,7 @@ prefix_ void senf::DVBFrontendProtocol::signalStrength(int16_t *strength) const { if (::ioctl(body().fd(), FE_READ_SIGNAL_STRENGTH, strength) < 0) - throw SystemException(errno); + throwErrno(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/Protocols/GenericAddressingPolicy.cc b/Socket/Protocols/GenericAddressingPolicy.cc index 70ac3d5..3e77b55 100644 --- a/Socket/Protocols/GenericAddressingPolicy.cc +++ b/Socket/Protocols/GenericAddressingPolicy.cc @@ -41,7 +41,7 @@ prefix_ void senf::GenericAddressingPolicy_Base::do_local(FileHandle handle, unsigned len) { if (::getsockname(handle.fd(),addr,&len) < 0) - throw SystemException(errno); + throwErrno(); } prefix_ void senf::GenericAddressingPolicy_Base::do_peer(FileHandle handle, @@ -49,7 +49,7 @@ 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, @@ -57,7 +57,7 @@ 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, @@ -72,15 +72,15 @@ 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; diff --git a/Socket/Protocols/INet/ConnectedUDPSocketHandle.cc b/Socket/Protocols/INet/ConnectedUDPSocketHandle.cc index f2049bc..ef74194 100644 --- a/Socket/Protocols/INet/ConnectedUDPSocketHandle.cc +++ b/Socket/Protocols/INet/ConnectedUDPSocketHandle.cc @@ -46,7 +46,7 @@ prefix_ void senf::ConnectedUDPv4SocketProtocol::init_client() { int sock = ::socket(PF_INET,SOCK_DGRAM,0); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } @@ -72,7 +72,7 @@ prefix_ void senf::ConnectedUDPv6SocketProtocol::init_client() { int sock = ::socket(PF_INET6,SOCK_DGRAM,0); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } diff --git a/Socket/Protocols/INet/INetProtocol.cc b/Socket/Protocols/INet/INetProtocol.cc index e5bd24c..477e9ac 100644 --- a/Socket/Protocols/INet/INetProtocol.cc +++ b/Socket/Protocols/INet/INetProtocol.cc @@ -42,14 +42,14 @@ prefix_ void senf::IPv4Protocol::connect(INet4SocketAddress const & address) 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(); } @@ -60,14 +60,14 @@ prefix_ void senf::IPv6Protocol::connect(INet6SocketAddress const & address) 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//////////////////////////////////////// diff --git a/Socket/Protocols/INet/TCPProtocol.cc b/Socket/Protocols/INet/TCPProtocol.cc index 6c7337d..79646be 100644 --- a/Socket/Protocols/INet/TCPProtocol.cc +++ b/Socket/Protocols/INet/TCPProtocol.cc @@ -45,7 +45,7 @@ prefix_ bool senf::TCPProtocol::nodelay() int value; socklen_t len (sizeof(value)); if (::getsockopt(body().fd(),SOL_TCP,TCP_NODELAY,&value,&len) < 0) - throw SystemException(errno); + throwErrno(); return value; } @@ -54,7 +54,7 @@ prefix_ void senf::TCPProtocol::nodelay(bool 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() @@ -62,7 +62,7 @@ prefix_ unsigned senf::TCPProtocol::siocinq() { int n; if (::ioctl(body().fd(),SIOCINQ,&n) < 0) - throw SystemException(errno); + throwErrno(); return n; } @@ -71,7 +71,7 @@ prefix_ unsigned senf::TCPProtocol::siocoutq() { int n; if (::ioctl(body().fd(),SIOCOUTQ,&n) < 0) - throw SystemException(errno); + throwErrno(); return n; } diff --git a/Socket/Protocols/INet/TCPSocketHandle.cc b/Socket/Protocols/INet/TCPSocketHandle.cc index f68db94..0825295 100644 --- a/Socket/Protocols/INet/TCPSocketHandle.cc +++ b/Socket/Protocols/INet/TCPSocketHandle.cc @@ -46,7 +46,7 @@ prefix_ void senf::TCPv4SocketProtocol::init_client() { int sock = ::socket(PF_INET,SOCK_STREAM,0); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } @@ -63,7 +63,7 @@ prefix_ void senf::TCPv4SocketProtocol::init_server() { int sock = ::socket(PF_INET,SOCK_STREAM,0); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } @@ -75,7 +75,7 @@ prefix_ void senf::TCPv4SocketProtocol::init_server(INet4SocketAddress const & a bind(address); reuseaddr(true); if (::listen(body().fd(),backlog) < 0) - throw SystemException(errno); + throwErrno(); } prefix_ std::auto_ptr senf::TCPv4SocketProtocol::clone() @@ -92,7 +92,7 @@ prefix_ void senf::TCPv6SocketProtocol::init_client() { int sock = ::socket(PF_INET6,SOCK_STREAM,0); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } @@ -109,7 +109,7 @@ prefix_ void senf::TCPv6SocketProtocol::init_server() { int sock = ::socket(PF_INET6,SOCK_STREAM,0); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } @@ -121,7 +121,7 @@ prefix_ void senf::TCPv6SocketProtocol::init_server(INet6SocketAddress const & a bind(address); reuseaddr(true); if (::listen(body().fd(),backlog) < 0) - throw SystemException(errno); + throwErrno(); } prefix_ std::auto_ptr senf::TCPv6SocketProtocol::clone() diff --git a/Socket/Protocols/INet/UDPProtocol.cc b/Socket/Protocols/INet/UDPProtocol.cc index fd681c9..22f1ac5 100644 --- a/Socket/Protocols/INet/UDPProtocol.cc +++ b/Socket/Protocols/INet/UDPProtocol.cc @@ -45,7 +45,7 @@ prefix_ unsigned senf::UDPProtocol::available() { int n; if (::ioctl(body().fd(),SIOCINQ,&n) < 0) - throw senf::SystemException(errno); + throwErrno(); return n; } @@ -61,7 +61,7 @@ prefix_ bool senf::UDPProtocol::mcLoop() 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; } @@ -70,7 +70,7 @@ prefix_ void senf::UDPProtocol::mcLoop(bool 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) @@ -81,7 +81,7 @@ prefix_ void senf::UDPProtocol::mcAddMembership(INet4SocketAddress const & mcAdd 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, @@ -93,7 +93,7 @@ prefix_ void senf::UDPProtocol::mcAddMembership(INet4SocketAddress const & mcAdd mreqn.imr_address = reinterpret_cast(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) @@ -104,7 +104,7 @@ prefix_ void senf::UDPProtocol::mcDropMembership(INet4SocketAddress const & mcAd 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, @@ -116,7 +116,7 @@ prefix_ void senf::UDPProtocol::mcDropMembership(INet4SocketAddress const & mcAd mreqn.imr_address = reinterpret_cast(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) @@ -127,10 +127,10 @@ 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() @@ -139,7 +139,7 @@ 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; } @@ -147,7 +147,7 @@ prefix_ void senf::UDPProtocol::mcTTL(unsigned value) const { if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0) - throw SystemException(errno); + throwErrno(); } diff --git a/Socket/Protocols/INet/UDPSocketHandle.cc b/Socket/Protocols/INet/UDPSocketHandle.cc index 35caf99..3d7f3d2 100644 --- a/Socket/Protocols/INet/UDPSocketHandle.cc +++ b/Socket/Protocols/INet/UDPSocketHandle.cc @@ -46,7 +46,7 @@ prefix_ void senf::UDPv4SocketProtocol::init_client() { int sock = ::socket(PF_INET,SOCK_DGRAM,0); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } @@ -72,7 +72,7 @@ prefix_ void senf::UDPv6SocketProtocol::init_client() { int sock = ::socket(PF_INET6,SOCK_DGRAM,0); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } diff --git a/Socket/Protocols/Raw/PacketSocketHandle.cc b/Socket/Protocols/Raw/PacketSocketHandle.cc index 8027f52..ca9a07a 100644 --- a/Socket/Protocols/Raw/PacketSocketHandle.cc +++ b/Socket/Protocols/Raw/PacketSocketHandle.cc @@ -50,7 +50,7 @@ prefix_ void senf::PacketProtocol::init_client(SocketType type, int protocol) protocol = ETH_P_ALL; int sock = ::socket(PF_PACKET, socktype, htons(protocol)); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } @@ -67,7 +67,7 @@ prefix_ unsigned senf::PacketProtocol::available() return 0; ssize_t l = ::recv(body().fd(),0,0,MSG_PEEK | MSG_TRUNC); if (l < 0) - throw SystemException(errno); + throwErrno(); return l; } @@ -84,14 +84,14 @@ namespace { 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(); } } diff --git a/Socket/Protocols/UN/UNDatagramSocketHandle.cc b/Socket/Protocols/UN/UNDatagramSocketHandle.cc index 1f37489..a91f49e 100644 --- a/Socket/Protocols/UN/UNDatagramSocketHandle.cc +++ b/Socket/Protocols/UN/UNDatagramSocketHandle.cc @@ -39,7 +39,7 @@ prefix_ void senf::UNDatagramSocketProtocol::init_client() const { int sock = ::socket(PF_UNIX,SOCK_DGRAM,0); if (sock < 0) - throw SystemException(errno); + throwErrno(); body().fd(sock); } diff --git a/Socket/Protocols/UN/UNProtocol.cc b/Socket/Protocols/UN/UNProtocol.cc index 4e48938..7e2f49e 100644 --- a/Socket/Protocols/UN/UNProtocol.cc +++ b/Socket/Protocols/UN/UNProtocol.cc @@ -39,7 +39,7 @@ prefix_ unsigned senf::UNProtocol::available() { int n; if (::ioctl(body().fd(),SIOCINQ,&n) < 0) - throw senf::SystemException(errno); + throwErrno(); return n; } @@ -53,14 +53,14 @@ prefix_ void senf::UNProtocol::connect(UNSocketAddress const & address) 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(); } diff --git a/Socket/ReadWritePolicy.cc b/Socket/ReadWritePolicy.cc index 4b43625..1e808a0 100644 --- a/Socket/ReadWritePolicy.cc +++ b/Socket/ReadWritePolicy.cc @@ -53,7 +53,7 @@ prefix_ unsigned senf::ReadablePolicy::read(FileHandle handle, char * buffer, rv = 0; break; default: - throw SystemException(errno); + throwErrno(); } } while (rv<0); return rv; @@ -74,7 +74,7 @@ prefix_ unsigned senf::ReadablePolicy::do_readfrom(FileHandle handle, char * buf rv = 0; break; default: - throw SystemException(errno); + throwErrno(); } } while (rv<0); return rv; @@ -100,7 +100,7 @@ prefix_ unsigned senf::WriteablePolicy::do_write(FileHandle handle, char const * rv = 0; break; default: - throw SystemException(errno); + throwErrno(); } } while (rv<0); return rv; @@ -121,7 +121,7 @@ prefix_ unsigned senf::WriteablePolicy::do_writeto(FileHandle handle, rv = 0; break; default: - throw SystemException(errno); + throwErrno(); } } while (rv<0); return rv; diff --git a/Socket/SocketProtocol.cc b/Socket/SocketProtocol.cc index e341447..13ee94e 100644 --- a/Socket/SocketProtocol.cc +++ b/Socket/SocketProtocol.cc @@ -37,9 +37,9 @@ prefix_ void senf::SocketProtocol::close() 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() diff --git a/Utils/Exception.cc b/Utils/Exception.cc index de36e86..2185643 100644 --- a/Utils/Exception.cc +++ b/Utils/Exception.cc @@ -33,19 +33,7 @@ #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) { diff --git a/Utils/Exception.cci b/Utils/Exception.cci index 9903bec..a601955 100644 --- a/Utils/Exception.cci +++ b/Utils/Exception.cci @@ -27,42 +27,27 @@ #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 { @@ -97,17 +82,17 @@ prefix_ senf::SystemException::~SystemException() 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/////////////////////////////////////// diff --git a/Utils/Exception.cti b/Utils/Exception.cti index bd89b67..f0be6aa 100644 --- a/Utils/Exception.cti +++ b/Utils/Exception.cti @@ -31,13 +31,17 @@ ///////////////////////////////cti.p/////////////////////////////////////// template -prefix_ senf::ErrnoException::ErrnoException() - : SystemException(fixed_code) +prefix_ senf::ErrnoException::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 -prefix_ senf::ErrnoException::ErrnoException(char const * where) - : SystemException(where,fixed_code) +prefix_ senf::ErrnoException::ErrnoException(ErrnoException const & other) + : SystemException(other) {} /////////////////////////////cti.e/////////////////////////////////////// diff --git a/Utils/Exception.hh b/Utils/Exception.hh index b19c2db..7162040 100644 --- a/Utils/Exception.hh +++ b/Utils/Exception.hh @@ -29,8 +29,11 @@ // Custom includes #include #include +#include +#include #include #include +#include //#include "Exception.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -73,38 +76,39 @@ namespace senf { /** \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) @@ -114,13 +118,16 @@ namespace senf { 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 @@ -135,6 +142,9 @@ namespace senf { if ((fd = ::open(filename, O_RDWR)) < 0) senf::throwErrno("open()"); \endcode + + \see SystemException + \ingroup exception */ template @@ -143,9 +153,10 @@ namespace senf { 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); }; @@ -157,7 +168,7 @@ namespace senf { /** \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 @@ -167,7 +178,7 @@ namespace senf { /** \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 }; diff --git a/Utils/Exception.test.cc b/Utils/Exception.test.cc index 314cc41..50e3c97 100644 --- a/Utils/Exception.test.cc +++ b/Utils/Exception.test.cc @@ -31,12 +31,33 @@ #include "../Utils/auto_unit_test.hh" #include +#include +#include #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_ diff --git a/config.hh b/config.hh index 3a8b2c9..4123383 100644 --- a/config.hh +++ b/config.hh @@ -88,5 +88,5 @@ // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" -// compile-command: "scons -u test" +// compile-command: "scons -u all_tests" // End: diff --git a/doclib/SConscript b/doclib/SConscript index a162731..7844638 100644 --- a/doclib/SConscript +++ b/doclib/SConscript @@ -106,8 +106,10 @@ div.tabs ul li.$projectname a { background-color: #EDE497; }