OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include <winsock2.h> | 5 #include <winsock2.h> |
6 #include <ws2tcpip.h> | 6 #include <ws2tcpip.h> |
7 #include <mswsock.h> | 7 #include <mswsock.h> |
8 | 8 |
9 #include "bin/builtin.h" | 9 #include "bin/builtin.h" |
10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 fprintf(stderr, "Error getsockname: %s\n", strerror(errno)); | 50 fprintf(stderr, "Error getsockname: %s\n", strerror(errno)); |
51 return 0; | 51 return 0; |
52 } | 52 } |
53 return ntohs(socket_address.sin_port); | 53 return ntohs(socket_address.sin_port); |
54 } | 54 } |
55 | 55 |
56 | 56 |
57 intptr_t Socket::CreateConnect(const char* host, const intptr_t port) { | 57 intptr_t Socket::CreateConnect(const char* host, const intptr_t port) { |
58 SOCKET s = socket(AF_INET, SOCK_STREAM, 0); | 58 SOCKET s = socket(AF_INET, SOCK_STREAM, 0); |
59 if (s == INVALID_SOCKET) { | 59 if (s == INVALID_SOCKET) { |
60 fprintf(stderr, "Error CreateConnect: %d\n", WSAGetLastError()); | |
61 return -1; | 60 return -1; |
62 } | 61 } |
63 | 62 |
64 linger l; | 63 linger l; |
65 l.l_onoff = 1; | 64 l.l_onoff = 1; |
66 l.l_linger = 10; | 65 l.l_linger = 10; |
67 int status = setsockopt(s, | 66 int status = setsockopt(s, |
68 SOL_SOCKET, | 67 SOL_SOCKET, |
69 SO_LINGER, | 68 SO_LINGER, |
70 reinterpret_cast<char*>(&l), | 69 reinterpret_cast<char*>(&l), |
71 sizeof(l)); | 70 sizeof(l)); |
72 if (status != NO_ERROR) { | 71 if (status != NO_ERROR) { |
73 FATAL("Failed setting SO_LINGER on socket"); | 72 FATAL("Failed setting SO_LINGER on socket"); |
74 } | 73 } |
75 | 74 |
76 // Perform a name lookup for an IPv4 address. | 75 // Perform a name lookup for an IPv4 address. |
77 struct addrinfo hints; | 76 struct addrinfo hints; |
78 memset(&hints, 0, sizeof(hints)); | 77 memset(&hints, 0, sizeof(hints)); |
79 hints.ai_family = AF_INET; | 78 hints.ai_family = AF_INET; |
80 hints.ai_socktype = SOCK_STREAM; | 79 hints.ai_socktype = SOCK_STREAM; |
81 hints.ai_protocol = IPPROTO_TCP; | 80 hints.ai_protocol = IPPROTO_TCP; |
82 struct addrinfo* result = NULL; | 81 struct addrinfo* result = NULL; |
83 status = getaddrinfo(host, 0, &hints, &result); | 82 status = getaddrinfo(host, 0, &hints, &result); |
84 if (status != NO_ERROR) { | 83 if (status != NO_ERROR) { |
85 fprintf(stderr, "getaddrinfo failed with error: %d\n", status); | |
86 return -1; | 84 return -1; |
87 } | 85 } |
88 | 86 |
89 // Copy IPv4 address and set the port. | 87 // Copy IPv4 address and set the port. |
90 struct sockaddr_in server_address; | 88 struct sockaddr_in server_address; |
91 memcpy(&server_address, | 89 memcpy(&server_address, |
92 reinterpret_cast<sockaddr_in *>(result->ai_addr), | 90 reinterpret_cast<sockaddr_in *>(result->ai_addr), |
93 sizeof(server_address)); | 91 sizeof(server_address)); |
94 server_address.sin_port = htons(port); | 92 server_address.sin_port = htons(port); |
95 freeaddrinfo(result); // Free data allocated by getaddrinfo. | 93 freeaddrinfo(result); // Free data allocated by getaddrinfo. |
96 status = connect( | 94 status = connect( |
97 s, | 95 s, |
98 reinterpret_cast<struct sockaddr*>(&server_address), | 96 reinterpret_cast<struct sockaddr*>(&server_address), |
99 sizeof(server_address)); | 97 sizeof(server_address)); |
100 if (status == SOCKET_ERROR) { | 98 if (status == SOCKET_ERROR) { |
101 fprintf(stderr, "Error CreateConnect: %d\n", WSAGetLastError()); | 99 DWORD rc = WSAGetLastError(); |
102 closesocket(s); | 100 closesocket(s); |
| 101 SetLastError(rc); |
103 return -1; | 102 return -1; |
104 } | 103 } |
105 | 104 |
106 ClientSocket* client_socket = new ClientSocket(s); | 105 ClientSocket* client_socket = new ClientSocket(s); |
107 return reinterpret_cast<intptr_t>(client_socket); | 106 return reinterpret_cast<intptr_t>(client_socket); |
108 } | 107 } |
109 | 108 |
110 | 109 |
| 110 void Socket::GetError(intptr_t fd, OSError* os_error) { |
| 111 Handle* handle = reinterpret_cast<Handle*>(fd); |
| 112 os_error->SetCodeAndMessage(OSError::kSystem, handle->last_error()); |
| 113 } |
| 114 |
| 115 |
111 intptr_t Socket::GetStdioHandle(int num) { | 116 intptr_t Socket::GetStdioHandle(int num) { |
112 HANDLE handle; | 117 HANDLE handle; |
113 switch (num) { | 118 switch (num) { |
114 case 0: | 119 case 0: |
115 handle = GetStdHandle(STD_INPUT_HANDLE); | 120 handle = GetStdHandle(STD_INPUT_HANDLE); |
116 break; | 121 break; |
117 case 1: | 122 case 1: |
118 handle = GetStdHandle(STD_OUTPUT_HANDLE); | 123 handle = GetStdHandle(STD_OUTPUT_HANDLE); |
119 break; | 124 break; |
120 case 2: | 125 case 2: |
121 handle = GetStdHandle(STD_ERROR_HANDLE); | 126 handle = GetStdHandle(STD_ERROR_HANDLE); |
122 break; | 127 break; |
123 default: UNREACHABLE(); | 128 default: UNREACHABLE(); |
124 } | 129 } |
125 if (handle == INVALID_HANDLE_VALUE) { | 130 if (handle == INVALID_HANDLE_VALUE) { |
126 fprintf(stderr, "Error GetStdHandle: %d\n", GetLastError()); | |
127 return -1; | 131 return -1; |
128 } | 132 } |
129 FileHandle* file_handle = new FileHandle(handle); | 133 FileHandle* file_handle = new FileHandle(handle); |
130 if (file_handle == NULL) return -1; | 134 if (file_handle == NULL) return -1; |
131 file_handle->MarkDoesNotSupportOverlappedIO(); | 135 file_handle->MarkDoesNotSupportOverlappedIO(); |
132 return reinterpret_cast<intptr_t>(file_handle); | 136 return reinterpret_cast<intptr_t>(file_handle); |
133 } | 137 } |
134 | 138 |
135 | 139 |
136 intptr_t ServerSocket::Accept(intptr_t fd) { | 140 intptr_t ServerSocket::Accept(intptr_t fd) { |
(...skipping 14 matching lines...) Expand all Loading... |
151 hints.ai_family = AF_INET; | 155 hints.ai_family = AF_INET; |
152 hints.ai_socktype = SOCK_STREAM; | 156 hints.ai_socktype = SOCK_STREAM; |
153 hints.ai_protocol = IPPROTO_TCP; | 157 hints.ai_protocol = IPPROTO_TCP; |
154 struct addrinfo* info = NULL; | 158 struct addrinfo* info = NULL; |
155 int status = getaddrinfo(host, 0, &hints, &info); | 159 int status = getaddrinfo(host, 0, &hints, &info); |
156 if (status != 0) { | 160 if (status != 0) { |
157 ASSERT(*os_error == NULL); | 161 ASSERT(*os_error == NULL); |
158 *os_error = new OSError(status, | 162 *os_error = new OSError(status, |
159 gai_strerror(status), | 163 gai_strerror(status), |
160 OSError::kGetAddressInfo); | 164 OSError::kGetAddressInfo); |
161 (*os_error)->set_code(status); | |
162 (*os_error)->SetMessage(gai_strerror(status)); | |
163 return NULL; | 165 return NULL; |
164 } | 166 } |
165 // Convert the address into IPv4 dotted decimal notation. | 167 // Convert the address into IPv4 dotted decimal notation. |
166 char* buffer = reinterpret_cast<char*>(malloc(INET_ADDRSTRLEN)); | 168 char* buffer = reinterpret_cast<char*>(malloc(INET_ADDRSTRLEN)); |
167 sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(info->ai_addr); | 169 sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(info->ai_addr); |
168 const char* result = inet_ntop(AF_INET, | 170 const char* result = inet_ntop(AF_INET, |
169 reinterpret_cast<void *>(&sockaddr->sin_addr), | 171 reinterpret_cast<void *>(&sockaddr->sin_addr), |
170 buffer, | 172 buffer, |
171 INET_ADDRSTRLEN); | 173 INET_ADDRSTRLEN); |
172 if (result == NULL) { | 174 if (result == NULL) { |
173 free(buffer); | 175 free(buffer); |
174 return NULL; | 176 return NULL; |
175 } | 177 } |
176 ASSERT(result == buffer); | 178 ASSERT(result == buffer); |
177 return buffer; | 179 return buffer; |
178 } | 180 } |
179 | 181 |
180 | 182 |
181 intptr_t ServerSocket::CreateBindListen(const char* host, | 183 intptr_t ServerSocket::CreateBindListen(const char* host, |
182 intptr_t port, | 184 intptr_t port, |
183 intptr_t backlog) { | 185 intptr_t backlog) { |
184 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | 186 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
185 if (s == INVALID_SOCKET) { | 187 if (s == INVALID_SOCKET) { |
186 fprintf(stderr, "Error CreateBindListen: %d\n", WSAGetLastError()); | |
187 return -1; | 188 return -1; |
188 } | 189 } |
189 | 190 |
190 BOOL optval = true; | 191 BOOL optval = true; |
191 int status = setsockopt(s, | 192 int status = setsockopt(s, |
192 SOL_SOCKET, | 193 SOL_SOCKET, |
193 SO_REUSEADDR, | 194 SO_REUSEADDR, |
194 reinterpret_cast<const char*>(&optval), | 195 reinterpret_cast<const char*>(&optval), |
195 sizeof(optval)); | 196 sizeof(optval)); |
196 if (status == SOCKET_ERROR) { | 197 if (status == SOCKET_ERROR) { |
197 fprintf(stderr, "Error CreateBindListen: %d\n", WSAGetLastError()); | 198 DWORD rc = WSAGetLastError(); |
198 closesocket(s); | 199 closesocket(s); |
| 200 SetLastError(rc); |
199 return -1; | 201 return -1; |
200 } | 202 } |
201 | 203 |
202 sockaddr_in addr; | 204 sockaddr_in addr; |
203 memset(&addr, 0, sizeof(addr)); | 205 memset(&addr, 0, sizeof(addr)); |
204 addr.sin_family = AF_INET; | 206 addr.sin_family = AF_INET; |
205 addr.sin_addr.s_addr = inet_addr(host); | 207 addr.sin_addr.s_addr = inet_addr(host); |
206 addr.sin_port = htons(port); | 208 addr.sin_port = htons(port); |
207 status = bind(s, | 209 status = bind(s, |
208 reinterpret_cast<struct sockaddr *>(&addr), | 210 reinterpret_cast<struct sockaddr *>(&addr), |
209 sizeof(addr)); | 211 sizeof(addr)); |
210 if (status == SOCKET_ERROR) { | 212 if (status == SOCKET_ERROR) { |
211 fprintf(stderr, "Error CreateBindListen: %d\n", WSAGetLastError()); | 213 DWORD rc = WSAGetLastError(); |
212 closesocket(s); | 214 closesocket(s); |
| 215 SetLastError(rc); |
213 return -1; | 216 return -1; |
214 } | 217 } |
215 | 218 |
216 status = listen(s, backlog); | 219 status = listen(s, backlog); |
217 if (status == SOCKET_ERROR) { | 220 if (status == SOCKET_ERROR) { |
218 fprintf(stderr, "Error socket listen: %d\n", WSAGetLastError()); | 221 DWORD rc = WSAGetLastError(); |
219 closesocket(s); | 222 closesocket(s); |
| 223 SetLastError(rc); |
220 return -1; | 224 return -1; |
221 } | 225 } |
222 | 226 |
223 ListenSocket* listen_socket = new ListenSocket(s); | 227 ListenSocket* listen_socket = new ListenSocket(s); |
224 return reinterpret_cast<intptr_t>(listen_socket); | 228 return reinterpret_cast<intptr_t>(listen_socket); |
225 } | 229 } |
OLD | NEW |