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

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

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