Utils: Implement more flexible SystemException
g0dil [Fri, 23 Nov 2007 17:34:30 +0000 (17:34 +0000)]
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

34 files changed:
Scheduler/ClockService.cc
Scheduler/ReadHelper.ct
Scheduler/ReadHelper.cti
Scheduler/Scheduler.cc
Scheduler/WriteHelper.ct
Scheduler/WriteHelper.cti
Socket/BufferingPolicy.cc
Socket/CommunicationPolicy.cc
Socket/FileHandle.cc
Socket/FileHandle.cci
Socket/FileHandle.test.cc
Socket/Protocols/BSDSocketProtocol.cc
Socket/Protocols/DVB/DVBDemuxHandles.cc
Socket/Protocols/DVB/DVBDemuxProtocol.cc
Socket/Protocols/DVB/DVBFrontendHandle.cc
Socket/Protocols/GenericAddressingPolicy.cc
Socket/Protocols/INet/ConnectedUDPSocketHandle.cc
Socket/Protocols/INet/INetProtocol.cc
Socket/Protocols/INet/TCPProtocol.cc
Socket/Protocols/INet/TCPSocketHandle.cc
Socket/Protocols/INet/UDPProtocol.cc
Socket/Protocols/INet/UDPSocketHandle.cc
Socket/Protocols/Raw/PacketSocketHandle.cc
Socket/Protocols/UN/UNDatagramSocketHandle.cc
Socket/Protocols/UN/UNProtocol.cc
Socket/ReadWritePolicy.cc
Socket/SocketProtocol.cc
Utils/Exception.cc
Utils/Exception.cci
Utils/Exception.cti
Utils/Exception.hh
Utils/Exception.test.cc
config.hh
doclib/SConscript

index 21a34b4..953c70f 100644 (file)
@@ -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
index 6e388f3..1be8a8d 100644 (file)
@@ -71,7 +71,7 @@ prefix_ void senf::ReadHelper<Handle>::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);
index 92d1264..88fadbb 100644 (file)
@@ -94,7 +94,7 @@ template <class Handle>
 prefix_ void senf::ReadHelper<Handle>::throw_error()
     const
 {
-    if (errno_ != 0) throw SystemException(errno_);
+    if (errno_ != 0) throwErrno(errno_);
 }
 
 ///////////////////////////////cti.e///////////////////////////////////////
index 1afc018..90ba9ef 100644 (file)
@@ -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();
 
index 898a549..afc09c6 100644 (file)
@@ -78,7 +78,7 @@ prefix_ void senf::WriteHelper<Handle>::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();
index a6a928a..2fd9fe9 100644 (file)
@@ -62,7 +62,7 @@ prefix_ void senf::WriteHelper<Handle>::throw_error()
     const
 {
     if (errno_ != 0)
-        throw senf::SystemException(errno_);
+        throwErrno(errno_);
 }
 
 
index c0983b9..19cb69f 100644 (file)
@@ -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////////////////////////////////////////
index 407dc54..3d67fb4 100644 (file)
@@ -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;
index 9110b6b..7aa9e24 100644 (file)
@@ -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;
index 312bc4e..62b9304 100644 (file)
@@ -54,7 +54,7 @@ prefix_  senf::FileBody::~FileBody()
 prefix_ void senf::FileBody::close()
 {
     if (!valid())
-        throw SystemException(EBADF);
+        throwErrno(EBADF);
     v_close();
     fd_ = -1;
 }
index 2b9395b..19fd1d7 100644 (file)
@@ -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);
             }
     };
index cd30a73..56fd6a4 100644 (file)
@@ -43,7 +43,7 @@ prefix_ std::pair<bool,unsigned> 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////////////////////////////////////////
index 13c70dd..c24a40f 100644 (file)
@@ -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);
 }
 
index d4172b3..1a2c70e 100644 (file)
@@ -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()
index a90eca4..7b121eb 100644 (file)
@@ -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////////////////////////////////////////
index 70ac3d5..3e77b55 100644 (file)
@@ -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;
index f2049bc..ef74194 100644 (file)
@@ -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);
 }
 
index e5bd24c..477e9ac 100644 (file)
@@ -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////////////////////////////////////////
index 6c7337d..79646be 100644 (file)
@@ -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;
 }
 
index f68db94..0825295 100644 (file)
@@ -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::SocketProtocol> 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::SocketProtocol> senf::TCPv6SocketProtocol::clone()
index fd681c9..22f1ac5 100644 (file)
@@ -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<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)
@@ -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<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)
@@ -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();
 }
 
 
index 35caf99..3d7f3d2 100644 (file)
@@ -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);
 }
 
index 8027f52..ca9a07a 100644 (file)
@@ -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();
     }
 
 }
index 1f37489..a91f49e 100644 (file)
@@ -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);
 }
 
index 4e48938..7e2f49e 100644 (file)
@@ -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();
     
 }
 
index 4b43625..1e808a0 100644 (file)
@@ -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;
index e341447..13ee94e 100644 (file)
@@ -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()
index de36e86..2185643 100644 (file)
 #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) {
 
index 9903bec..a601955 100644 (file)
 #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///////////////////////////////////////
index bd89b67..f0be6aa 100644 (file)
 ///////////////////////////////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///////////////////////////////////////
index b19c2db..7162040 100644 (file)
 // 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////////////////////////////////////////
@@ -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 <int Code>
@@ -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 };
 
index 314cc41..50e3c97 100644 (file)
 
 #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_
index 3a8b2c9..4123383 100644 (file)
--- 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:
index a162731..7844638 100644 (file)
@@ -106,8 +106,10 @@ div.tabs ul li.$projectname a { background-color: #EDE497; }
   <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>