openMSX
Socket.cc
Go to the documentation of this file.
1#include "Socket.hh"
2#include "MSXException.hh" // FatalError
3#include "utf8_checked.hh"
4#include <cerrno>
5#include <cstring>
6
7namespace openmsx {
8
9std::string sock_error()
10{
11#ifdef _WIN32
12 wchar_t* s = nullptr;
13 FormatMessageW(
14 FORMAT_MESSAGE_ALLOCATE_BUFFER |
15 FORMAT_MESSAGE_FROM_SYSTEM |
16 FORMAT_MESSAGE_IGNORE_INSERTS,
17 nullptr, WSAGetLastError(), 0, reinterpret_cast<LPWSTR>(&s),
18 0, nullptr);
19 std::string result = utf8::utf16to8(s);
20 LocalFree(s);
21 return result;
22#else
23 return strerror(errno);
24#endif
25}
26
28{
29#ifdef _WIN32
30 // MAKEWORD is #define'd as ((WORD)(((BYTE)(a))|(((WORD)((BYTE)(b)))<<8)))
31 // but using that gives old-style-cast warnings
32 WORD w = 1 | (1 << 8); // MAKEWORD(1, 1)
33 WSAData wsaData;
34 if (WSAStartup(w, &wsaData) != 0) {
35 throw FatalError(sock_error());
36 }
37#else
38 // nothing needed for unix
39#endif
40}
41
43{
44#ifdef _WIN32
45 WSACleanup();
46#else
47 // nothing needed for unix
48#endif
49}
50
51// close a connection
53{
54#ifdef _WIN32
55 closesocket(sd);
56#else
57 close(sd);
58#endif
59}
60
61
62ptrdiff_t sock_recv(SOCKET sd, char* buf, size_t count)
63{
64 ptrdiff_t num = recv(sd, buf, count, 0);
65 if (num > 0) return num; // normal case
66 if (num == 0) return -1; // socket was closed by client
67#ifdef _WIN32
68 // Something bad happened on the socket. It could just be a
69 // "would block" notification, or it could be something more
70 // serious. WSAEWOULDBLOCK can happen after select() says a
71 // socket is readable under Win9x, it doesn't happen on
72 // WinNT/2000 or on Unix.
73 int err;
74 int errLen = sizeof(err);
75 getsockopt(sd, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&err), &errLen);
76 if (err == WSAEWOULDBLOCK) return 0;
77 return -1;
78#else
79 if (errno == EWOULDBLOCK) return 0;
80 return -1;
81#endif
82}
83
84
85ptrdiff_t sock_send(SOCKET sd, const char* buf, size_t count)
86{
87 ptrdiff_t num = send(sd, buf, count, 0);
88 if (num >= 0) return num; // normal case
89#ifdef _WIN32
90 int err;
91 int errLen = sizeof(err);
92 getsockopt(sd, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&err), &errLen);
93 if (err == WSAEWOULDBLOCK) return 0;
94 return -1;
95#else
96 if (errno == EWOULDBLOCK) return 0;
97 return -1;
98#endif
99}
100
101} // namespace openmsx
This file implemented 3 utility functions:
Definition Autofire.cc:9
ptrdiff_t sock_send(SOCKET sd, const char *buf, size_t count)
Definition Socket.cc:85
void sock_close(SOCKET sd)
Definition Socket.cc:52
void sock_startup()
Definition Socket.cc:27
std::string sock_error()
Definition Socket.cc:9
int SOCKET
Definition Socket.hh:24
void sock_cleanup()
Definition Socket.cc:42
ptrdiff_t sock_recv(SOCKET sd, char *buf, size_t count)
Definition Socket.cc:62
octet_iterator utf16to8(u16bit_iterator start, u16bit_iterator end, octet_iterator result)