1// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6#if defined(HOST_OS_WINDOWS)
7
8#include "bin/socket_base.h"
9#include "bin/sync_socket.h"
10
11namespace dart {
12namespace bin {
13
14bool SynchronousSocket::Initialize() {
15 return SocketBase::Initialize();
16}
17
18static intptr_t Create(const RawAddr& addr) {
19 const intptr_t type = SOCK_STREAM;
20 SOCKET s = WSASocket(addr.ss.ss_family, type, 0, NULL, 0, 0);
21 return (s == INVALID_SOCKET) ? -1 : s;
22}
23
24static intptr_t Connect(intptr_t fd, const RawAddr& addr) {
25 SOCKET socket = static_cast<SOCKET>(fd);
26 intptr_t result =
27 connect(socket, &addr.addr, SocketAddress::GetAddrLength(addr));
28 return (result == SOCKET_ERROR) ? -1 : socket;
29}
30
31intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) {
32 intptr_t fd = Create(addr);
33 return (fd < 0) ? fd : Connect(fd, addr);
34}
35
36intptr_t SynchronousSocket::Available(intptr_t fd) {
37 SOCKET socket = static_cast<SOCKET>(fd);
38 DWORD available;
39 intptr_t result = ioctlsocket(socket, FIONREAD, &available);
40 return (result == SOCKET_ERROR) ? -1 : static_cast<intptr_t>(available);
41}
42
43intptr_t SynchronousSocket::GetPort(intptr_t fd) {
44 SOCKET socket = static_cast<SOCKET>(fd);
45 RawAddr raw;
46 socklen_t size = sizeof(raw);
47 if (getsockname(socket, &raw.addr, &size) == SOCKET_ERROR) {
48 return 0;
49 }
50 return SocketAddress::GetAddrPort(raw);
51}
52
53SocketAddress* SynchronousSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
54 SOCKET socket = static_cast<SOCKET>(fd);
55 RawAddr raw;
56 socklen_t size = sizeof(raw);
57 if (getpeername(socket, &raw.addr, &size)) {
58 return NULL;
59 }
60 *port = SocketAddress::GetAddrPort(raw);
61 // Clear the port before calling WSAAddressToString as WSAAddressToString
62 // includes the port in the formatted string.
63 SocketAddress::SetAddrPort(&raw, 0);
64 return new SocketAddress(&raw.addr);
65}
66
67intptr_t SynchronousSocket::Read(intptr_t fd,
68 void* buffer,
69 intptr_t num_bytes) {
70 SOCKET socket = static_cast<SOCKET>(fd);
71 return recv(socket, reinterpret_cast<char*>(buffer), num_bytes, 0);
72}
73
74intptr_t SynchronousSocket::Write(intptr_t fd,
75 const void* buffer,
76 intptr_t num_bytes) {
77 SOCKET socket = static_cast<SOCKET>(fd);
78 return send(socket, reinterpret_cast<const char*>(buffer), num_bytes, 0);
79}
80
81void SynchronousSocket::ShutdownRead(intptr_t fd) {
82 SOCKET socket = static_cast<SOCKET>(fd);
83 shutdown(socket, SD_RECEIVE);
84}
85
86void SynchronousSocket::ShutdownWrite(intptr_t fd) {
87 SOCKET socket = static_cast<SOCKET>(fd);
88 shutdown(socket, SD_SEND);
89}
90
91void SynchronousSocket::Close(intptr_t fd) {
92 SOCKET socket = static_cast<SOCKET>(fd);
93 closesocket(socket);
94}
95
96} // namespace bin
97} // namespace dart
98
99#endif // defined(HOST_OS_WINDOWS)
100