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

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: Created 6 years, 10 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
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 (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 = socket(addr.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
64 addr.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
65 if (fd < 0) { 59 if (fd < 0) {
66 const int kBufferSize = 1024; 60 const int kBufferSize = 1024;
67 char error_buf[kBufferSize]; 61 char error_buf[kBufferSize];
68 Log::PrintErr("Error Create: %s\n", 62 Log::PrintErr("Error Create: %s\n",
69 strerror_r(errno, error_buf, kBufferSize)); 63 strerror_r(errno, error_buf, kBufferSize));
70 return -1; 64 return -1;
71 } 65 }
72 return fd; 66 return fd;
73 } 67 }
74 68
75 69
76 intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) { 70 intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) {
77 SocketAddress::SetAddrPort(&addr, port); 71 SocketAddress::SetAddrPort(&addr, port);
78 intptr_t result = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 72 intptr_t result = TEMP_FAILURE_RETRY(
79 connect(fd, 73 connect(fd, &addr.addr, SocketAddress::GetAddrLength(&addr)));
80 &addr.addr,
81 SocketAddress::GetAddrLength(&addr)));
82 if (result == 0 || errno == EINPROGRESS) { 74 if (result == 0 || errno == EINPROGRESS) {
83 return fd; 75 return fd;
84 } 76 }
85 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 77 VOID_TEMP_FAILURE_RETRY(close(fd));
86 return -1; 78 return -1;
87 } 79 }
88 80
89 81
90 intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) { 82 intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) {
91 intptr_t fd = Socket::Create(addr); 83 intptr_t fd = Socket::Create(addr);
92 if (fd < 0) { 84 if (fd < 0) {
93 return fd; 85 return fd;
94 } 86 }
95 return Socket::Connect(fd, addr, port); 87 return Socket::Connect(fd, addr, port);
96 } 88 }
97 89
98 90
99 intptr_t Socket::Available(intptr_t fd) { 91 intptr_t Socket::Available(intptr_t fd) {
100 return FDUtils::AvailableBytes(fd); 92 return FDUtils::AvailableBytes(fd);
101 } 93 }
102 94
103 95
104 int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { 96 int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
105 ASSERT(fd >= 0); 97 ASSERT(fd >= 0);
106 ssize_t read_bytes = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(read(fd, buffer, 98 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
107 num_bytes));
108 ASSERT(EAGAIN == EWOULDBLOCK); 99 ASSERT(EAGAIN == EWOULDBLOCK);
109 if (read_bytes == -1 && errno == EWOULDBLOCK) { 100 if (read_bytes == -1 && errno == EWOULDBLOCK) {
110 // If the read would block we need to retry and therefore return 0 101 // If the read would block we need to retry and therefore return 0
111 // as the number of bytes written. 102 // as the number of bytes written.
112 read_bytes = 0; 103 read_bytes = 0;
113 } 104 }
114 return read_bytes; 105 return read_bytes;
115 } 106 }
116 107
117 108
118 int Socket::RecvFrom(intptr_t fd, void* buffer, intptr_t num_bytes, 109 int Socket::RecvFrom(intptr_t fd, void* buffer, intptr_t num_bytes,
119 RawAddr* addr) { 110 RawAddr* addr) {
120 ASSERT(fd >= 0); 111 ASSERT(fd >= 0);
121 socklen_t addr_len = sizeof(addr->ss); 112 socklen_t addr_len = sizeof(addr->ss);
122 ssize_t read_bytes = 113 ssize_t read_bytes = TEMP_FAILURE_RETRY(
123 TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 114 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) { 115 if (read_bytes == -1 && errno == EWOULDBLOCK) {
126 // If the read would block we need to retry and therefore return 0 116 // If the read would block we need to retry and therefore return 0
127 // as the number of bytes written. 117 // as the number of bytes written.
128 read_bytes = 0; 118 read_bytes = 0;
129 } 119 }
130 return read_bytes; 120 return read_bytes;
131 } 121 }
132 122
133 123
134 int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { 124 int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
135 ASSERT(fd >= 0); 125 ASSERT(fd >= 0);
136 ssize_t written_bytes = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(write(fd, buffer, 126 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
137 num_bytes));
138 ASSERT(EAGAIN == EWOULDBLOCK); 127 ASSERT(EAGAIN == EWOULDBLOCK);
139 if (written_bytes == -1 && errno == EWOULDBLOCK) { 128 if (written_bytes == -1 && errno == EWOULDBLOCK) {
140 // If the would block we need to retry and therefore return 0 as 129 // If the would block we need to retry and therefore return 0 as
141 // the number of bytes written. 130 // the number of bytes written.
142 written_bytes = 0; 131 written_bytes = 0;
143 } 132 }
144 return written_bytes; 133 return written_bytes;
145 } 134 }
146 135
147 136
148 int Socket::SendTo(intptr_t fd, const void* buffer, intptr_t num_bytes, 137 int Socket::SendTo(intptr_t fd, const void* buffer, intptr_t num_bytes,
149 RawAddr addr) { 138 RawAddr addr) {
150 ASSERT(fd >= 0); 139 ASSERT(fd >= 0);
151 ssize_t written_bytes = 140 ssize_t written_bytes = TEMP_FAILURE_RETRY(
152 TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 141 sendto(fd, buffer, num_bytes, 0,
153 sendto(fd, buffer, num_bytes, 0, 142 &addr.addr, SocketAddress::GetAddrLength(&addr)));
154 &addr.addr, SocketAddress::GetAddrLength(&addr)));
155 ASSERT(EAGAIN == EWOULDBLOCK); 143 ASSERT(EAGAIN == EWOULDBLOCK);
156 if (written_bytes == -1 && errno == EWOULDBLOCK) { 144 if (written_bytes == -1 && errno == EWOULDBLOCK) {
157 // If the would block we need to retry and therefore return 0 as 145 // If the would block we need to retry and therefore return 0 as
158 // the number of bytes written. 146 // the number of bytes written.
159 written_bytes = 0; 147 written_bytes = 0;
160 } 148 }
161 return written_bytes; 149 return written_bytes;
162 } 150 }
163 151
164 152
165 intptr_t Socket::GetPort(intptr_t fd) { 153 intptr_t Socket::GetPort(intptr_t fd) {
166 ASSERT(fd >= 0); 154 ASSERT(fd >= 0);
167 RawAddr raw; 155 RawAddr raw;
168 socklen_t size = sizeof(raw); 156 socklen_t size = sizeof(raw);
169 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 157 if (getsockname(fd, &raw.addr, &size)) {
170 getsockname(fd,
171 &raw.addr,
172 &size))) {
173 const int kBufferSize = 1024; 158 const int kBufferSize = 1024;
174 char error_buf[kBufferSize]; 159 char error_buf[kBufferSize];
175 Log::PrintErr("Error getsockname: %s\n", 160 Log::PrintErr("Error getsockname: %s\n",
176 strerror_r(errno, error_buf, kBufferSize)); 161 strerror_r(errno, error_buf, kBufferSize));
177 return 0; 162 return 0;
178 } 163 }
179 return SocketAddress::GetAddrPort(&raw); 164 return SocketAddress::GetAddrPort(&raw);
180 } 165 }
181 166
182 167
183 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { 168 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) {
184 ASSERT(fd >= 0); 169 ASSERT(fd >= 0);
185 RawAddr raw; 170 RawAddr raw;
186 socklen_t size = sizeof(raw); 171 socklen_t size = sizeof(raw);
187 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 172 if (getpeername(fd, &raw.addr, &size)) {
188 getpeername(fd,
189 &raw.addr,
190 &size))) {
191 const int kBufferSize = 1024; 173 const int kBufferSize = 1024;
192 char error_buf[kBufferSize]; 174 char error_buf[kBufferSize];
193 Log::PrintErr("Error getpeername: %s\n", 175 Log::PrintErr("Error getpeername: %s\n",
194 strerror_r(errno, error_buf, kBufferSize)); 176 strerror_r(errno, error_buf, kBufferSize));
195 return NULL; 177 return NULL;
196 } 178 }
197 *port = SocketAddress::GetAddrPort(&raw); 179 *port = SocketAddress::GetAddrPort(&raw);
198 return new SocketAddress(&raw.addr); 180 return new SocketAddress(&raw.addr);
199 } 181 }
200 182
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 freeaddrinfo(info); 250 freeaddrinfo(info);
269 return addresses; 251 return addresses;
270 } 252 }
271 253
272 254
273 bool Socket::ReverseLookup(RawAddr addr, 255 bool Socket::ReverseLookup(RawAddr addr,
274 char* host, 256 char* host,
275 intptr_t host_len, 257 intptr_t host_len,
276 OSError** os_error) { 258 OSError** os_error) {
277 ASSERT(host_len >= NI_MAXHOST); 259 ASSERT(host_len >= NI_MAXHOST);
278 int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getnameinfo( 260 int status = getnameinfo(
279 &addr.addr, 261 &addr.addr,
280 SocketAddress::GetAddrLength(&addr), 262 SocketAddress::GetAddrLength(&addr),
281 host, 263 host,
282 host_len, 264 host_len,
283 NULL, 265 NULL,
284 0, 266 0,
285 NI_NAMEREQD)); 267 NI_NAMEREQD);
286 if (status != 0) { 268 if (status != 0) {
287 ASSERT(*os_error == NULL); 269 ASSERT(*os_error == NULL);
288 *os_error = new OSError(status, 270 *os_error = new OSError(status,
289 gai_strerror(status), 271 gai_strerror(status),
290 OSError::kGetAddressInfo); 272 OSError::kGetAddressInfo);
291 return false; 273 return false;
292 } 274 }
293 return true; 275 return true;
294 } 276 }
295 277
296 278
297 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { 279 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) {
298 int result; 280 int result;
299 if (type == SocketAddress::TYPE_IPV4) { 281 if (type == SocketAddress::TYPE_IPV4) {
300 result = inet_pton(AF_INET, address, &addr->in.sin_addr); 282 result = inet_pton(AF_INET, address, &addr->in.sin_addr);
301 } else { 283 } else {
302 ASSERT(type == SocketAddress::TYPE_IPV6); 284 ASSERT(type == SocketAddress::TYPE_IPV6);
303 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); 285 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr);
304 } 286 }
305 return result == 1; 287 return result == 1;
306 } 288 }
307 289
308 290
309 intptr_t Socket::CreateBindDatagram( 291 intptr_t Socket::CreateBindDatagram(
310 RawAddr* addr, intptr_t port, bool reuseAddress) { 292 RawAddr* addr, intptr_t port, bool reuseAddress) {
311 intptr_t fd; 293 intptr_t fd;
312 294
313 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket( 295 fd = socket(addr->addr.sa_family,
314 addr->addr.sa_family, 296 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
315 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 297 IPPROTO_UDP);
316 IPPROTO_UDP));
317 if (fd < 0) return -1; 298 if (fd < 0) return -1;
318 299
319 if (reuseAddress) { 300 if (reuseAddress) {
320 int optval = 1; 301 int optval = 1;
321 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 302 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
322 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
323 } 303 }
324 304
325 SocketAddress::SetAddrPort(addr, port); 305 SocketAddress::SetAddrPort(addr, port);
326 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 306 if (bind(fd, &addr->addr, SocketAddress::GetAddrLength(addr)) < 0) {
327 bind(fd, 307 TEMP_FAILURE_RETRY(close(fd));
328 &addr->addr,
329 SocketAddress::GetAddrLength(addr))) < 0) {
330 TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
331 return -1; 308 return -1;
332 } 309 }
333 return fd; 310 return fd;
334 } 311 }
335 312
336 313
337 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { 314 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
338 if (ifa->ifa_addr == NULL) { 315 if (ifa->ifa_addr == NULL) {
339 // OpenVPN's virtual device tun0. 316 // OpenVPN's virtual device tun0.
340 return false; 317 return false;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 return addresses; 361 return addresses;
385 } 362 }
386 363
387 364
388 intptr_t ServerSocket::CreateBindListen(RawAddr addr, 365 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
389 intptr_t port, 366 intptr_t port,
390 intptr_t backlog, 367 intptr_t backlog,
391 bool v6_only) { 368 bool v6_only) {
392 intptr_t fd; 369 intptr_t fd;
393 370
394 fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(socket( 371 fd = socket(addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
395 addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
396 if (fd < 0) return -1; 372 if (fd < 0) return -1;
397 373
398 int optval = 1; 374 int optval = 1;
399 TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 375 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
400 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
401 376
402 if (addr.ss.ss_family == AF_INET6) { 377 if (addr.ss.ss_family == AF_INET6) {
403 optval = v6_only ? 1 : 0; 378 optval = v6_only ? 1 : 0;
404 TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 379 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
405 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
406 } 380 }
407 381
408 SocketAddress::SetAddrPort(&addr, port); 382 SocketAddress::SetAddrPort(&addr, port);
409 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 383 if (bind(fd, &addr.addr, SocketAddress::GetAddrLength(&addr)) < 0) {
410 bind(fd, 384 VOID_TEMP_FAILURE_RETRY(close(fd));
411 &addr.addr,
412 SocketAddress::GetAddrLength(&addr))) < 0) {
413 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
414 return -1; 385 return -1;
415 } 386 }
416 387
417 // Test for invalid socket port 65535 (some browsers disallow it). 388 // Test for invalid socket port 65535 (some browsers disallow it).
418 if (port == 0 && Socket::GetPort(fd) == 65535) { 389 if (port == 0 && Socket::GetPort(fd) == 65535) {
419 // Don't close the socket until we have created a new socket, ensuring 390 // Don't close the socket until we have created a new socket, ensuring
420 // that we do not get the bad port number again. 391 // that we do not get the bad port number again.
421 intptr_t new_fd = CreateBindListen(addr, 0, backlog, v6_only); 392 intptr_t new_fd = CreateBindListen(addr, 0, backlog, v6_only);
422 int err = errno; 393 int err = errno;
423 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 394 VOID_TEMP_FAILURE_RETRY(close(fd));
424 errno = err; 395 errno = err;
425 return new_fd; 396 return new_fd;
426 } 397 }
427 398
428 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 399 if (listen(fd, backlog > 0 ? backlog : SOMAXCONN) != 0) {
429 listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { 400 VOID_TEMP_FAILURE_RETRY(close(fd));
430 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
431 return -1; 401 return -1;
432 } 402 }
433 403
434 return fd; 404 return fd;
435 } 405 }
436 406
437 407
438 static bool IsTemporaryAcceptError(int error) { 408 static bool IsTemporaryAcceptError(int error) {
439 // On Linux a number of protocol errors should be treated as EAGAIN. 409 // On Linux a number of protocol errors should be treated as EAGAIN.
440 // These are the ones for TCP/IP. 410 // These are the ones for TCP/IP.
441 return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) || 411 return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) ||
442 (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) || 412 (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) ||
443 (error == EHOSTUNREACH) || (error == EOPNOTSUPP) || 413 (error == EHOSTUNREACH) || (error == EOPNOTSUPP) ||
444 (error == ENETUNREACH); 414 (error == ENETUNREACH);
445 } 415 }
446 416
447 417
448 intptr_t ServerSocket::Accept(intptr_t fd) { 418 intptr_t ServerSocket::Accept(intptr_t fd) {
449 intptr_t socket; 419 intptr_t socket;
450 struct sockaddr clientaddr; 420 struct sockaddr clientaddr;
451 socklen_t addrlen = sizeof(clientaddr); 421 socklen_t addrlen = sizeof(clientaddr);
452 socket = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(accept4( 422 socket = TEMP_FAILURE_RETRY(accept4(
453 fd, &clientaddr, &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC)); 423 fd, &clientaddr, &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC));
454 if (socket == -1) { 424 if (socket == -1) {
455 if (IsTemporaryAcceptError(errno)) { 425 if (IsTemporaryAcceptError(errno)) {
456 // We need to signal to the caller that this is actually not an 426 // We need to signal to the caller that this is actually not an
457 // error. We got woken up from the poll on the listening socket, 427 // error. We got woken up from the poll on the listening socket,
458 // but there is no connection ready to be accepted. 428 // but there is no connection ready to be accepted.
459 ASSERT(kTemporaryFailure != -1); 429 ASSERT(kTemporaryFailure != -1);
460 socket = kTemporaryFailure; 430 socket = kTemporaryFailure;
461 } 431 }
462 } 432 }
463 return socket; 433 return socket;
464 } 434 }
465 435
466 436
467 void Socket::Close(intptr_t fd) { 437 void Socket::Close(intptr_t fd) {
468 ASSERT(fd >= 0); 438 ASSERT(fd >= 0);
469 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd)); 439 int err = TEMP_FAILURE_RETRY(close(fd));
470 if (err != 0) { 440 if (err != 0) {
471 const int kBufferSize = 1024; 441 const int kBufferSize = 1024;
472 char error_buf[kBufferSize]; 442 char error_buf[kBufferSize];
473 Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize)); 443 Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize));
474 } 444 }
475 } 445 }
476 446
477 447
478 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) { 448 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) {
479 int on; 449 int on;
480 socklen_t len = sizeof(on); 450 socklen_t len = sizeof(on);
481 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd, 451 int err = getsockopt(
482 IPPROTO_TCP, 452 fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<void *>(&on), &len);
483 TCP_NODELAY,
484 reinterpret_cast<void *>(&on),
485 &len));
486 if (err == 0) { 453 if (err == 0) {
487 *enabled = on == 1; 454 *enabled = on == 1;
488 } 455 }
489 return err == 0; 456 return err == 0;
490 } 457 }
491 458
492 459
493 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { 460 bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
494 int on = enabled ? 1 : 0; 461 int on = enabled ? 1 : 0;
495 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd, 462 return setsockopt(fd,
496 IPPROTO_TCP, 463 IPPROTO_TCP,
497 TCP_NODELAY, 464 TCP_NODELAY,
498 reinterpret_cast<char *>(&on), 465 reinterpret_cast<char *>(&on),
499 sizeof(on))) == 0; 466 sizeof(on)) == 0;
500 } 467 }
501 468
502 469
503 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) { 470 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) {
504 uint8_t on; 471 uint8_t on;
505 socklen_t len = sizeof(on); 472 socklen_t len = sizeof(on);
506 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 473 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
507 int optname = protocol == SocketAddress::TYPE_IPV4 474 int optname = protocol == SocketAddress::TYPE_IPV4
508 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; 475 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP;
509 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd, 476 if (getsockopt(
510 level, 477 fd, level, optname, reinterpret_cast<char *>(&on), &len) == 0) {
511 optname,
512 reinterpret_cast<char *>(&on),
513 &len)) == 0) {
514 *enabled = (on == 1); 478 *enabled = (on == 1);
515 return true; 479 return true;
516 } 480 }
517 return false; 481 return false;
518 } 482 }
519 483
520 484
521 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) { 485 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) {
522 int on = enabled ? 1 : 0; 486 int on = enabled ? 1 : 0;
523 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 487 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
524 int optname = protocol == SocketAddress::TYPE_IPV4 488 int optname = protocol == SocketAddress::TYPE_IPV4
525 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; 489 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP;
526 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd, 490 return setsockopt(
527 level, 491 fd, level, optname, reinterpret_cast<char *>(&on), sizeof(on)) == 0;
528 optname,
529 reinterpret_cast<char *>(&on),
530 sizeof(on))) == 0;
531 } 492 }
532 493
533 494
534 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { 495 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
535 uint8_t v; 496 uint8_t v;
536 socklen_t len = sizeof(v); 497 socklen_t len = sizeof(v);
537 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 498 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
538 int optname = protocol == SocketAddress::TYPE_IPV4 499 int optname = protocol == SocketAddress::TYPE_IPV4
539 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; 500 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS;
540 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd, 501 if (getsockopt(fd, level, optname, reinterpret_cast<char *>(&v), &len) == 0) {
541 level,
542 optname,
543 reinterpret_cast<char *>(&v),
544 &len)) == 0) {
545 *value = v; 502 *value = v;
546 return true; 503 return true;
547 } 504 }
548 return false; 505 return false;
549 } 506 }
550 507
551 508
552 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { 509 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
553 int v = value; 510 int v = value;
554 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 511 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
555 int optname = protocol == SocketAddress::TYPE_IPV4 512 int optname = protocol == SocketAddress::TYPE_IPV4
556 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; 513 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS;
557 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd, 514 return setsockopt(
558 level, 515 fd, level, optname, reinterpret_cast<char *>(&v), sizeof(v)) == 0;
559 optname,
560 reinterpret_cast<char *>(&v),
561 sizeof(v))) == 0;
562 } 516 }
563 517
564 518
565 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) { 519 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) {
566 int on; 520 int on;
567 socklen_t len = sizeof(on); 521 socklen_t len = sizeof(on);
568 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd, 522 int err = getsockopt(
569 SOL_SOCKET, 523 fd, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<char *>(&on), &len);
570 SO_BROADCAST,
571 reinterpret_cast<char *>(&on),
572 &len));
573 if (err == 0) { 524 if (err == 0) {
574 *enabled = on == 1; 525 *enabled = on == 1;
575 } 526 }
576 return err == 0; 527 return err == 0;
577 } 528 }
578 529
579 530
580 bool Socket::SetBroadcast(intptr_t fd, bool enabled) { 531 bool Socket::SetBroadcast(intptr_t fd, bool enabled) {
581 int on = enabled ? 1 : 0; 532 int on = enabled ? 1 : 0;
582 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd, 533 return setsockopt(fd,
583 SOL_SOCKET, 534 SOL_SOCKET,
584 SO_BROADCAST, 535 SO_BROADCAST,
585 reinterpret_cast<char *>(&on), 536 reinterpret_cast<char *>(&on),
586 sizeof(on))) == 0; 537 sizeof(on)) == 0;
587 } 538 }
588 539
589 540
590 bool Socket::JoinMulticast( 541 bool Socket::JoinMulticast(
591 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) { 542 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) {
592 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 543 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
593 struct group_req mreq; 544 struct group_req mreq;
594 mreq.gr_interface = interfaceIndex; 545 mreq.gr_interface = interfaceIndex;
595 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr)); 546 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr));
596 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt( 547 return setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq)) == 0;
597 fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0;
598 } 548 }
599 549
600 550
601 bool Socket::LeaveMulticast( 551 bool Socket::LeaveMulticast(
602 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) { 552 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) {
603 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 553 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
604 struct group_req mreq; 554 struct group_req mreq;
605 mreq.gr_interface = interfaceIndex; 555 mreq.gr_interface = interfaceIndex;
606 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr)); 556 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr));
607 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt( 557 return setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq)) == 0;
608 fd, proto, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0;
609 } 558 }
610 559
611 } // namespace bin 560 } // namespace bin
612 } // namespace dart 561 } // namespace dart
613 562
614 #endif // defined(TARGET_OS_LINUX) 563 #endif // defined(TARGET_OS_LINUX)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698