Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: runtime/bin/socket_linux.cc

Issue 165723007: Move signal_blocker to platform and use it by default in TEMP_FAILURE_RETRY. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Tiny fix. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/socket_android.cc ('k') | runtime/bin/socket_macos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_LINUX) 6 #if defined(TARGET_OS_LINUX)
7 7
8 #include <errno.h> // NOLINT 8 #include <errno.h> // NOLINT
9 #include <stdio.h> // NOLINT 9 #include <stdio.h> // NOLINT
10 #include <stdlib.h> // NOLINT 10 #include <stdlib.h> // NOLINT
11 #include <string.h> // NOLINT 11 #include <string.h> // NOLINT
12 #include <sys/stat.h> // NOLINT 12 #include <sys/stat.h> // NOLINT
13 #include <unistd.h> // NOLINT 13 #include <unistd.h> // NOLINT
14 #include <net/if.h> // NOLINT 14 #include <net/if.h> // NOLINT
15 #include <netinet/tcp.h> // NOLINT 15 #include <netinet/tcp.h> // NOLINT
16 #include <ifaddrs.h> // NOLINT 16 #include <ifaddrs.h> // NOLINT
17 17
18 #include "bin/fdutils.h" 18 #include "bin/fdutils.h"
19 #include "bin/file.h" 19 #include "bin/file.h"
20 #include "bin/log.h" 20 #include "bin/log.h"
21 #include "bin/signal_blocker.h"
22 #include "bin/socket.h" 21 #include "bin/socket.h"
22 #include "platform/signal_blocker.h"
23 #include "vm/thread.h" 23 #include "vm/thread.h"
24 24
25 25
26 namespace dart { 26 namespace dart {
27 namespace bin { 27 namespace bin {
28 28
29 SocketAddress::SocketAddress(struct sockaddr* sa) { 29 SocketAddress::SocketAddress(struct sockaddr* sa) {
30 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); 30 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
31 if (!Socket::FormatNumericAddress( 31 if (!Socket::FormatNumericAddress(
32 reinterpret_cast<RawAddr*>(sa), as_string_, INET6_ADDRSTRLEN)) { 32 reinterpret_cast<RawAddr*>(sa), as_string_, INET6_ADDRSTRLEN)) {
33 as_string_[0] = 0; 33 as_string_[0] = 0;
34 } 34 }
35 socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa)); 35 socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa));
36 memmove(reinterpret_cast<void *>(&addr_), sa, salen); 36 memmove(reinterpret_cast<void *>(&addr_), sa, salen);
37 } 37 }
38 38
39 39
40 bool Socket::FormatNumericAddress(RawAddr* addr, char* address, int len) { 40 bool Socket::FormatNumericAddress(RawAddr* addr, char* address, int len) {
41 socklen_t salen = SocketAddress::GetAddrLength(addr); 41 socklen_t salen = SocketAddress::GetAddrLength(addr);
42 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getnameinfo(&addr->addr, 42 if (NO_RETRY_EXPECTED(getnameinfo(
43 salen, 43 &addr->addr, salen, address, len, NULL, 0, NI_NUMERICHOST) != 0)) {
44 address,
45 len,
46 NULL,
47 0,
48 NI_NUMERICHOST)) != 0) {
49 return false; 44 return false;
50 } 45 }
51 return true; 46 return true;
52 } 47 }
53 48
54 49
55 bool Socket::Initialize() { 50 bool Socket::Initialize() {
56 // Nothing to do on Linux. 51 // Nothing to do on Linux.
57 return true; 52 return true;
58 } 53 }
59 54
60 55
61 intptr_t Socket::Create(RawAddr addr) { 56 intptr_t Socket::Create(RawAddr addr) {
62 intptr_t fd; 57 intptr_t fd;
63 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket( 58 fd = NO_RETRY_EXPECTED(
64 addr.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); 59 socket(addr.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
65 if (fd < 0) { 60 if (fd < 0) {
66 const int kBufferSize = 1024; 61 const int kBufferSize = 1024;
67 char error_buf[kBufferSize]; 62 char error_buf[kBufferSize];
68 Log::PrintErr("Error Create: %s\n", 63 Log::PrintErr("Error Create: %s\n",
69 strerror_r(errno, error_buf, kBufferSize)); 64 strerror_r(errno, error_buf, kBufferSize));
70 return -1; 65 return -1;
71 } 66 }
72 return fd; 67 return fd;
73 } 68 }
74 69
75 70
76 intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) { 71 intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) {
77 SocketAddress::SetAddrPort(&addr, port); 72 SocketAddress::SetAddrPort(&addr, port);
78 intptr_t result = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 73 intptr_t result = TEMP_FAILURE_RETRY(
79 connect(fd, 74 connect(fd, &addr.addr, SocketAddress::GetAddrLength(&addr)));
80 &addr.addr,
81 SocketAddress::GetAddrLength(&addr)));
82 if (result == 0 || errno == EINPROGRESS) { 75 if (result == 0 || errno == EINPROGRESS) {
83 return fd; 76 return fd;
84 } 77 }
85 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 78 VOID_TEMP_FAILURE_RETRY(close(fd));
86 return -1; 79 return -1;
87 } 80 }
88 81
89 82
90 intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) { 83 intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) {
91 intptr_t fd = Socket::Create(addr); 84 intptr_t fd = Socket::Create(addr);
92 if (fd < 0) { 85 if (fd < 0) {
93 return fd; 86 return fd;
94 } 87 }
95 return Socket::Connect(fd, addr, port); 88 return Socket::Connect(fd, addr, port);
96 } 89 }
97 90
98 91
99 intptr_t Socket::Available(intptr_t fd) { 92 intptr_t Socket::Available(intptr_t fd) {
100 return FDUtils::AvailableBytes(fd); 93 return FDUtils::AvailableBytes(fd);
101 } 94 }
102 95
103 96
104 int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { 97 int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
105 ASSERT(fd >= 0); 98 ASSERT(fd >= 0);
106 ssize_t read_bytes = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(read(fd, buffer, 99 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
107 num_bytes));
108 ASSERT(EAGAIN == EWOULDBLOCK); 100 ASSERT(EAGAIN == EWOULDBLOCK);
109 if (read_bytes == -1 && errno == EWOULDBLOCK) { 101 if (read_bytes == -1 && errno == EWOULDBLOCK) {
110 // If the read would block we need to retry and therefore return 0 102 // If the read would block we need to retry and therefore return 0
111 // as the number of bytes written. 103 // as the number of bytes written.
112 read_bytes = 0; 104 read_bytes = 0;
113 } 105 }
114 return read_bytes; 106 return read_bytes;
115 } 107 }
116 108
117 109
118 int Socket::RecvFrom(intptr_t fd, void* buffer, intptr_t num_bytes, 110 int Socket::RecvFrom(intptr_t fd, void* buffer, intptr_t num_bytes,
119 RawAddr* addr) { 111 RawAddr* addr) {
120 ASSERT(fd >= 0); 112 ASSERT(fd >= 0);
121 socklen_t addr_len = sizeof(addr->ss); 113 socklen_t addr_len = sizeof(addr->ss);
122 ssize_t read_bytes = 114 ssize_t read_bytes = TEMP_FAILURE_RETRY(
123 TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 115 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
124 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
125 if (read_bytes == -1 && errno == EWOULDBLOCK) { 116 if (read_bytes == -1 && errno == EWOULDBLOCK) {
126 // If the read would block we need to retry and therefore return 0 117 // If the read would block we need to retry and therefore return 0
127 // as the number of bytes written. 118 // as the number of bytes written.
128 read_bytes = 0; 119 read_bytes = 0;
129 } 120 }
130 return read_bytes; 121 return read_bytes;
131 } 122 }
132 123
133 124
134 int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { 125 int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
135 ASSERT(fd >= 0); 126 ASSERT(fd >= 0);
136 ssize_t written_bytes = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(write(fd, buffer, 127 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
137 num_bytes));
138 ASSERT(EAGAIN == EWOULDBLOCK); 128 ASSERT(EAGAIN == EWOULDBLOCK);
139 if (written_bytes == -1 && errno == EWOULDBLOCK) { 129 if (written_bytes == -1 && errno == EWOULDBLOCK) {
140 // If the would block we need to retry and therefore return 0 as 130 // If the would block we need to retry and therefore return 0 as
141 // the number of bytes written. 131 // the number of bytes written.
142 written_bytes = 0; 132 written_bytes = 0;
143 } 133 }
144 return written_bytes; 134 return written_bytes;
145 } 135 }
146 136
147 137
148 int Socket::SendTo(intptr_t fd, const void* buffer, intptr_t num_bytes, 138 int Socket::SendTo(intptr_t fd, const void* buffer, intptr_t num_bytes,
149 RawAddr addr) { 139 RawAddr addr) {
150 ASSERT(fd >= 0); 140 ASSERT(fd >= 0);
151 ssize_t written_bytes = 141 ssize_t written_bytes = TEMP_FAILURE_RETRY(
152 TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 142 sendto(fd, buffer, num_bytes, 0,
153 sendto(fd, buffer, num_bytes, 0, 143 &addr.addr, SocketAddress::GetAddrLength(&addr)));
154 &addr.addr, SocketAddress::GetAddrLength(&addr)));
155 ASSERT(EAGAIN == EWOULDBLOCK); 144 ASSERT(EAGAIN == EWOULDBLOCK);
156 if (written_bytes == -1 && errno == EWOULDBLOCK) { 145 if (written_bytes == -1 && errno == EWOULDBLOCK) {
157 // If the would block we need to retry and therefore return 0 as 146 // If the would block we need to retry and therefore return 0 as
158 // the number of bytes written. 147 // the number of bytes written.
159 written_bytes = 0; 148 written_bytes = 0;
160 } 149 }
161 return written_bytes; 150 return written_bytes;
162 } 151 }
163 152
164 153
165 intptr_t Socket::GetPort(intptr_t fd) { 154 intptr_t Socket::GetPort(intptr_t fd) {
166 ASSERT(fd >= 0); 155 ASSERT(fd >= 0);
167 RawAddr raw; 156 RawAddr raw;
168 socklen_t size = sizeof(raw); 157 socklen_t size = sizeof(raw);
169 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 158 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
170 getsockname(fd,
171 &raw.addr,
172 &size))) {
173 const int kBufferSize = 1024; 159 const int kBufferSize = 1024;
174 char error_buf[kBufferSize]; 160 char error_buf[kBufferSize];
175 Log::PrintErr("Error getsockname: %s\n", 161 Log::PrintErr("Error getsockname: %s\n",
176 strerror_r(errno, error_buf, kBufferSize)); 162 strerror_r(errno, error_buf, kBufferSize));
177 return 0; 163 return 0;
178 } 164 }
179 return SocketAddress::GetAddrPort(&raw); 165 return SocketAddress::GetAddrPort(&raw);
180 } 166 }
181 167
182 168
183 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { 169 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) {
184 ASSERT(fd >= 0); 170 ASSERT(fd >= 0);
185 RawAddr raw; 171 RawAddr raw;
186 socklen_t size = sizeof(raw); 172 socklen_t size = sizeof(raw);
187 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 173 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) {
188 getpeername(fd,
189 &raw.addr,
190 &size))) {
191 return NULL; 174 return NULL;
192 } 175 }
193 *port = SocketAddress::GetAddrPort(&raw); 176 *port = SocketAddress::GetAddrPort(&raw);
194 return new SocketAddress(&raw.addr); 177 return new SocketAddress(&raw.addr);
195 } 178 }
196 179
197 180
198 void Socket::GetError(intptr_t fd, OSError* os_error) { 181 void Socket::GetError(intptr_t fd, OSError* os_error) {
199 int len = sizeof(errno); 182 int len = sizeof(errno);
200 int err = 0; 183 int err = 0;
201 getsockopt(fd, 184 VOID_NO_RETRY_EXPECTED(getsockopt(
202 SOL_SOCKET, 185 fd, SOL_SOCKET, SO_ERROR, &err, reinterpret_cast<socklen_t*>(&len)));
203 SO_ERROR,
204 &err,
205 reinterpret_cast<socklen_t*>(&len));
206 errno = err; 186 errno = err;
207 os_error->SetCodeAndMessage(OSError::kSystem, errno); 187 os_error->SetCodeAndMessage(OSError::kSystem, errno);
208 } 188 }
209 189
210 190
211 int Socket::GetType(intptr_t fd) { 191 int Socket::GetType(intptr_t fd) {
212 struct stat64 buf; 192 struct stat64 buf;
213 int result = fstat64(fd, &buf); 193 int result = NO_RETRY_EXPECTED(fstat64(fd, &buf));
214 if (result == -1) return -1; 194 if (result == -1) return -1;
215 if (S_ISCHR(buf.st_mode)) return File::kTerminal; 195 if (S_ISCHR(buf.st_mode)) return File::kTerminal;
216 if (S_ISFIFO(buf.st_mode)) return File::kPipe; 196 if (S_ISFIFO(buf.st_mode)) return File::kPipe;
217 if (S_ISREG(buf.st_mode)) return File::kFile; 197 if (S_ISREG(buf.st_mode)) return File::kFile;
218 return File::kOther; 198 return File::kOther;
219 } 199 }
220 200
221 201
222 intptr_t Socket::GetStdioHandle(intptr_t num) { 202 intptr_t Socket::GetStdioHandle(intptr_t num) {
223 return num; 203 return num;
224 } 204 }
225 205
226 206
227 AddressList<SocketAddress>* Socket::LookupAddress(const char* host, 207 AddressList<SocketAddress>* Socket::LookupAddress(const char* host,
228 int type, 208 int type,
229 OSError** os_error) { 209 OSError** os_error) {
230 // Perform a name lookup for a host name. 210 // Perform a name lookup for a host name.
231 struct addrinfo hints; 211 struct addrinfo hints;
232 memset(&hints, 0, sizeof(hints)); 212 memset(&hints, 0, sizeof(hints));
233 hints.ai_family = SocketAddress::FromType(type); 213 hints.ai_family = SocketAddress::FromType(type);
234 hints.ai_socktype = SOCK_STREAM; 214 hints.ai_socktype = SOCK_STREAM;
235 hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG); 215 hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
236 hints.ai_protocol = IPPROTO_TCP; 216 hints.ai_protocol = IPPROTO_TCP;
237 struct addrinfo* info = NULL; 217 struct addrinfo* info = NULL;
238 int status = getaddrinfo(host, 0, &hints, &info); 218 int status = NO_RETRY_EXPECTED(getaddrinfo(host, 0, &hints, &info));
239 if (status != 0) { 219 if (status != 0) {
240 // We failed, try without AI_ADDRCONFIG. This can happen when looking up 220 // We failed, try without AI_ADDRCONFIG. This can happen when looking up
241 // e.g. '::1', when there are no global IPv6 addresses. 221 // e.g. '::1', when there are no global IPv6 addresses.
242 hints.ai_flags = AI_V4MAPPED; 222 hints.ai_flags = AI_V4MAPPED;
243 status = getaddrinfo(host, 0, &hints, &info); 223 status = NO_RETRY_EXPECTED(getaddrinfo(host, 0, &hints, &info));
244 if (status != 0) { 224 if (status != 0) {
245 ASSERT(*os_error == NULL); 225 ASSERT(*os_error == NULL);
246 *os_error = new OSError(status, 226 *os_error = new OSError(status,
247 gai_strerror(status), 227 gai_strerror(status),
248 OSError::kGetAddressInfo); 228 OSError::kGetAddressInfo);
249 return NULL; 229 return NULL;
250 } 230 }
251 } 231 }
252 intptr_t count = 0; 232 intptr_t count = 0;
253 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { 233 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
(...skipping 10 matching lines...) Expand all
264 freeaddrinfo(info); 244 freeaddrinfo(info);
265 return addresses; 245 return addresses;
266 } 246 }
267 247
268 248
269 bool Socket::ReverseLookup(RawAddr addr, 249 bool Socket::ReverseLookup(RawAddr addr,
270 char* host, 250 char* host,
271 intptr_t host_len, 251 intptr_t host_len,
272 OSError** os_error) { 252 OSError** os_error) {
273 ASSERT(host_len >= NI_MAXHOST); 253 ASSERT(host_len >= NI_MAXHOST);
274 int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getnameinfo( 254 int status = NO_RETRY_EXPECTED(getnameinfo(
275 &addr.addr, 255 &addr.addr,
276 SocketAddress::GetAddrLength(&addr), 256 SocketAddress::GetAddrLength(&addr),
277 host, 257 host,
278 host_len, 258 host_len,
279 NULL, 259 NULL,
280 0, 260 0,
281 NI_NAMEREQD)); 261 NI_NAMEREQD));
282 if (status != 0) { 262 if (status != 0) {
283 ASSERT(*os_error == NULL); 263 ASSERT(*os_error == NULL);
284 *os_error = new OSError(status, 264 *os_error = new OSError(status,
285 gai_strerror(status), 265 gai_strerror(status),
286 OSError::kGetAddressInfo); 266 OSError::kGetAddressInfo);
287 return false; 267 return false;
288 } 268 }
289 return true; 269 return true;
290 } 270 }
291 271
292 272
293 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { 273 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) {
294 int result; 274 int result;
295 if (type == SocketAddress::TYPE_IPV4) { 275 if (type == SocketAddress::TYPE_IPV4) {
296 result = inet_pton(AF_INET, address, &addr->in.sin_addr); 276 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr));
297 } else { 277 } else {
298 ASSERT(type == SocketAddress::TYPE_IPV6); 278 ASSERT(type == SocketAddress::TYPE_IPV6);
299 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); 279 result = NO_RETRY_EXPECTED(
280 inet_pton(AF_INET6, address, &addr->in6.sin6_addr));
300 } 281 }
301 return result == 1; 282 return result == 1;
302 } 283 }
303 284
304 285
305 intptr_t Socket::CreateBindDatagram( 286 intptr_t Socket::CreateBindDatagram(
306 RawAddr* addr, intptr_t port, bool reuseAddress) { 287 RawAddr* addr, intptr_t port, bool reuseAddress) {
307 intptr_t fd; 288 intptr_t fd;
308 289
309 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket( 290 fd = NO_RETRY_EXPECTED(socket(addr->addr.sa_family,
310 addr->addr.sa_family, 291 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
311 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 292 IPPROTO_UDP));
312 IPPROTO_UDP));
313 if (fd < 0) return -1; 293 if (fd < 0) return -1;
314 294
315 if (reuseAddress) { 295 if (reuseAddress) {
316 int optval = 1; 296 int optval = 1;
317 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 297 VOID_NO_RETRY_EXPECTED(
318 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); 298 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
319 } 299 }
320 300
321 SocketAddress::SetAddrPort(addr, port); 301 SocketAddress::SetAddrPort(addr, port);
322 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 302 if (NO_RETRY_EXPECTED(
323 bind(fd, 303 bind(fd, &addr->addr, SocketAddress::GetAddrLength(addr))) < 0) {
324 &addr->addr, 304 VOID_TEMP_FAILURE_RETRY(close(fd));
325 SocketAddress::GetAddrLength(addr))) < 0) {
326 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
327 return -1; 305 return -1;
328 } 306 }
329 return fd; 307 return fd;
330 } 308 }
331 309
332 310
333 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { 311 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
334 if (ifa->ifa_addr == NULL) { 312 if (ifa->ifa_addr == NULL) {
335 // OpenVPN's virtual device tun0. 313 // OpenVPN's virtual device tun0.
336 return false; 314 return false;
337 } 315 }
338 int family = ifa->ifa_addr->sa_family; 316 int family = ifa->ifa_addr->sa_family;
339 if (lookup_family == family) return true; 317 if (lookup_family == family) return true;
340 if (lookup_family == AF_UNSPEC && 318 if (lookup_family == AF_UNSPEC &&
341 (family == AF_INET || family == AF_INET6)) { 319 (family == AF_INET || family == AF_INET6)) {
342 return true; 320 return true;
343 } 321 }
344 return false; 322 return false;
345 } 323 }
346 324
347 325
348 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( 326 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
349 int type, 327 int type,
350 OSError** os_error) { 328 OSError** os_error) {
351 struct ifaddrs* ifaddr; 329 struct ifaddrs* ifaddr;
352 330
353 int status = getifaddrs(&ifaddr); 331 int status = NO_RETRY_EXPECTED(getifaddrs(&ifaddr));
354 if (status != 0) { 332 if (status != 0) {
355 ASSERT(*os_error == NULL); 333 ASSERT(*os_error == NULL);
356 *os_error = new OSError(status, 334 *os_error = new OSError(status,
357 gai_strerror(status), 335 gai_strerror(status),
358 OSError::kGetAddressInfo); 336 OSError::kGetAddressInfo);
359 return NULL; 337 return NULL;
360 } 338 }
361 339
362 int lookup_family = SocketAddress::FromType(type); 340 int lookup_family = SocketAddress::FromType(type);
363 341
(...skipping 16 matching lines...) Expand all
380 return addresses; 358 return addresses;
381 } 359 }
382 360
383 361
384 intptr_t ServerSocket::CreateBindListen(RawAddr addr, 362 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
385 intptr_t port, 363 intptr_t port,
386 intptr_t backlog, 364 intptr_t backlog,
387 bool v6_only) { 365 bool v6_only) {
388 intptr_t fd; 366 intptr_t fd;
389 367
390 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket( 368 fd = NO_RETRY_EXPECTED(
391 addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)); 369 socket(addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
392 if (fd < 0) return -1; 370 if (fd < 0) return -1;
393 371
394 int optval = 1; 372 int optval = 1;
395 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 373 VOID_NO_RETRY_EXPECTED(
396 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); 374 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
397 375
398 if (addr.ss.ss_family == AF_INET6) { 376 if (addr.ss.ss_family == AF_INET6) {
399 optval = v6_only ? 1 : 0; 377 optval = v6_only ? 1 : 0;
400 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 378 VOID_NO_RETRY_EXPECTED(
401 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))); 379 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
402 } 380 }
403 381
404 SocketAddress::SetAddrPort(&addr, port); 382 SocketAddress::SetAddrPort(&addr, port);
405 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 383 if (NO_RETRY_EXPECTED(
406 bind(fd, 384 bind(fd, &addr.addr, SocketAddress::GetAddrLength(&addr))) < 0) {
407 &addr.addr, 385 VOID_TEMP_FAILURE_RETRY(close(fd));
408 SocketAddress::GetAddrLength(&addr))) < 0) {
409 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
410 return -1; 386 return -1;
411 } 387 }
412 388
413 // Test for invalid socket port 65535 (some browsers disallow it). 389 // Test for invalid socket port 65535 (some browsers disallow it).
414 if (port == 0 && Socket::GetPort(fd) == 65535) { 390 if (port == 0 && Socket::GetPort(fd) == 65535) {
415 // Don't close the socket until we have created a new socket, ensuring 391 // Don't close the socket until we have created a new socket, ensuring
416 // that we do not get the bad port number again. 392 // that we do not get the bad port number again.
417 intptr_t new_fd = CreateBindListen(addr, 0, backlog, v6_only); 393 intptr_t new_fd = CreateBindListen(addr, 0, backlog, v6_only);
418 int err = errno; 394 int err = errno;
419 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 395 VOID_TEMP_FAILURE_RETRY(close(fd));
420 errno = err; 396 errno = err;
421 return new_fd; 397 return new_fd;
422 } 398 }
423 399
424 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 400 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
425 listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { 401 VOID_TEMP_FAILURE_RETRY(close(fd));
426 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
427 return -1; 402 return -1;
428 } 403 }
429 404
430 return fd; 405 return fd;
431 } 406 }
432 407
433 408
434 static bool IsTemporaryAcceptError(int error) { 409 static bool IsTemporaryAcceptError(int error) {
435 // On Linux a number of protocol errors should be treated as EAGAIN. 410 // On Linux a number of protocol errors should be treated as EAGAIN.
436 // These are the ones for TCP/IP. 411 // These are the ones for TCP/IP.
437 return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) || 412 return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) ||
438 (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) || 413 (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) ||
439 (error == EHOSTUNREACH) || (error == EOPNOTSUPP) || 414 (error == EHOSTUNREACH) || (error == EOPNOTSUPP) ||
440 (error == ENETUNREACH); 415 (error == ENETUNREACH);
441 } 416 }
442 417
443 418
444 intptr_t ServerSocket::Accept(intptr_t fd) { 419 intptr_t ServerSocket::Accept(intptr_t fd) {
445 intptr_t socket; 420 intptr_t socket;
446 struct sockaddr clientaddr; 421 struct sockaddr clientaddr;
447 socklen_t addrlen = sizeof(clientaddr); 422 socklen_t addrlen = sizeof(clientaddr);
448 socket = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(accept4( 423 socket = TEMP_FAILURE_RETRY(accept4(
449 fd, &clientaddr, &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC)); 424 fd, &clientaddr, &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC));
450 if (socket == -1) { 425 if (socket == -1) {
451 if (IsTemporaryAcceptError(errno)) { 426 if (IsTemporaryAcceptError(errno)) {
452 // We need to signal to the caller that this is actually not an 427 // We need to signal to the caller that this is actually not an
453 // error. We got woken up from the poll on the listening socket, 428 // error. We got woken up from the poll on the listening socket,
454 // but there is no connection ready to be accepted. 429 // but there is no connection ready to be accepted.
455 ASSERT(kTemporaryFailure != -1); 430 ASSERT(kTemporaryFailure != -1);
456 socket = kTemporaryFailure; 431 socket = kTemporaryFailure;
457 } 432 }
458 } 433 }
459 return socket; 434 return socket;
460 } 435 }
461 436
462 437
463 void Socket::Close(intptr_t fd) { 438 void Socket::Close(intptr_t fd) {
464 ASSERT(fd >= 0); 439 ASSERT(fd >= 0);
465 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 440 int err = TEMP_FAILURE_RETRY(close(fd));
466 if (err != 0) { 441 if (err != 0) {
467 const int kBufferSize = 1024; 442 const int kBufferSize = 1024;
468 char error_buf[kBufferSize]; 443 char error_buf[kBufferSize];
469 Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize)); 444 Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize));
470 } 445 }
471 } 446 }
472 447
473 448
474 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) { 449 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) {
475 int on; 450 int on;
476 socklen_t len = sizeof(on); 451 socklen_t len = sizeof(on);
477 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd, 452 int err = NO_RETRY_EXPECTED(getsockopt(
478 IPPROTO_TCP, 453 fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<void *>(&on), &len));
479 TCP_NODELAY,
480 reinterpret_cast<void *>(&on),
481 &len));
482 if (err == 0) { 454 if (err == 0) {
483 *enabled = on == 1; 455 *enabled = on == 1;
484 } 456 }
485 return err == 0; 457 return err == 0;
486 } 458 }
487 459
488 460
489 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { 461 bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
490 int on = enabled ? 1 : 0; 462 int on = enabled ? 1 : 0;
491 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd, 463 return NO_RETRY_EXPECTED(setsockopt(fd,
492 IPPROTO_TCP, 464 IPPROTO_TCP,
493 TCP_NODELAY, 465 TCP_NODELAY,
494 reinterpret_cast<char *>(&on), 466 reinterpret_cast<char *>(&on),
495 sizeof(on))) == 0; 467 sizeof(on))) == 0;
496 } 468 }
497 469
498 470
499 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) { 471 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) {
500 uint8_t on; 472 uint8_t on;
501 socklen_t len = sizeof(on); 473 socklen_t len = sizeof(on);
502 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 474 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
503 int optname = protocol == SocketAddress::TYPE_IPV4 475 int optname = protocol == SocketAddress::TYPE_IPV4
504 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; 476 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP;
505 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd, 477 if (NO_RETRY_EXPECTED(getsockopt(
506 level, 478 fd, level, optname, reinterpret_cast<char *>(&on), &len)) == 0) {
507 optname,
508 reinterpret_cast<char *>(&on),
509 &len)) == 0) {
510 *enabled = (on == 1); 479 *enabled = (on == 1);
511 return true; 480 return true;
512 } 481 }
513 return false; 482 return false;
514 } 483 }
515 484
516 485
517 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) { 486 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) {
518 int on = enabled ? 1 : 0; 487 int on = enabled ? 1 : 0;
519 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 488 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
520 int optname = protocol == SocketAddress::TYPE_IPV4 489 int optname = protocol == SocketAddress::TYPE_IPV4
521 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; 490 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP;
522 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd, 491 return NO_RETRY_EXPECTED(setsockopt(
523 level, 492 fd, level, optname, reinterpret_cast<char *>(&on), sizeof(on))) == 0;
524 optname,
525 reinterpret_cast<char *>(&on),
526 sizeof(on))) == 0;
527 } 493 }
528 494
529 495
530 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { 496 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
531 uint8_t v; 497 uint8_t v;
532 socklen_t len = sizeof(v); 498 socklen_t len = sizeof(v);
533 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 499 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
534 int optname = protocol == SocketAddress::TYPE_IPV4 500 int optname = protocol == SocketAddress::TYPE_IPV4
535 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; 501 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS;
536 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd, 502 if (NO_RETRY_EXPECTED(getsockopt(
537 level, 503 fd, level, optname, reinterpret_cast<char *>(&v), &len)) == 0) {
538 optname,
539 reinterpret_cast<char *>(&v),
540 &len)) == 0) {
541 *value = v; 504 *value = v;
542 return true; 505 return true;
543 } 506 }
544 return false; 507 return false;
545 } 508 }
546 509
547 510
548 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { 511 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
549 int v = value; 512 int v = value;
550 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 513 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
551 int optname = protocol == SocketAddress::TYPE_IPV4 514 int optname = protocol == SocketAddress::TYPE_IPV4
552 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; 515 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS;
553 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd, 516 return NO_RETRY_EXPECTED(setsockopt(
554 level, 517 fd, level, optname, reinterpret_cast<char *>(&v), sizeof(v))) == 0;
555 optname,
556 reinterpret_cast<char *>(&v),
557 sizeof(v))) == 0;
558 } 518 }
559 519
560 520
561 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) { 521 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) {
562 int on; 522 int on;
563 socklen_t len = sizeof(on); 523 socklen_t len = sizeof(on);
564 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd, 524 int err = NO_RETRY_EXPECTED(getsockopt(
565 SOL_SOCKET, 525 fd, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<char *>(&on), &len));
566 SO_BROADCAST,
567 reinterpret_cast<char *>(&on),
568 &len));
569 if (err == 0) { 526 if (err == 0) {
570 *enabled = on == 1; 527 *enabled = on == 1;
571 } 528 }
572 return err == 0; 529 return err == 0;
573 } 530 }
574 531
575 532
576 bool Socket::SetBroadcast(intptr_t fd, bool enabled) { 533 bool Socket::SetBroadcast(intptr_t fd, bool enabled) {
577 int on = enabled ? 1 : 0; 534 int on = enabled ? 1 : 0;
578 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd, 535 return NO_RETRY_EXPECTED(setsockopt(fd,
579 SOL_SOCKET, 536 SOL_SOCKET,
580 SO_BROADCAST, 537 SO_BROADCAST,
581 reinterpret_cast<char *>(&on), 538 reinterpret_cast<char *>(&on),
582 sizeof(on))) == 0; 539 sizeof(on))) == 0;
583 } 540 }
584 541
585 542
586 bool Socket::JoinMulticast( 543 bool Socket::JoinMulticast(
587 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) { 544 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) {
588 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 545 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
589 struct group_req mreq; 546 struct group_req mreq;
590 mreq.gr_interface = interfaceIndex; 547 mreq.gr_interface = interfaceIndex;
591 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr)); 548 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr));
592 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt( 549 return NO_RETRY_EXPECTED(
593 fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; 550 setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0;
594 } 551 }
595 552
596 553
597 bool Socket::LeaveMulticast( 554 bool Socket::LeaveMulticast(
598 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) { 555 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) {
599 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 556 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
600 struct group_req mreq; 557 struct group_req mreq;
601 mreq.gr_interface = interfaceIndex; 558 mreq.gr_interface = interfaceIndex;
602 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr)); 559 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr));
603 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt( 560 return NO_RETRY_EXPECTED(
604 fd, proto, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0; 561 setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0;
605 } 562 }
606 563
607 } // namespace bin 564 } // namespace bin
608 } // namespace dart 565 } // namespace dart
609 566
610 #endif // defined(TARGET_OS_LINUX) 567 #endif // defined(TARGET_OS_LINUX)
OLDNEW
« no previous file with comments | « runtime/bin/socket_android.cc ('k') | runtime/bin/socket_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698