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"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
|
|
|
@ -5,9 +5,17 @@
|
|||
#define SOCKET_DESCRIPTOR_HXX
|
||||
|
||||
#include "Features.hxx"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "io/FileDescriptor.hxx"
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h> // for SOCKET, INVALID_SOCKET
|
||||
#endif
|
||||
|
||||
class SocketAddress;
|
||||
class StaticSocketAddress;
|
||||
|
@ -15,24 +23,44 @@ class IPv4Address;
|
|||
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:
|
||||
#ifdef _WIN32
|
||||
/* WinSock sockets are not file descriptors, they are a
|
||||
special type */
|
||||
SOCKET fd;
|
||||
#else // !_WIN32
|
||||
explicit constexpr SocketDescriptor(FileDescriptor _fd) noexcept
|
||||
:FileDescriptor(_fd) {}
|
||||
#endif // !_WIN32
|
||||
|
||||
public:
|
||||
SocketDescriptor() = default;
|
||||
|
||||
#ifdef _WIN32
|
||||
explicit constexpr SocketDescriptor(SOCKET _fd) noexcept
|
||||
:fd(_fd) {}
|
||||
#else // !_WIN32
|
||||
explicit constexpr SocketDescriptor(int _fd) noexcept
|
||||
:FileDescriptor(_fd) {}
|
||||
#endif // !_WIN32
|
||||
|
||||
constexpr bool operator==(SocketDescriptor other) const noexcept {
|
||||
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
|
||||
* possible on operating systems where socket descriptors are the
|
||||
|
@ -52,13 +80,11 @@ public:
|
|||
constexpr const FileDescriptor &ToFileDescriptor() const noexcept {
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
using FileDescriptor::IsDefined;
|
||||
#ifndef _WIN32
|
||||
using FileDescriptor::IsValid;
|
||||
using FileDescriptor::IsSocket;
|
||||
#endif
|
||||
#endif // !_WIN32
|
||||
|
||||
/**
|
||||
* Determine the socket type, i.e. SOCK_STREAM, SOCK_DGRAM or
|
||||
|
@ -73,25 +99,48 @@ public:
|
|||
[[gnu::pure]]
|
||||
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::Set;
|
||||
using FileDescriptor::Steal;
|
||||
using FileDescriptor::SetUndefined;
|
||||
|
||||
static constexpr SocketDescriptor Undefined() noexcept {
|
||||
return SocketDescriptor(FileDescriptor::Undefined());
|
||||
}
|
||||
|
||||
using FileDescriptor::EnableCloseOnExec;
|
||||
using FileDescriptor::DisableCloseOnExec;
|
||||
|
||||
#ifndef _WIN32
|
||||
using FileDescriptor::SetNonBlocking;
|
||||
using FileDescriptor::SetBlocking;
|
||||
using FileDescriptor::Duplicate;
|
||||
using FileDescriptor::CheckDuplicate;
|
||||
using FileDescriptor::Close;
|
||||
#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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,13 +20,20 @@ public:
|
|||
|
||||
explicit UniqueSocketDescriptor(SocketDescriptor _fd) noexcept
|
||||
:SocketDescriptor(_fd) {}
|
||||
#ifndef _WIN32
|
||||
explicit UniqueSocketDescriptor(FileDescriptor _fd) noexcept
|
||||
:SocketDescriptor(_fd) {}
|
||||
#endif // !_WIN32
|
||||
explicit UniqueSocketDescriptor(int _fd) noexcept
|
||||
:SocketDescriptor(_fd) {}
|
||||
|
||||
#ifdef _WIN32
|
||||
UniqueSocketDescriptor(UniqueSocketDescriptor &&other) noexcept
|
||||
:SocketDescriptor(std::exchange(other.fd, INVALID_SOCKET)) {}
|
||||
#else // !_WIN32
|
||||
UniqueSocketDescriptor(UniqueSocketDescriptor &&other) noexcept
|
||||
:SocketDescriptor(std::exchange(other.fd, -1)) {}
|
||||
#endif // !_WIN32
|
||||
|
||||
~UniqueSocketDescriptor() noexcept {
|
||||
if (IsDefined())
|
||||
|
|
Loading…
Reference in New Issue