28 #include <event2/util.h> 41 static struct WinSockInit {
44 WSAStartup(MAKEWORD(2, 2), &dat);
51 int translate_wsa_error(
int wsaErr) {
61 template <
class R,
class F,
class...
Args>
62 static R wrapSocketFunction(F
f, NetworkSocket
s,
Args... args) {
63 R ret =
f(s.data, args...);
65 errno = translate_wsa_error(WSAGetLastError());
72 return NetworkSocket(wrapSocketFunction<NetworkSocket::native_handle_type>(
73 ::
accept, s, addr, addrlen));
77 if (
kIsWindows && name->sa_family == AF_UNIX) {
82 if (name->sa_data[0] ==
'\0') {
87 return wrapSocketFunction<int>(
::bind,
s,
name, namelen);
97 if (r == -1 && WSAGetLastError() == WSAEWOULDBLOCK) {
118 auto ret = wrapSocketFunction<int>(
121 if (optname == TCP_NODELAY && *optlen == 1) {
125 *(
int*)optval = *(
uint8_t*)optval;
126 *optlen =
sizeof(int);
133 inp->s_addr = inet_addr(cp);
134 return inp->s_addr == INADDR_NONE ? 0 : 1;
138 return wrapSocketFunction<int>(
::listen,
s, backlog);
146 "PollDescriptor is misaligned");
149 "PollDescriptor is the wrong size");
152 "PollDescriptor.fd is at the wrong place");
154 sizeof(decltype(
PollDescriptor().fd)) ==
sizeof(decltype(pollfd().fd)),
155 "PollDescriptor.fd is the wrong size");
158 "PollDescriptor.events is at the wrong place");
161 sizeof(decltype(pollfd().events)),
162 "PollDescriptor.events is the wrong size");
165 "PollDescriptor.revents is at the wrong place");
168 sizeof(decltype(pollfd().revents)),
169 "PollDescriptor.revents is the wrong size");
172 pollfd* files =
reinterpret_cast<pollfd*
>(
reinterpret_cast<void*
>(fds));
174 return ::WSAPoll(files, (ULONG)nfds, timeout);
182 if ((flags & MSG_DONTWAIT) == MSG_DONTWAIT) {
183 flags &= ~MSG_DONTWAIT;
185 u_long pendingRead = 0;
186 if (ioctlsocket(s.
data, FIONREAD, &pendingRead)) {
187 errno = translate_wsa_error(WSAGetLastError());
193 FD_SET(s.
data, &readSet);
195 auto ret = select(1, &readSet,
nullptr,
nullptr, &
timeout);
201 return wrapSocketFunction<ssize_t>(
::recv,
s, (
char*)buf, (
int)len,
flags);
203 return wrapSocketFunction<ssize_t>(
::recv,
s, buf, len,
flags);
213 socklen_t* fromlen) {
215 if ((flags & MSG_TRUNC) == MSG_TRUNC) {
219 wBuf.buf = (CHAR*)buf;
220 wBuf.len = (ULONG)len;
222 wMsg.dwBufferCount = 1;
223 wMsg.lpBuffers = &wBuf;
225 if (fromlen !=
nullptr) {
226 wMsg.namelen = *fromlen;
232 LPFN_WSARECVMSG WSARecvMsg;
233 GUID WSARecgMsg_GUID = WSAID_WSARECVMSG;
237 SIO_GET_EXTENSION_FUNCTION_POINTER,
239 sizeof(WSARecgMsg_GUID),
247 int res = WSARecvMsg(h, &wMsg, &bytesReceived,
nullptr,
nullptr);
248 errno = translate_wsa_error(WSAGetLastError());
250 return bytesReceived;
252 if (fromlen !=
nullptr) {
253 *fromlen = wMsg.namelen;
255 if ((wMsg.dwFlags & MSG_TRUNC) == MSG_TRUNC) {
260 return wrapSocketFunction<ssize_t>(
263 return wrapSocketFunction<ssize_t>(
274 if (message->msg_name !=
nullptr || message->msg_namelen != 0) {
280 msg.Control.buf = (CHAR*)message->msg_control;
281 msg.Control.len = (ULONG)message->msg_controllen;
283 msg.dwBufferCount = (DWORD)message->msg_iovlen;
284 msg.lpBuffers =
new WSABUF[message->msg_iovlen];
286 delete[] msg.lpBuffers;
288 for (
size_t i = 0;
i <
message->msg_iovlen;
i++) {
289 msg.lpBuffers[
i].buf = (CHAR*)
message->msg_iov[
i].iov_base;
290 msg.lpBuffers[
i].len = (ULONG)
message->msg_iov[
i].iov_len;
296 LPFN_WSARECVMSG WSARecvMsg;
297 GUID WSARecgMsg_GUID = WSAID_WSARECVMSG;
301 SIO_GET_EXTENSION_FUNCTION_POINTER,
303 sizeof(WSARecgMsg_GUID),
311 int res = WSARecvMsg(
h, &msg, &bytesReceived,
nullptr,
nullptr);
312 errno = translate_wsa_error(WSAGetLastError());
313 return res == 0 ? (ssize_t)bytesReceived : -1;
321 return wrapSocketFunction<ssize_t>(
324 return wrapSocketFunction<ssize_t>(
::send,
s, buf, len,
flags);
331 SOCKET
h = socket.
data;
336 ssize_t bytesSent = 0;
337 for (
size_t i = 0;
i < message->msg_iovlen;
i++) {
339 if (message->msg_name !=
nullptr) {
342 (
const char*)message->msg_iov[
i].iov_base,
343 (
int)message->msg_iov[
i].iov_len,
345 (
const sockaddr*)message->msg_name,
346 (
int)message->msg_namelen);
350 (
const char*)message->msg_iov[
i].iov_base,
351 (
int)message->msg_iov[
i].iov_len,
354 if (r == -1 ||
size_t(r) != message->msg_iov[
i].iov_len) {
355 errno = translate_wsa_error(WSAGetLastError());
356 if (WSAGetLastError() == WSAEWOULDBLOCK && bytesSent > 0) {
377 return wrapSocketFunction<ssize_t>(
380 return wrapSocketFunction<ssize_t>(
::sendto,
s, buf, len,
flags,
to, tolen);
391 if (optname == SO_REUSEADDR) {
400 return wrapSocketFunction<int>(
403 return wrapSocketFunction<int>(
409 return wrapSocketFunction<int>(
::shutdown,
s, how);
418 if (domain != PF_UNIX || type != SOCK_STREAM || protocol != 0) {
422 auto r = evutil_socketpair(AF_INET, type, protocol, pair);
443 u_long nonBlockingEnabled = 1;
444 return ioctlsocket(s.
data, FIONBIO, &nonBlockingEnabled);
450 return fcntl(s.
data, F_SETFL, flags | O_NONBLOCK);
456 if (SetHandleInformation((HANDLE)s.
data, HANDLE_FLAG_INHERIT, 0)) {
461 return fcntl(s.
data, F_SETFD, FD_CLOEXEC);
ssize_t recvfrom(NetworkSocket s, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen)
int connect(NetworkSocket s, const sockaddr *name, socklen_t namelen)
ssize_t sendmsg(NetworkSocket socket, const msghdr *message, int flags)
int inet_aton(const char *cp, in_addr *inp)
int setsockopt(NetworkSocket s, int level, int optname, const void *optval, socklen_t optlen)
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
static int close(int fd) noexcept
—— Concurrent Priority Queue Implementation ——
int getsockname(NetworkSocket s, sockaddr *name, socklen_t *namelen)
int shutdown(NetworkSocket s, int how)
ssize_t sendto(NetworkSocket s, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen)
std::enable_if< detail::is_chrono_conversion< Tgt, Src >::value, Tgt >::type to(const Src &value)
int getsockopt(NetworkSocket s, int level, int optname, void *optval, socklen_t *optlen)
ssize_t send(NetworkSocket s, const void *buf, size_t len, int flags)
NetworkSocket socket(int af, int type, int protocol)
int listen(NetworkSocket s, int backlog)
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::operators::from_fn from
ssize_t recvmsg(NetworkSocket s, msghdr *message, int flags)
int set_socket_non_blocking(NetworkSocket s)
int poll(PollDescriptor fds[], nfds_t nfds, int timeout)
int bind(NetworkSocket s, const sockaddr *name, socklen_t namelen)
int getpeername(NetworkSocket s, sockaddr *name, socklen_t *namelen)
constexpr auto kIsWindows
int set_socket_close_on_exec(NetworkSocket s)
ssize_t recv(NetworkSocket s, void *buf, size_t len, int flags)
int close(NetworkSocket s)
ThreadPoolListHook * addr
int socketpair(int domain, int type, int protocol, NetworkSocket sv[2])
NetworkSocket accept(NetworkSocket s, sockaddr *addr, socklen_t *addrlen)