#include <cerrno>
#include <msp/core/systemerror.h>
+#include <msp/io/handle_private.h>
#include <msp/strings/format.h>
#include "datagramsocket.h"
+#include "socket_private.h"
namespace Msp {
namespace Net {
Socket(f, SOCK_DGRAM, p)
{
#ifdef WIN32
- WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
+ WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
#endif
set_events(IO::P_INPUT);
}
sockaddr_storage sa;
socklen_t size = addr.fill_sockaddr(sa);
- int err = ::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
+ int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa), size);
if(err==-1)
{
#ifdef WIN32
delete local_addr;
size = sizeof(sockaddr_storage);
- getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
+ getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
local_addr = SockAddr::create(sa);
connected = true;
sockaddr_storage addr;
socklen_t addr_len = addr_.fill_sockaddr(addr);
- int ret = ::sendto(handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), addr_len);
+ int ret = ::sendto(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), addr_len);
if(ret<0)
{
if(errno==EAGAIN)
sockaddr_storage addr;
socklen_t addr_len = sizeof(sockaddr_storage);
- int ret = ::recvfrom(handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), &addr_len);
+ int ret = ::recvfrom(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), &addr_len);
if(ret<0)
{
if(errno==EAGAIN)
#include <msp/time/rawtime_private.h>
#include <msp/time/units.h>
#include "socket.h"
+#include "socket_private.h"
namespace {
namespace Msp {
namespace Net {
-Socket::Socket(SocketHandle h, const SockAddr &paddr):
- handle(h),
+Socket::Socket(const Private &p, const SockAddr &paddr):
+ priv(new Private),
connected(true),
local_addr(0),
peer_addr(paddr.copy())
{
+ priv->handle = p.handle;
+
sockaddr_storage sa;
socklen_t size = sizeof(sockaddr_storage);
- getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
+ getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
local_addr = SockAddr::create(sa);
#ifdef WIN32
- event = CreateEvent(0, false, false, 0);
+ *priv->event = CreateEvent(0, false, false, 0);
#else
- *event = handle;
+ *priv->event = priv->handle;
#endif
}
Socket::Socket(Family af, int type, int proto):
+ priv(new Private),
connected(false),
local_addr(0),
peer_addr(0)
{
- handle = socket(af, type, proto);
+ priv->handle = socket(af, type, proto);
#ifdef WIN32
- event = CreateEvent(0, false, false, 0);
+ *priv->event = CreateEvent(0, false, false, 0);
#else
- *event = handle;
+ *priv->event = priv->handle;
#endif
}
{
signal_flush_required.emit();
#ifdef WIN32
- closesocket(handle);
- CloseHandle(event);
+ closesocket(priv->handle);
+ CloseHandle(*priv->event);
#else
- ::close(handle);
+ ::close(priv->handle);
#endif
delete local_addr;
delete peer_addr;
+ delete priv;
}
void Socket::set_block(bool b)
#ifdef WIN32
u_long flag = !b;
- ioctlsocket(handle, FIONBIO, &flag);
+ ioctlsocket(priv->handle, FIONBIO, &flag);
#else
- int flags = fcntl(handle, F_GETFL);
- fcntl(handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK));
+ int flags = fcntl(priv->handle, F_GETFL);
+ fcntl(priv->handle, F_SETFL, (flags&O_NONBLOCK)|(b?0:O_NONBLOCK));
#endif
}
const IO::Handle &Socket::get_event_handle()
{
- return event;
+ return priv->event;
}
sockaddr_storage sa;
unsigned size = addr.fill_sockaddr(sa);
- int err = ::bind(handle, reinterpret_cast<sockaddr *>(&sa), size);
+ int err = ::bind(priv->handle, reinterpret_cast<sockaddr *>(&sa), size);
if(err==-1)
throw system_error("bind");
int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen)
{
#ifdef WIN32
- return setsockopt(handle, level, optname, reinterpret_cast<const char *>(optval), optlen);
+ return setsockopt(priv->handle, level, optname, reinterpret_cast<const char *>(optval), optlen);
#else
- return setsockopt(handle, level, optname, optval, optlen);
+ return setsockopt(priv->handle, level, optname, optval, optlen);
#endif
}
int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) const
{
#ifdef WIN32
- return getsockopt(handle, level, optname, reinterpret_cast<char *>(optval), optlen);
+ return getsockopt(priv->handle, level, optname, reinterpret_cast<char *>(optval), optlen);
#else
- return getsockopt(handle, level, optname, optval, optlen);
+ return getsockopt(priv->handle, level, optname, optval, optlen);
#endif
}
if(size==0)
return 0;
- int ret = ::send(handle, buf, size, 0);
+ int ret = ::send(priv->handle, buf, size, 0);
if(ret<0)
{
if(errno==EAGAIN)
if(size==0)
return 0;
- int ret = ::recv(handle, buf, size, 0);
+ int ret = ::recv(priv->handle, buf, size, 0);
if(ret<0)
{
if(errno==EAGAIN)
#include <msp/io/handle.h>
#include "constants.h"
#include "sockaddr.h"
-#include "types.h"
namespace Msp {
namespace Net {
+#ifdef WIN32
+typedef int socklen_t;
+#endif
+
+
class bad_socket_state: public std::logic_error
{
public:
class Socket: public IO::EventObject
{
protected:
- SocketHandle handle;
- IO::Handle event;
+ struct Private;
+
+ Private *priv;
bool connected;
SockAddr *local_addr;
SockAddr *peer_addr;
- Socket(SocketHandle, const SockAddr &);
+ Socket(const Private &, const SockAddr &);
Socket(Family, int, int);
public:
~Socket();
--- /dev/null
+#ifndef MSP_NET_SOCKET_PRIVATE_H_
+#define MSP_NET_SOCKET_PRIVATE_H_
+
+#include <msp/io/handle.h>
+#include "socket.h"
+
+namespace Msp {
+namespace Net {
+
+struct Socket::Private
+{
+#ifdef WIN32
+ SOCKET handle;
+#else
+ int handle;
+#endif
+
+ /* On POSIX platforms this is the same as the handle. This might seem
+ strange but it allows the same syntax on both POSIX and Windows. */
+ IO::Handle event;
+};
+
+} // namespace Net
+} // namespace Msp
+
+#endif
#include <cerrno>
#include <msp/core/refptr.h>
#include <msp/core/systemerror.h>
+#include <msp/io/handle_private.h>
#include <msp/strings/format.h>
+#include "socket_private.h"
#include "streamlistensocket.h"
#include "streamsocket.h"
{
bind(addr);
- int err = ::listen(handle, backlog);
+ int err = ::listen(priv->handle, backlog);
if(err==-1)
throw system_error("listen");
#ifdef WIN32
- WSAEventSelect(handle, event, FD_ACCEPT);
+ WSAEventSelect(priv->handle, *priv->event, FD_ACCEPT);
#endif
set_events(IO::P_INPUT);
sockaddr_storage sa;
socklen_t size = sizeof(sockaddr_storage);
- SocketHandle new_h = ::accept(handle, reinterpret_cast<sockaddr *>(&sa), &size);
+ Private new_p;
+ new_p.handle = ::accept(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
RefPtr<SockAddr> paddr = SockAddr::create(sa);
- return new StreamSocket(new_h, *paddr);
+ return new StreamSocket(new_p, *paddr);
}
} // namespace Net
#endif
#include <cerrno>
#include <msp/core/systemerror.h>
+#include <msp/io/handle_private.h>
#include <msp/io/poll.h>
#include <msp/strings/format.h>
+#include "socket_private.h"
#include "streamsocket.h"
namespace Msp {
namespace Net {
-StreamSocket::StreamSocket(SocketHandle h, const SockAddr &paddr):
- Socket(h, paddr),
+StreamSocket::StreamSocket(const Private &p, const SockAddr &paddr):
+ Socket(p, paddr),
connecting(false)
{
#ifdef WIN32
- WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
+ WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
#endif
set_events(IO::P_INPUT);
}
}
#ifdef WIN32
- WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
+ WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
#endif
set_events(IO::P_INPUT);
socklen_t size = addr.fill_sockaddr(sa);
#ifdef WIN32
- int err = WSAConnect(handle, reinterpret_cast<sockaddr *>(&sa), size, 0, 0, 0, 0);
+ int err = WSAConnect(priv->handle, reinterpret_cast<sockaddr *>(&sa), size, 0, 0, 0, 0);
if(err==SOCKET_ERROR)
{
int err_code = WSAGetLastError();
if(err_code==WSAEWOULDBLOCK)
{
connecting = true;
- WSAEventSelect(handle, event, FD_CONNECT);
+ WSAEventSelect(priv->handle, *priv->event, FD_CONNECT);
set_events(IO::P_OUTPUT);
}
else
throw system_error("connect", err_code);
}
#else
- int err = ::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
+ int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa), size);
if(err==-1)
{
if(errno==EINPROGRESS)
delete local_addr;
size = sizeof(sockaddr_storage);
- getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
+ getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
local_addr = SockAddr::create(sa);
if(err==0)
}
#ifdef WIN32
- WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
+ WSAEventSelect(priv->handle, *priv->event, FD_READ|FD_CLOSE);
#endif
set_events((err==0) ? IO::P_INPUT : IO::P_NONE);
}
private:
/// Used by StreamListenSocket to construct a new socket from accept.
- StreamSocket(SocketHandle, const SockAddr &);
+ StreamSocket(const Private &, const SockAddr &);
public:
StreamSocket(Family, int = 0);
+++ /dev/null
-#ifndef MSP_NET_TYPES_H_
-#define MSP_NET_TYPES_H_
-
-namespace Msp {
-namespace Net {
-
-#ifdef WIN32
-typedef SOCKET SocketHandle;
-typedef int socklen_t;
-
-#define MSP_NET_INVALID_SOCKET_HANDLE static_cast<SOCKET>(-1)
-#else
-typedef int SocketHandle;
-
-#define MSP_NET_INVALID_SOCKET_HANDLE -1
-#endif
-
-} // namespace Net
-} // namespace Msp
-
-#endif