OXYGENHUB
◆ main openmsx / src / events / Socket.hh
2.5 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef SOCKET_HH
2
#define SOCKET_HH
3
4
#include <cassert>
5
#include <cstddef>
6
#include <cstdint>
7
#include <string>
8
9
#ifndef _WIN32
10
#include <fcntl.h>
11
#include <netinet/in.h>
12
#include <sys/socket.h>
13
#include <sys/types.h>
14
#include <sys/un.h>
15
#include <unistd.h>
16
#else
17
#include <winsock2.h>
18
#include <ws2tcpip.h>
19
#ifdef interface
20
// windows.h (via winsock2.h) defines an 'interface' macro; undo it so it
21
// cannot clobber other openMSX code that uses the word as an identifier.
22
#undef interface
23
#endif
24
#endif
25
26
namespace openmsx {
27
28
#ifndef _WIN32
29
inline constexpr int OPENMSX_INVALID_SOCKET = -1;
30
inline constexpr int SOCKET_ERROR = -1;
31
using SOCKET = int;
32
using socklen_t = int;
33
#else
34
// INVALID_SOCKET is #defined as  (SOCKET)(~0)
35
// but that gives a old-style-cast warning
36
static const SOCKET OPENMSX_INVALID_SOCKET = static_cast<SOCKET>(~0);
37
using in_addr_t =  UINT32;
38
#endif
39
40
[[nodiscard]] std::string sock_error();
41
void sock_close(SOCKET sd);
42
[[nodiscard]] ptrdiff_t sock_recv(SOCKET sd, char* buf, size_t count);
43
[[nodiscard]] ptrdiff_t sock_send(SOCKET sd, const char* buf, size_t count);
44
45
// Make socket 'sd' non-blocking.
46
void sock_setNonBlocking(SOCKET sd);
47
// Set an integer/boolean socket option (wraps the Windows 'const char*' cast).
48
void sock_setIntOption(SOCKET sd, int level, int optName, int value = 1);
49
// Get an integer socket option (e.g. SO_ERROR), 0 on failure.
50
[[nodiscard]] int sock_getIntOption(SOCKET sd, int level, int optName);
51
// Disable Nagle's algorithm (TCP_NODELAY): send small writes immediately.
52
void sock_setNoDelay(SOCKET sd);
53
// Non-blocking readiness poll (zero timeout): data ready or pending connection.
54
[[nodiscard]] bool sock_readable(SOCKET sd);
55
// Build an IPv4 sockaddr_in (network order); hostIp==0 -> INADDR_ANY.
56
[[nodiscard]] sockaddr_in sock_makeIPv4(uint32_t hostIp, uint16_t port);
57
// Best-effort local IPv4 (host order, 0 if unknown). Sends no packets.
58
[[nodiscard]] uint32_t sock_localIPv4();
59
60
////
61
62
// Activate the socket subsystem (required on Windows)
63
void sock_startup(); // should only be called via SockActivator
64
void sock_cleanup();
65
66
struct SocketActivator
67
{
68
	SocketActivator(const SocketActivator&) = delete;
69
	SocketActivator(SocketActivator&&) = delete;
70
	SocketActivator& operator=(const SocketActivator&) = delete;
71
	SocketActivator& operator=(SocketActivator&&) = delete;
72
73
	SocketActivator()
74
	{
75
		if (counter == 0) {
76
			sock_startup();
77
		}
78
		++counter;
79
	}
80
81
	~SocketActivator()
82
	{
83
		assert(counter > 0);
84
		--counter;
85
		if (counter == 0) {
86
			sock_cleanup();
87
		}
88
	}
89
90
private:
91
	static inline int counter = 0;
92
};
93
94
} // namespace openmsx
95
96
#endif