}
}
+prefix_ senf::FileHandle senf::FileBody::handle()
+{
+ return FileHandle(ptr(this));
+}
+
prefix_ int senf::FileBody::fd()
const
{
: body_(body.release())
{}
+prefix_ senf::FileHandle::FileHandle(FileBody::ptr body)
+ : body_(body)
+{}
+
prefix_ senf::FileBody & senf::FileHandle::body()
{
BOOST_ASSERT(body_);
\c new. To configure the FileHandle behavior, A derived class
may provide any class derived from FileBody here. */
+ explicit FileHandle(FileBody::ptr body);
+
FileBody & body(); ///< Access body
FileBody const & body() const; ///< Access body in const context
static FileBody & body(FileHandle & handle); ///< Access body of another FileHandle instance
private:
FileBody::ptr body_;
+
+ friend class FileBody;
};
/** \brief Adapt FileHandle to senf::Scheduler
namespace senf {
+ class FileHandle;
/** \brief FileHandle referenced body
///@}
///////////////////////////////////////////////////////////////////////////
+ FileHandle handle();
+
int fd() const;
void fd(int fd);
struct linger ling;
socklen_t len = sizeof(ling);
::memset(&ling,sizeof(ling),0);
- if (::getsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,&len) < 0)
+ if (::getsockopt(fd(),SOL_SOCKET,SO_LINGER,&ling,&len) < 0)
throwErrno();
return std::make_pair(ling.l_onoff, ling.l_linger);
}
struct linger ling;
ling.l_onoff = enable;
ling.l_linger = timeout;
- if (::setsockopt(body().fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling)) < 0)
+ if (::setsockopt(fd(),SOL_SOCKET,SO_LINGER,&ling,sizeof(ling)) < 0)
throwErrno();
}
const
{
struct timeval tv;
- if (::ioctl(body().fd(), SIOCGSTAMP, &tv) < 0)
+ if (::ioctl(fd(), SIOCGSTAMP, &tv) < 0)
throwErrno();
return tv;
}
{
int value;
socklen_t len (sizeof(value));
- if (::getsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0)
+ if (::getsockopt(fd(),SOL_SOCKET,SO_REUSEADDR,&value,&len) < 0)
throwErrno();
return value;
}
const
{
int ivalue (value);
- if (::setsockopt(body().fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0)
+ if (::setsockopt(fd(),SOL_SOCKET,SO_REUSEADDR,&ivalue,sizeof(ivalue)) < 0)
throwErrno();
}
{
std::string devDemux = str( boost::format(
"/dev/dvb/adapter%d/demux%d") % adapter % device);
- int fd = open(devDemux.c_str(), O_RDONLY | O_NONBLOCK);
- if (fd < 0)
+ int f = open(devDemux.c_str(), O_RDONLY | O_NONBLOCK);
+ if (f < 0)
throwErrno();
- body().fd(fd);
+ fd(f);
}
prefix_ unsigned senf::DVBDemuxSectionProtocol::available()
prefix_ void senf::DVBDemuxSectionProtocol::setSectionFilter(struct dmx_sct_filter_params *filter)
const
{
- if (::ioctl(body().fd(), DMX_SET_FILTER, filter) < 0)
+ if (::ioctl(fd(), DMX_SET_FILTER, filter) < 0)
throwErrno();
}
{
std::string devDemux = str( boost::format(
"/dev/dvb/adapter%d/demux%d") % adapter % device);
- int fd = open(devDemux.c_str(), O_RDONLY | O_NONBLOCK);
- if (fd < 0)
+ int f = open(devDemux.c_str(), O_RDONLY | O_NONBLOCK);
+ if (f < 0)
throwErrno();
- body().fd(fd);
+ fd(f);
}
prefix_ unsigned senf::DVBDemuxPESProtocol::available()
prefix_ void senf::DVBDemuxPESProtocol::setPESFilter(struct dmx_pes_filter_params *filter)
const
{
- if (::ioctl(body().fd(), DMX_SET_PES_FILTER, filter) < 0)
+ if (::ioctl(fd(), DMX_SET_PES_FILTER, filter) < 0)
throwErrno();
}
{
std::string devDvr = str( boost::format(
"/dev/dvb/adapter%d/dvr%d") % adapter % device);
- int fd = open(devDvr.c_str(), O_RDONLY | O_NONBLOCK);
- if (fd < 0)
+ int f = open(devDvr.c_str(), O_RDONLY | O_NONBLOCK);
+ if (f < 0)
throwErrno();
- body().fd(fd);
+ fd(f);
}
prefix_ unsigned senf::DVBDvrProtocol::available()
prefix_ void senf::DVBDemuxProtocol::setBufferSize(unsigned long size)
const
{
- if (::ioctl(body().fd(), DMX_SET_BUFFER_SIZE, size) < 0)
+ if (::ioctl(fd(), DMX_SET_BUFFER_SIZE, size) < 0)
throwErrno();
}
prefix_ void senf::DVBDemuxProtocol::startFiltering()
const
{
- if (::ioctl(body().fd(), DMX_START) < 0)
+ if (::ioctl(fd(), DMX_START) < 0)
throwErrno();
}
prefix_ void senf::DVBDemuxProtocol::stopFiltering()
const
{
- if (::ioctl(body().fd(), DMX_STOP) < 0)
+ if (::ioctl(fd(), DMX_STOP) < 0)
throwErrno();
}
{
std::string devFrontend = str( boost::format(
"/dev/dvb/adapter%d/frontend%d") % adapter % device);
- int fd = open(devFrontend.c_str(), O_RDONLY | O_NONBLOCK);
- if (fd < 0)
+ int f = open(devFrontend.c_str(), O_RDONLY | O_NONBLOCK);
+ if (f < 0)
throwErrno();
- body().fd(fd);
+ fd(f);
}
prefix_ unsigned senf::DVBFrontendProtocol::available()
prefix_ void senf::DVBFrontendProtocol::signalStrength(int16_t *strength)
const
{
- if (::ioctl(body().fd(), FE_READ_SIGNAL_STRENGTH, strength) < 0)
+ if (::ioctl(fd(), FE_READ_SIGNAL_STRENGTH, strength) < 0)
throwErrno();
}
int sock = ::socket(PF_INET, SOCK_RAW, protocol);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
int sock = ::socket(PF_INET6,SOCK_RAW,protocol);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
+//#include "ConnectedRawInetSocketHandle.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
int sock = ::socket(PF_INET,SOCK_DGRAM,0);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
int sock = ::socket(PF_INET6,SOCK_DGRAM,0);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
INet4Address address() const; ///< Return address
unsigned port() const; ///< Return port number
- bool boolean_test() const; ///< \c true, if address is empty (i.e. 0.0.0.0:0)
+ bool boolean_test() const; ///< \c true, if address is not empty (i.e. 0.0.0.0:0)
void clear(); ///< Clear address/port to 0.0.0.0:0
prefix_ void senf::IPv4Protocol::connect(INet4SocketAddress const & address)
const
{
- if (::connect(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
+ if (::connect(fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
throwErrno();
}
prefix_ void senf::IPv4Protocol::bind(INet4SocketAddress const & address)
const
{
- if (::bind(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
+ if (::bind(fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
throwErrno();
}
prefix_ void senf::IPv6Protocol::connect(INet6SocketAddress const & address)
const
{
- if (::connect(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
+ if (::connect(fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
throwErrno();
}
prefix_ void senf::IPv6Protocol::bind(INet6SocketAddress const & address)
const
{
- if (::bind(body().fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
+ if (::bind(fd(),address.sockaddr_p(), address.sockaddr_len()) < 0)
throwErrno();
}
const
{
int n;
- if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
+ if (::ioctl(fd(),SIOCINQ,&n) < 0)
throwErrno();
return n;
}
{
return false;
}
+
+///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
+//#include "UDPProtocol.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
int sock = ::socket(PF_INET, SOCK_RAW, protocol);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
int sock = ::socket(PF_INET6,SOCK_RAW,protocol);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
+//#include "RawInetSocketHandle.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
{
int value;
socklen_t len (sizeof(value));
- if (::getsockopt(body().fd(),SOL_TCP,TCP_NODELAY,&value,&len) < 0)
+ if (::getsockopt(fd(),SOL_TCP,TCP_NODELAY,&value,&len) < 0)
throwErrno();
return value;
}
const
{
int ivalue (value);
- if (::setsockopt(body().fd(),SOL_TCP,TCP_NODELAY,&ivalue,sizeof(ivalue)) < 0)
+ if (::setsockopt(fd(),SOL_TCP,TCP_NODELAY,&ivalue,sizeof(ivalue)) < 0)
throwErrno();
}
const
{
int n;
- if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
+ if (::ioctl(fd(),SIOCINQ,&n) < 0)
throwErrno();
return n;
}
const
{
int n;
- if (::ioctl(body().fd(),SIOCOUTQ,&n) < 0)
+ if (::ioctl(fd(),SIOCOUTQ,&n) < 0)
throwErrno();
return n;
}
prefix_ bool senf::TCPProtocol::eof()
const
{
- return body().readable() && available()==0;
+ return fh().readable() && available()==0;
}
int sock = ::socket(PF_INET,SOCK_STREAM,0);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
int sock = ::socket(PF_INET,SOCK_STREAM,0);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void senf::TCPv4SocketProtocol::init_server(INet4SocketAddress const & address,
init_server();
bind(address);
reuseaddr(true);
- if (::listen(body().fd(),backlog) < 0)
+ if (::listen(fd(),backlog) < 0)
throwErrno();
}
int sock = ::socket(PF_INET6,SOCK_STREAM,0);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
int sock = ::socket(PF_INET6,SOCK_STREAM,0);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void senf::TCPv6SocketProtocol::init_server(INet6SocketAddress const & address,
init_server();
bind(address);
reuseaddr(true);
- if (::listen(body().fd(),backlog) < 0)
+ if (::listen(fd(),backlog) < 0)
throwErrno();
}
/** \brief IPv4 TCP Socket Protocol
\par Socket Handle typedefs:
- \ref TCPv4ClientSocketHandle (ProtocolClientSocketHandle), \ref TCPv4ServerSocketHandle
- (ProtocolServerSocketHandle)
-
+ \ref TCPv4ClientSocketHandle (ProtocolClientSocketHandle), \ref TCPv4ServerSocketHandle
+ (ProtocolServerSocketHandle)
+
\par Policy Interface:
- ClientSocketHandle::read(), ClientSocketHandle::write(), ClientSocketHandle::bind(),
- ClientSocketHandle::local(), ClientSocketHandle::connect(), ClientSocketHandle::peer(),
- ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf()
+ ClientSocketHandle::read(), ClientSocketHandle::write(), ClientSocketHandle::bind(),
+ ClientSocketHandle::local(), ClientSocketHandle::connect(), ClientSocketHandle::peer(),
+ ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf()
\par Address Type:
- INet4Address
+ INet4Address
TCPv4SocketProtocol provides an internet protocol stream socket based on the TCP protocol
and IPv4 addressing.
const
{
int n;
- if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
+ if (::ioctl(fd(),SIOCINQ,&n) < 0)
throwErrno();
return n;
}
{
int value;
socklen_t len (sizeof(value));
- if (::getsockopt(body().fd(),SOL_IP,IP_MULTICAST_LOOP,&value,&len) < 0)
+ if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&value,&len) < 0)
throwErrno();
return value;
}
const
{
int ivalue (value);
- if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0)
+ if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_LOOP,&ivalue,sizeof(ivalue)) < 0)
throwErrno();
}
mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
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)
+ if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
throwErrno();
}
mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
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)
+ if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
throwErrno();
}
mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
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)
+ if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
throwErrno();
}
mreqn.imr_multiaddr = reinterpret_cast<struct sockaddr_in const *>(mcAddr.sockaddr_p())->sin_addr;
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)
+ if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
throwErrno();
}
if (mreqn.imr_ifindex == 0)
throwErrno(EINVAL);
}
- if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_IF,&mreqn,sizeof(mreqn)) < 0)
+ if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_IF,&mreqn,sizeof(mreqn)) < 0)
throwErrno();
}
{
int value;
socklen_t len (sizeof(value));
- if (::getsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,&len) < 0)
+ if (::getsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,&len) < 0)
throwErrno();
return value;
}
prefix_ void senf::UDPProtocol::mcTTL(unsigned value)
const
{
- if (::setsockopt(body().fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0)
+ if (::setsockopt(fd(),SOL_IP,IP_MULTICAST_TTL,&value,sizeof(value)) < 0)
throwErrno();
}
int sock = ::socket(PF_INET,SOCK_DGRAM,0);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
int sock = ::socket(PF_INET6,SOCK_DGRAM,0);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void
int sock = ::socket(PF_PACKET, socktype, htons(protocol));
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ std::auto_ptr<senf::SocketProtocol> senf::PacketProtocol::clone()
prefix_ unsigned senf::PacketProtocol::available()
const
{
- if (! body().readable())
+ if (! fh().readable())
return 0;
- ssize_t l = ::recv(body().fd(),0,0,MSG_PEEK | MSG_TRUNC);
+ ssize_t l = ::recv(fd(),0,0,MSG_PEEK | MSG_TRUNC);
if (l < 0)
throwErrno();
return l;
MACAddress const & address)
const
{
- do_mc(body().fd(),interface,address,true);
+ do_mc(fd(),interface,address,true);
}
prefix_ void senf::PacketProtocol::mcDrop(std::string const & interface,
MACAddress const & address)
const
{
- do_mc(body().fd(),interface,address,false);
+ do_mc(fd(),interface,address,false);
}
///////////////////////////////cc.e////////////////////////////////////////
prefix_ void senf::TapProtocol::init_client(std::string const & interface_name, bool const NO_PI)
const
{
- int fd;
- if ( (fd = ::open("/dev/net/tun", O_RDWR)) < 0 )
+ int f;
+ if ( (f = ::open("/dev/net/tun", O_RDWR)) < 0 )
throwErrno();
struct ifreq ifr;
::memset( &ifr, 0, sizeof(ifr));
if (NO_PI)
ifr.ifr_flags |= IFF_NO_PI;
interface_name.copy( ifr.ifr_name, IFNAMSIZ);
- if (::ioctl(fd, TUNSETIFF, (void *) &ifr) < 0 )
+ if (::ioctl(f, TUNSETIFF, (void *) &ifr) < 0 )
throwErrno();
- body().fd(fd);
+ fd(f);
}
prefix_ std::auto_ptr<senf::SocketProtocol> senf::TapProtocol::clone()
prefix_ unsigned senf::TapProtocol::available()
const
{
- if (! body().readable())
+ if (! fh().readable())
return 0;
- ssize_t l = ::recv(body().fd(),0,0,MSG_PEEK | MSG_TRUNC);
+ ssize_t l = ::recv(fd(),0,0,MSG_PEEK | MSG_TRUNC);
if (l < 0)
//throwErrno();
return 1588;
+++ /dev/null
-// Copyright (C) 2007
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum NETwork research (NET)
-// David Wagner <david.wagner@fokus.fraunhofer.de>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the
-// Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-/** \file
- \brief UNAddress non-inline non-template implementation */
-
-#include "UNAddress.hh"
-//#include "UNAddress.ih"
-
-// Custom includes
-
-//#include "UNAddress.mpp"
-#define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
-
-prefix_ senf::UNAddress::UNAddress()
- //:path("")
-{
- path = "";
-}
-
-prefix_ senf::UNAddress::UNAddress(std::string p)
-{
- path = p;
-}
-
-
-prefix_ senf::UNAddress::UNAddress senf::UNAddress::fromString(std::string & s)
-{
- return senf::UNAddress::UNAddress(s);
-}
-
-
-prefix_ std::string senf::UNAddress::pathString()
- const
-{
- return path;
-}
-
-prefix_ senf::UNAddress::UNAddress senf::UNAddress::clone()
-{
- senf::UNAddress::UNAddress local_addr = senf::UNAddress::UNAddress(pathString());
- return local_addr;
-}
-
-prefix_ std::ostream & senf::operator<<(std::ostream & os, UNAddress const & addr)
-{
- os << addr.pathString();
- return os;
-}
-
-///////////////////////////////cc.e////////////////////////////////////////
-#undef prefix_
-//#include "UNAddress.mpp"
-
-\f
-// Local Variables:
-// mode: c++
-// fill-column: 100
-// comment-column: 40
-// c-file-style: "senf"
-// indent-tabs-mode: nil
-// ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
-// End:
+++ /dev/null
-// Copyright (C) 2007
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum NETwork research (NET)
-// David Wagner <david.wagner@fokus.fraunhofer.de>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the
-// Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-/** \file
- \brief UNAddress public header */
-
-#ifndef HH_UNAddress_
-#define HH_UNAddress_ 1
-
-// Custom includes
-#include <string>
-#include <boost/operators.hpp>
-#include "../../../Utils/safe_bool.hh"
-
-//#include "UNAddress.mpp"
-///////////////////////////////hh.p////////////////////////////////////////
-namespace senf {
- /** \brief Unix domain address
-
- UNAddress represents a simple unix domain address which is given by a path to a socket.
- It is modelled as a boost::filesystem::path.
-
- \ingroup addr_group
- */
- class UNAddress
- : public comparable_safe_bool<UNAddress>
- {
- public:
- UNAddress(); ///< Construct an empty address
- explicit UNAddress(std::string);///< Construct an address constant from given path
- static UNAddress fromString(std::string & s); ///< Convert string to address by interpreting the string as path
- UNAddress clone(); ///< Clone object
- std::string pathString() const; ///< Return the path of the address as string
-
- /** \brief Base-class for UNAddress exceptions */
- struct AddressException : public std::exception {};
-
- private:
- std::string path;
- };
-
-std::ostream & operator<<(std::ostream & os, UNAddress const & addr);
-}
-
-///////////////////////////////hh.e////////////////////////////////////////
-//#include "UNAddress.cci"
-//#include "UNAddress.ct"
-//#include "UNAddress.cti"
-#endif
-
-\f
-// Local Variables:
-// mode: c++
-// fill-column: 100
-// comment-column: 40
-// c-file-style: "senf"
-// indent-tabs-mode: nil
-// ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
-// End:
+++ /dev/null
-// Copyright (C) 2007
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum NETwork research (NET)
-// David Wagner <david.wagner@fokus.fraunhofer.de>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the
-// Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-/** \file
- \brief UNAddress.test unit tests */
-
-//#include "UNAddress.test.hh"
-//#include "UNAddress.test.ih"
-
-// Custom includes
-#include "UNAddress.hh"
-#include <boost/filesystem/path.hpp>
-#include "../../../Utils/auto_unit_test.hh"
-#include <boost/test/test_tools.hpp>
-
-#include <iostream>
-#define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
-
-BOOST_AUTO_UNIT_TEST(unAddress)
-{
-// TODO: muss wieder rein.
-// std::string testS = "/tmp/senfTestSocket";
-// boost::filesystem::path testp = boost::filesystem::path(testS);
-// senf::UNAddress addr1 = senf::UNAddress::fromString(testS);
-// senf::UNAddress addr2 = senf::UNAddress::fromPath(testp);
-// BOOST_CHECK( testS == addr1.pathString());
-// BOOST_CHECK( testS == addr2.pathString());
-}
-
-///////////////////////////////cc.e////////////////////////////////////////
-#undef prefix_
-
-\f
-// Local Variables:
-// mode: c++
-// fill-column: 100
-// comment-column: 40
-// c-file-style: "senf"
-// indent-tabs-mode: nil
-// ispell-local-dictionary: "american"
-// compile-command: "scons -u test"
-// End:
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ senf::UNSocketAddress::UNSocketAddress()
+{}
+
prefix_ senf::UNSocketAddress::UNSocketAddress(std::string p)
{
- sockAddr.sun_family = AF_UNIX;
- strcpy(sockAddr.sun_path, p.c_str());
+ clear();
+ ::strncpy(addr_.sun_path, p.c_str(), sizeof(addr_.sun_path));
+ addr_.sun_path[sizeof(addr_.sun_path)-1] = 0;
}
-prefix_ senf::UNSocketAddress fromString(std::string s) {
+prefix_ senf::UNSocketAddress fromString(std::string s)
+{
return senf::UNSocketAddress::UNSocketAddress(s);
}
+prefix_ bool senf::UNSocketAddress::operator==(UNSocketAddress const & other)
+ const
+{
+ return path() == other.path();
+}
prefix_ std::string senf::UNSocketAddress::path()
const
{
- return std::string(sockAddr.sun_path);
+ return std::string(addr_.sun_path);
}
-prefix_ sockaddr_un senf::UNSocketAddress::sockaddr()
+prefix_ bool senf::UNSocketAddress::boolean_test()
+ const
{
- struct sockaddr_un out;
- out.sun_family = sockAddr.sun_family;
- strncpy(out.sun_path, sockAddr.sun_path, sizeof( out.sun_path));
- return out;
+ return addr_.sun_path[0] != 0;
}
-prefix_ sockaddr * senf::UNSocketAddress::sockaddr_p()
+prefix_ void senf::UNSocketAddress::clear()
{
- return reinterpret_cast <struct sockaddr *> (&sockAddr);
+ ::memset(&addr_, 0, sizeof(addr_));
+ addr_.sun_family = AF_UNIX;
}
+prefix_ sockaddr * senf::UNSocketAddress::sockaddr_p()
+{
+ return reinterpret_cast <struct sockaddr *> (&addr_);
+}
prefix_ sockaddr const * senf::UNSocketAddress::sockaddr_p()
const
{
- return reinterpret_cast <struct sockaddr const *> (&sockAddr);
+ return reinterpret_cast <struct sockaddr const *> (&addr_);
}
prefix_ unsigned senf::UNSocketAddress::sockaddr_len()
const
{
- return sizeof(sockAddr);
+ return sizeof(addr_);
}
-prefix_ std::ostream & operator<<(std::ostream & os, senf::UNSocketAddress::UNSocketAddress const & addr){
+prefix_ std::ostream & operator<<(std::ostream & os,
+ senf::UNSocketAddress::UNSocketAddress const & addr)
+{
os << addr.path();
return os;
}
-
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "UNAddressing.mpp"
#include "../../../Socket/CommunicationPolicy.hh"
#include "../../../Socket/Protocols/GenericAddressingPolicy.hh"
#include "../../../Utils/safe_bool.hh"
-#include "UNAddress.hh"
//#include "UNAddressing.mpp"
///////////////////////////////hh.p////////////////////////////////////////
+
namespace senf {
+
/** \brief Unix domain socket address
UNSocketAddress wraps the standard sockaddr_un datatype. It provides simple accessor methods
\implementation This implementation is based on sockaddr_un.
\ingroup addr_group
+
+ \fixme Why both std::string constructor and from_string member ?
*/
class UNSocketAddress
: public comparable_safe_bool<UNSocketAddress>
{
public:
-
- //UNSocketAddress();
+ UNSocketAddress();
explicit UNSocketAddress(std::string p);
///< Construct an address constant from given path
- static UNSocketAddress from_string(std::string const s); ///< Create UNSocketAddress from string
- std::string path() const ; ///< Return path as string
- struct sockaddr_un sockaddr();
+ static UNSocketAddress from_string(std::string const s);
+ ///< Create UNSocketAddress from string
+
+ bool operator==(UNSocketAddress const & other) const;
+ ///< Compare UNSocketAddress for equality
+
+ std::string path() const ; ///< Return path as string
+
+ bool boolean_test() const; ///< \c true, if address is not empty
+
+ void clear(); ///< Clear address
+
struct sockaddr * sockaddr_p() ;
struct sockaddr const * sockaddr_p() const;
unsigned sockaddr_len() const;
+
private:
- struct sockaddr_un sockAddr;
+ struct sockaddr_un addr_;
};
- /** \brief Write path os
+ /** \brief Write path to os
\related UNSocketAddress
*/
using GenericAddressingPolicy<UNSocketAddress>::connect;
using GenericAddressingPolicy<UNSocketAddress>::bind;
};
+
+ ///@}
}
+
///////////////////////////////hh.e////////////////////////////////////////
//#include "UNAddressing.cci"
//#include "UNAddressing.ct"
int sock = ::socket(PF_UNIX,SOCK_DGRAM,0);
if (sock < 0)
throwErrno();
- body().fd(sock);
+ fd(sock);
}
prefix_ void senf::UNDatagramSocketProtocol::init_client(UNSocketAddress const & address) const
\par Address Type:
UNAddress
- UNDatagramSocketProtocol provides an datagram protocol socket based on the unix domain addressing.
-
- This class is utilized as the protocol class of the ProtocolClientSocketHandle
- via the Socket Handle typedefs above.
+ UNDatagramSocketProtocol provides an datagram protocol socket based on the unix domain
+ addressing.
+ This class is utilized as the protocol class of the ProtocolClientSocketHandle via the
+ Socket Handle typedefs above.
*/
class UNDatagramSocketProtocol
: public ConcreteSocketProtocol<UNDatagramSocket_Policy>,
typedef ProtocolClientSocketHandle<UNDatagramSocketProtocol> UNDatagramClientSocketHandle;
+ ///@}
+
}
///////////////////////////////hh.e////////////////////////////////////////
//#include "UNDatagramSocketHandle.cci"
const
{
int n;
- if (::ioctl(body().fd(),SIOCINQ,&n) < 0)
+ if (::ioctl(fd(),SIOCINQ,&n) < 0)
throwErrno();
return n;
}
prefix_ void senf::UNProtocol::connect(UNSocketAddress const & address)
const
{
- if(::connect(body().fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0)
+ if(::connect(fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0)
throwErrno();
}
prefix_ void senf::UNProtocol::bind(UNSocketAddress const & address)
const
{
- if(::bind(body().fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0)
+ if(::bind(fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0)
throwErrno();
}
prefix_ void senf::UNProtocol::check_and_unlink()
const
{
-// struct sockaddr_un test;
-// socklen_t len;
-// memset( (char*)&test, 0xff, sizeof( test));
-// int fd = inputSocket.fd() ;
-//// printf( "fd: %d\n", fd);
-//
-// int r = getsockname( fd, (struct sockaddr *)&test, &len);
-// if( r < 0){
-// perror( "bla:");
-// }
-// else{
-// printf( "name: %d %d %s\n", r, len , test.sun_path);
-// unsigned char *p = (unsigned char*) &test;for( r=0; r< len; r++) printf( "%2.2x ", (int)(p[r])); printf ("\n");
-// }
- struct sockaddr_un test;
- socklen_t len = sizeof( test);
- int r = ::getsockname( body().fd(), (struct sockaddr *)&test, &len);
- if( r == 0 && ::strlen(test.sun_path) > 0){
- ::unlink( test.sun_path);
+ typedef ClientSocketHandle<MakeSocketPolicy<UNAddressingPolicy>::policy> UNSocketHandle;
+ try {
+ UNSocketAddress una (static_socket_cast<UNSocketHandle>(fh()).local());
+ ::unlink(una.path().c_str());
+ }
+ catch (SystemException & e) {
}
}
+
+// // struct sockaddr_un test;
+// // socklen_t len;
+// // memset( (char*)&test, 0xff, sizeof( test));
+// // int fd = inputSocket.fd() ;
+// //// printf( "fd: %d\n", fd);
+// //
+// // int r = getsockname( fd, (struct sockaddr *)&test, &len);
+// // if( r < 0){
+// // perror( "bla:");
+// // }
+// // else{
+// // printf( "name: %d %d %s\n", r, len , test.sun_path);
+// // unsigned char *p = (unsigned char*) &test;for( r=0; r< len; r++) printf( "%2.2x ", (int)(p[r])); printf ("\n");
+// // }
+// struct sockaddr_un test;
+// socklen_t len = sizeof( test);
+// int r = ::getsockname(fd(), (struct sockaddr *)&test, &len);
+// if( r == 0 && ::strlen(test.sun_path) > 0){
+// ::unlink( test.sun_path);
+// }
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
+++ /dev/null
-#include "UNAddress.hh"
-#include "UNAddressing.hh"
-#include "UNDatagramSocketHandle.hh"
-#include "UNProtocol.hh"
prefix_ void senf::SocketBody::state(SocketStateMap & map, unsigned lod)
{
- map["file.handle"] = fd();
- map["file.refcount"] = refcount();
- map["socket.server"] = isServer();
- map["socket.protocol"] = prettyName(typeid(protocol()));
- map["socket.policy"] = prettyName(typeid(protocol().policy()));
+ map["file.handle"] << fd();
+ map["file.refcount"] << refcount();
+ map["socket.server"] << isServer();
+ map["socket.protocol"] << prettyName(typeid(protocol()));
+ map["socket.policy"] << prettyName(typeid(protocol().policy()));
protocol().state(map,lod);
}
}
///////////////////////////////////////////////////////////////////////////
-// senf::detail::ConvertibleString
+// senf::detail::StreamableString
-prefix_ senf::detail::ConvertibleString::ConvertibleString()
-{}
-
-prefix_ senf::detail::ConvertibleString::ConvertibleString(bool v)
- : std::string(v ? "true" : "false")
-{}
+prefix_ senf::detail::StreamableString & senf::detail::StreamableString::operator<<(bool v)
+{
+ return (*this) << std::string(v ? "true" : "false");
+}
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+// senf::detail::StreamableString
+
template <class T>
-prefix_ senf::detail::ConvertibleString &
-senf::detail::ConvertibleString::operator+=(ConvertibleString const & other)
+prefix_ senf::detail::StreamableString &
+senf::detail::StreamableString::operator<<(T const & other)
{
if (!empty())
- this->std::string::operator+=(", ");
- this->std::string::operator+=(other);
+ (*this) += ", ";
+ (*this) += boost::lexical_cast<std::string>(other);
return *this;
}
// automatically include the SocketPolicy template parameter in
// the type name and therefore show the \e static policy of the
// socket handle.
- map["handle"] = prettyName(typeid(*this));
+ map["handle"] << prettyName(typeid(*this));
body().state(map,lod);
}
return detail::dumpState(map);
}
-///////////////////////////////////////////////////////////////////////////
-// senf::detail::ConvertibleString
-
-template <class T>
-prefix_ senf::detail::ConvertibleString::ConvertibleString(T const & other)
- : std::string(boost::lexical_cast<std::string>(other))
-{}
-
///////////////////////////////cti.e///////////////////////////////////////
#undef prefix_
\param map string to string mapping to be filled with
state information
- \param lod level of detail requested. The interpretation
- of this value is protocol specific
+ \param lod level of detail requested. The
+ interpretation of this value is protocol specific
\implementation This member will be re-implemented in
every derived class. This is very important since
/**< Formats the complete state map value and returns it as
a single multi-line string.
- param lod level of detail requested. The interpretation
- of this value is protocol specific
-
+ \param lod level of detail requested. The
+ interpretation of this value is protocol specific
+
\implementation This member will be re-implemented in
every derived class. See the state()
documentation. */
\param isChecked has to be \c true
\todo Answer, why the heck I need the \c isChecked
- parameter ??
- */
+ parameter ?? */
SocketBody & body(); ///< Access socket body
/**< This member replaces the corresponding FileHandle
/** \brief String supporting automatic type conversion
- The ConvertibleString class is used to simplify creating a text representation of
- arbitrary values. ConvertibleString is an ordinary string with an additional constructor
+ The StreamableString class is used to simplify creating a text representation of
+ arbitrary values. StreamableString is an ordinary string with an additional constructor
which allows constructing the string from any arbitrary, streamable type.
\note It is generally not advisable to derive from the standard library container
additional functionality is added. It is absolutely safe to convert the derived class
back to the base type.
*/
- class ConvertibleString : public std::string
+ class StreamableString : public std::string
{
public:
- ConvertibleString();
- ConvertibleString(bool v); ///< Bool conversion constructor
- /**< The bool conversion is defined explicitly to use a
- specialized representation (the strings 'true' and
- 'false') */
- template <class T>
- ConvertibleString(T const & other);
- ///< Conversion constructor
- /**< This constructor will assign the string from any
- arbitrary type. It will use boost::lexical_cast to
- convert the argument to its string representation. */
+ using std::string::operator=;
template <class T>
- ConvertibleString & operator+= (ConvertibleString const & other);
- ///< Add additional values with separator
- /**< This operator facilitates the representation of
- multiple values in a single string. Each value is first
- converted to a string (using the type conversion
- machinery of C++ and the ConvertibleString conversion
- constructors). It is then appended to the current string
- with ', ' as a separator (if the current string is
- non-empty). */
+ StreamableString & operator<<(T const & other);
+ ///< Value assigment
+ /**< This operator will assign the string from any
+ arbitrary type. It will use boost::lexical_cast to
+ convert the argument to its string representation.
+
+ If the string is non-empty, an additional separating
+ comma is added to the string. */
+
+ StreamableString & operator<<(bool v); ///< Bool assignment
+ /**< The bool assignment is defined explicitly to use a
+ specialized representation (the strings 'true' and
+ 'false'). */
};
}
- typedef std::map< std::string, detail::ConvertibleString > SocketStateMap;
+ typedef std::map< std::string, detail::StreamableString > SocketStateMap;
namespace detail {
/** \brief Helper to convert SocketStateMap to multiline string representation
// check, wether each policy of other is (dynamically!) convertible
// to the corresponding (static) policy of this class. Throws
// std::bad_cast on failure
-# define SP_CheckPolicy(x1,x2,SomePolicy) (void) dynamic_cast<BOOST_PP_CAT(SomePolicy,_) const &>(other.BOOST_PP_CAT(the,SomePolicy)());
+
+# define SP_CheckPolicy(x1,x2,SomePolicy) \
+ (void) dynamic_cast<BOOST_PP_CAT(SomePolicy,_) const &>( \
+ other.BOOST_PP_CAT(the,SomePolicy)());
+
BOOST_PP_SEQ_FOR_EACH( SP_CheckPolicy, , SENF_SOCKET_POLICIES )
+
# undef SP_CheckPolicy
}
{
/** \brief Check dynamic policy compatibility
- This method will check the socket policy \a other against this policy. It will check,
- whether \a other is a base policy (or the same) of this policy. This check is done
- against the \e dynamic type of \a other using RTTI. It will throw \c std::bad_cast, if
- the policy is not compatible.
+ This check will validate, that a socket with \a other as it's policy is convertible to a
+ socket with the current SocketPolicy as it's policy. This is true, if for each policy
+ axis, the policy class of that axis as defined in the \a other policy is convertible to
+ the policy class of that same axis in the current SocketPolicy instance (as is defined
+ by the template arguments). This again is true, if the \a other policy class is derived
+ from (or is the same as) the policy class taken from the current SocketPolicy instance.
+
+ In other words, this call checks, that the current SocketPolicy (as defined via the
+ template arguments) is more generic than the \a other socket policy.
\param[in] other SocketPolicy to check
\throws std::bad_cast if \a other is not a compatible policy
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+// senf::SocketProtocol
+
+prefix_ senf::FileHandle senf::SocketProtocol::fh()
+ const
+{
+ return body().handle();
+}
+
+prefix_ int senf::SocketProtocol::fd()
+ const
+{
+ return body().fd();
+}
+
+prefix_ void senf::SocketProtocol::fd(int fd)
+ const
+{
+ BOOST_ASSERT(! body().valid());
+ body().fd(fd);
+}
+
prefix_ senf::SocketProtocol::SocketProtocol()
: body_(0)
{}
#define prefix_ inline
///////////////////////////////cti.p///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+// senf::ConcreteSocketProtocol<SocketPolicy>
+
template <class SocketPolicy>
prefix_ senf::ConcreteSocketProtocol<SocketPolicy>::~ConcreteSocketProtocol()
{}
///@}
///////////////////////////////////////////////////////////////////////////
- SocketBody & body() const; ///< Access the socket body
- /**< \todo we don't need body(), we should better provide a
- handle() member which will return a simple FIleHandle
- object (we cannot return some other derived class since
- we don't know the Protocol or Policy at this point) */
virtual SocketPolicyBase const & policy() const = 0;
///< Access the policy instance
\attention This member must be implemented in every \e
leaf protocol class to return a new instance of the
appropriate type. */
+
virtual unsigned available() const = 0;
///< Return number of bytes available for reading without
///< blocking
/**< This member will check in a (very, sigh) protocol
- dependent way, how many bytes are guaranteed to be
- readable from the socket without blocking even if the
- socket is blocking. If the socket does not support
- reading (viz. NotReadablePolicy is set), this member
- should always return \c 0.*/
+ dependent way, how many bytes may be read from a socket
+ in a single (non-blocking) read operation. If the
+ socket does not support reading (viz. NotReadablePolicy
+ is set), this member should always return \c 0.
+
+ Depending on the protocol, it may not be possible to
+ return a good value. In this case, an upper bound may
+ be returned (e.g.: When reading from a socket which
+ returns ethernet frames, returning 1500 from
+ available() is ok). However, this should only be done
+ as a last resort. Also beware, that this number should
+ not be to large since the socket layer will always need
+ to allocate that number of bytes for the data to be
+ read. */
virtual bool eof() const = 0; ///< Check for end-of-file condition
/**< This is another check which (like available()) is
/**< This override will automatically \c shutdown() the
socket whenever it is closed.
\throws senf::SystemException */
+
virtual void terminate() const; ///< Forcibly close socket
/**< This override will automatically \c shutdown() the
socket whenever it is called. Additionally it will
disable SO_LINGER to ensure, that v_terminate will not
block. Like the overriden method, this member will ignore
- failures and will never throw. It therefore safe to be
+ failures and will never throw. It is therefore safe to be
called from a destructor. */
virtual void state(SocketStateMap & map, unsigned lod) const;
assigning non-string values to the map:
\code
- map["socket.protocol.ip.address"] = peer();
- map["socket.protocol.tcp.backlog"] = backlog();
+ map["socket.protocol.ip.address"] << peer();
+ map["socket.protocol.tcp.backlog"] << backlog();
\endcode
This will work even if peer() returns an ip-address
object or backlog() returns an integer. The values are
automatically converted to their string representation.
- The operator "+=" also has been reimplemented to
- simplify adding multiple values to a single entry: It
- will automatically add a ", " separator if the string
- is non-empty. */
+ Additionally, if the slot the date is written to is not
+ empty, the <tt>\<\<</tt> operator will add add a comma
+ as separator. */
protected:
+ FileHandle fh() const; ///< Get a FileHandle for this instance
+ /**< This member will re turn a FileHandle instance for this
+ protocol instance. You may cast this FileHandle
+ instance to a ClientSocketHandle / ServerSocketHandle
+ as long as you know some of the socket policy using
+ static_socket_cast or dynamic_socket_cast */
+
+ int fd() const; ///< Get file descriptor
+ /**< Returns the file descriptor this protocol instance
+ references. This is the same as <tt>fh().fd()</tt> but
+ is implemented here since it is needed so often. */
+
+ void fd(int) const; ///< Initialize file descriptor
+ /**< Assigns the file descriptor to the file handle, this
+ protocol instance references. Only valid, if the file
+ handle has not yet been assigned any descriptor (To
+ change the file descriptor association later, use \c
+ ::dup2()). */
private:
// backpointer to owning SocketBody instance
+
+ SocketBody & body() const;
+
SocketBody * body_;
friend class SocketBody;
};