net/SocketDescriptor: decouple from FileDescriptor on Windows
On Windows, a socket is not a file descriptor; it is a different beast (and anyway, Windows doesn't have file descriptors).
This commit is contained in:
parent
7a5f485cf8
commit
53ec02d5e9
|
@ -8,7 +8,6 @@
|
||||||
#include "IPv6Address.hxx"
|
#include "IPv6Address.hxx"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
|
@ -5,9 +5,17 @@
|
||||||
#define SOCKET_DESCRIPTOR_HXX
|
#define SOCKET_DESCRIPTOR_HXX
|
||||||
|
|
||||||
#include "Features.hxx"
|
#include "Features.hxx"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
#include "io/FileDescriptor.hxx"
|
#include "io/FileDescriptor.hxx"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <winsock2.h> // for SOCKET, INVALID_SOCKET
|
||||||
|
#endif
|
||||||
|
|
||||||
class SocketAddress;
|
class SocketAddress;
|
||||||
class StaticSocketAddress;
|
class StaticSocketAddress;
|
||||||
|
@ -15,24 +23,44 @@ class IPv4Address;
|
||||||
class IPv6Address;
|
class IPv6Address;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An OO wrapper for a UNIX socket descriptor.
|
* An OO wrapper for a Berkeley or WinSock socket descriptor.
|
||||||
*/
|
*/
|
||||||
class SocketDescriptor : protected FileDescriptor {
|
class SocketDescriptor
|
||||||
|
#ifndef _WIN32
|
||||||
|
/* Berkeley sockets are represented as file descriptors */
|
||||||
|
: protected FileDescriptor
|
||||||
|
#endif
|
||||||
|
{
|
||||||
protected:
|
protected:
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* WinSock sockets are not file descriptors, they are a
|
||||||
|
special type */
|
||||||
|
SOCKET fd;
|
||||||
|
#else // !_WIN32
|
||||||
explicit constexpr SocketDescriptor(FileDescriptor _fd) noexcept
|
explicit constexpr SocketDescriptor(FileDescriptor _fd) noexcept
|
||||||
:FileDescriptor(_fd) {}
|
:FileDescriptor(_fd) {}
|
||||||
|
#endif // !_WIN32
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SocketDescriptor() = default;
|
SocketDescriptor() = default;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
explicit constexpr SocketDescriptor(SOCKET _fd) noexcept
|
||||||
|
:fd(_fd) {}
|
||||||
|
#else // !_WIN32
|
||||||
explicit constexpr SocketDescriptor(int _fd) noexcept
|
explicit constexpr SocketDescriptor(int _fd) noexcept
|
||||||
:FileDescriptor(_fd) {}
|
:FileDescriptor(_fd) {}
|
||||||
|
#endif // !_WIN32
|
||||||
|
|
||||||
constexpr bool operator==(SocketDescriptor other) const noexcept {
|
constexpr bool operator==(SocketDescriptor other) const noexcept {
|
||||||
return fd == other.fd;
|
return fd == other.fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifdef _WIN32
|
||||||
|
constexpr bool IsDefined() const noexcept {
|
||||||
|
return fd != INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
#else // !_WIN32
|
||||||
/**
|
/**
|
||||||
* Convert a #FileDescriptor to a #SocketDescriptor. This is only
|
* Convert a #FileDescriptor to a #SocketDescriptor. This is only
|
||||||
* possible on operating systems where socket descriptors are the
|
* possible on operating systems where socket descriptors are the
|
||||||
|
@ -52,13 +80,11 @@ public:
|
||||||
constexpr const FileDescriptor &ToFileDescriptor() const noexcept {
|
constexpr const FileDescriptor &ToFileDescriptor() const noexcept {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
using FileDescriptor::IsDefined;
|
using FileDescriptor::IsDefined;
|
||||||
#ifndef _WIN32
|
|
||||||
using FileDescriptor::IsValid;
|
using FileDescriptor::IsValid;
|
||||||
using FileDescriptor::IsSocket;
|
using FileDescriptor::IsSocket;
|
||||||
#endif
|
#endif // !_WIN32
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the socket type, i.e. SOCK_STREAM, SOCK_DGRAM or
|
* Determine the socket type, i.e. SOCK_STREAM, SOCK_DGRAM or
|
||||||
|
@ -73,25 +99,48 @@ public:
|
||||||
[[gnu::pure]]
|
[[gnu::pure]]
|
||||||
bool IsStream() const noexcept;
|
bool IsStream() const noexcept;
|
||||||
|
|
||||||
|
static constexpr SocketDescriptor Undefined() noexcept {
|
||||||
|
#ifdef _WIN32
|
||||||
|
return SocketDescriptor{INVALID_SOCKET};
|
||||||
|
#else // !_WIN32
|
||||||
|
return SocketDescriptor(FileDescriptor::Undefined());
|
||||||
|
#endif // !_WIN32
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
using FileDescriptor::Get;
|
using FileDescriptor::Get;
|
||||||
using FileDescriptor::Set;
|
using FileDescriptor::Set;
|
||||||
using FileDescriptor::Steal;
|
using FileDescriptor::Steal;
|
||||||
using FileDescriptor::SetUndefined;
|
using FileDescriptor::SetUndefined;
|
||||||
|
|
||||||
static constexpr SocketDescriptor Undefined() noexcept {
|
|
||||||
return SocketDescriptor(FileDescriptor::Undefined());
|
|
||||||
}
|
|
||||||
|
|
||||||
using FileDescriptor::EnableCloseOnExec;
|
using FileDescriptor::EnableCloseOnExec;
|
||||||
using FileDescriptor::DisableCloseOnExec;
|
using FileDescriptor::DisableCloseOnExec;
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
using FileDescriptor::SetNonBlocking;
|
using FileDescriptor::SetNonBlocking;
|
||||||
using FileDescriptor::SetBlocking;
|
using FileDescriptor::SetBlocking;
|
||||||
using FileDescriptor::Duplicate;
|
using FileDescriptor::Duplicate;
|
||||||
using FileDescriptor::CheckDuplicate;
|
using FileDescriptor::CheckDuplicate;
|
||||||
using FileDescriptor::Close;
|
using FileDescriptor::Close;
|
||||||
#else
|
#else
|
||||||
|
constexpr SOCKET Get() const noexcept {
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void Set(SOCKET _fd) noexcept {
|
||||||
|
fd = _fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void SetUndefined() noexcept {
|
||||||
|
fd = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SOCKET Steal() noexcept {
|
||||||
|
return std::exchange(fd, INVALID_SOCKET);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnableCloseOnExec() const noexcept {}
|
||||||
|
void DisableCloseOnExec() const noexcept {}
|
||||||
|
|
||||||
bool SetNonBlocking() const noexcept;
|
bool SetNonBlocking() const noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,13 +20,20 @@ public:
|
||||||
|
|
||||||
explicit UniqueSocketDescriptor(SocketDescriptor _fd) noexcept
|
explicit UniqueSocketDescriptor(SocketDescriptor _fd) noexcept
|
||||||
:SocketDescriptor(_fd) {}
|
:SocketDescriptor(_fd) {}
|
||||||
|
#ifndef _WIN32
|
||||||
explicit UniqueSocketDescriptor(FileDescriptor _fd) noexcept
|
explicit UniqueSocketDescriptor(FileDescriptor _fd) noexcept
|
||||||
:SocketDescriptor(_fd) {}
|
:SocketDescriptor(_fd) {}
|
||||||
|
#endif // !_WIN32
|
||||||
explicit UniqueSocketDescriptor(int _fd) noexcept
|
explicit UniqueSocketDescriptor(int _fd) noexcept
|
||||||
:SocketDescriptor(_fd) {}
|
:SocketDescriptor(_fd) {}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
UniqueSocketDescriptor(UniqueSocketDescriptor &&other) noexcept
|
||||||
|
:SocketDescriptor(std::exchange(other.fd, INVALID_SOCKET)) {}
|
||||||
|
#else // !_WIN32
|
||||||
UniqueSocketDescriptor(UniqueSocketDescriptor &&other) noexcept
|
UniqueSocketDescriptor(UniqueSocketDescriptor &&other) noexcept
|
||||||
:SocketDescriptor(std::exchange(other.fd, -1)) {}
|
:SocketDescriptor(std::exchange(other.fd, -1)) {}
|
||||||
|
#endif // !_WIN32
|
||||||
|
|
||||||
~UniqueSocketDescriptor() noexcept {
|
~UniqueSocketDescriptor() noexcept {
|
||||||
if (IsDefined())
|
if (IsDefined())
|
||||||
|
|
Loading…
Reference in New Issue