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

Side by Side Diff: runtime/bin/socket_macos.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_linux.cc ('k') | runtime/bin/utils_android.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_MACOS) 6 #if defined(TARGET_OS_MACOS)
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 Mac OS. 55 // Nothing to do on Mac OS.
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_message[kBufferSize]; 66 char error_message[kBufferSize];
66 strerror_r(errno, error_message, kBufferSize); 67 strerror_r(errno, error_message, kBufferSize);
67 Log::PrintErr("Error Create: %s\n", error_message); 68 Log::PrintErr("Error Create: %s\n", error_message);
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_message[kBufferSize]; 178 char error_message[kBufferSize];
176 strerror_r(errno, error_message, kBufferSize); 179 strerror_r(errno, error_message, kBufferSize);
177 Log::PrintErr("Error getsockname: %s\n", error_message); 180 Log::PrintErr("Error getsockname: %s\n", error_message);
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_message[kBufferSize]; 196 char error_message[kBufferSize];
194 strerror_r(errno, error_message, kBufferSize); 197 strerror_r(errno, error_message, kBufferSize);
195 Log::PrintErr("Error getpeername: %s\n", error_message); 198 Log::PrintErr("Error getpeername: %s\n", error_message);
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 VOID_TEMP_FAILURE_RETRY(close(fd)); 327 VOID_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 VOID_TEMP_FAILURE_RETRY( 400 VOID_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 VOID_TEMP_FAILURE_RETRY( 405 VOID_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 intptr_t ServerSocket::Accept(intptr_t fd) { 440 intptr_t ServerSocket::Accept(intptr_t fd) {
436 intptr_t socket; 441 intptr_t socket;
437 struct sockaddr clientaddr; 442 struct sockaddr clientaddr;
438 socklen_t addrlen = sizeof(clientaddr); 443 socklen_t addrlen = sizeof(clientaddr);
439 socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen)); 444 socket = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(accept(fd, &clientaddr, &addrlen));
440 if (socket == -1) { 445 if (socket == -1) {
441 if (errno == EAGAIN) { 446 if (errno == EAGAIN) {
442 // We need to signal to the caller that this is actually not an 447 // We need to signal to the caller that this is actually not an
443 // error. We got woken up from the poll on the listening socket, 448 // error. We got woken up from the poll on the listening socket,
444 // but there is no connection ready to be accepted. 449 // but there is no connection ready to be accepted.
445 ASSERT(kTemporaryFailure != -1); 450 ASSERT(kTemporaryFailure != -1);
446 socket = kTemporaryFailure; 451 socket = kTemporaryFailure;
447 } 452 }
448 } else { 453 } else {
449 Socket::SetNonBlocking(socket); 454 Socket::SetNonBlocking(socket);
450 } 455 }
451 return socket; 456 return socket;
452 } 457 }
453 458
454 459
455 void Socket::Close(intptr_t fd) { 460 void Socket::Close(intptr_t fd) {
456 ASSERT(fd >= 0); 461 ASSERT(fd >= 0);
457 int err = TEMP_FAILURE_RETRY(close(fd)); 462 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fd));
458 if (err != 0) { 463 if (err != 0) {
459 const int kBufferSize = 1024; 464 const int kBufferSize = 1024;
460 char error_message[kBufferSize]; 465 char error_message[kBufferSize];
461 strerror_r(errno, error_message, kBufferSize); 466 strerror_r(errno, error_message, kBufferSize);
462 Log::PrintErr("%s\n", error_message); 467 Log::PrintErr("%s\n", error_message);
463 } 468 }
464 } 469 }
465 470
466 471
467 bool Socket::SetNonBlocking(intptr_t fd) { 472 bool Socket::SetNonBlocking(intptr_t fd) {
468 return FDUtils::SetNonBlocking(fd); 473 return FDUtils::SetNonBlocking(fd);
469 } 474 }
470 475
471 476
472 bool Socket::SetBlocking(intptr_t fd) { 477 bool Socket::SetBlocking(intptr_t fd) {
473 return FDUtils::SetBlocking(fd); 478 return FDUtils::SetBlocking(fd);
474 } 479 }
475 480
476 481
477 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) { 482 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) {
478 int on; 483 int on;
479 socklen_t len = sizeof(on); 484 socklen_t len = sizeof(on);
480 int err = TEMP_FAILURE_RETRY(getsockopt(fd, 485 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd,
481 IPPROTO_TCP, 486 IPPROTO_TCP,
482 TCP_NODELAY, 487 TCP_NODELAY,
483 reinterpret_cast<void *>(&on), 488 reinterpret_cast<void *>(&on),
484 &len)); 489 &len));
485 if (err == 0) { 490 if (err == 0) {
486 *enabled = on == 1; 491 *enabled = on == 1;
487 } 492 }
488 return err == 0; 493 return err == 0;
489 } 494 }
490 495
491 496
492 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { 497 bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
493 int on = enabled ? 1 : 0; 498 int on = enabled ? 1 : 0;
494 return TEMP_FAILURE_RETRY(setsockopt(fd, 499 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd,
495 IPPROTO_TCP, 500 IPPROTO_TCP,
496 TCP_NODELAY, 501 TCP_NODELAY,
497 reinterpret_cast<char *>(&on), 502 reinterpret_cast<char *>(&on),
498 sizeof(on))) == 0; 503 sizeof(on))) == 0;
499 } 504 }
500 505
501 506
502 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) { 507 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) {
503 uint8_t on; 508 uint8_t on;
504 socklen_t len = sizeof(on); 509 socklen_t len = sizeof(on);
505 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 510 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
506 int optname = protocol == SocketAddress::TYPE_IPV4 511 int optname = protocol == SocketAddress::TYPE_IPV4
507 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; 512 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP;
508 if (TEMP_FAILURE_RETRY(getsockopt(fd, 513 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd,
509 level, 514 level,
510 optname, 515 optname,
511 reinterpret_cast<char *>(&on), 516 reinterpret_cast<char *>(&on),
512 &len)) == 0) { 517 &len)) == 0) {
513 *enabled = (on == 1); 518 *enabled = (on == 1);
514 return true; 519 return true;
515 } 520 }
516 return false; 521 return false;
517 } 522 }
518 523
519 524
520 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) { 525 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) {
521 u_int on = enabled ? 1 : 0; 526 u_int on = enabled ? 1 : 0;
522 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 527 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
523 int optname = protocol == SocketAddress::TYPE_IPV4 528 int optname = protocol == SocketAddress::TYPE_IPV4
524 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; 529 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP;
525 return TEMP_FAILURE_RETRY(setsockopt(fd, 530 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd,
526 level, 531 level,
527 optname, 532 optname,
528 reinterpret_cast<char *>(&on), 533 reinterpret_cast<char *>(&on),
529 sizeof(on))) == 0; 534 sizeof(on))) == 0;
530 } 535 }
531 536
532 537
533 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { 538 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
534 uint8_t v; 539 uint8_t v;
535 socklen_t len = sizeof(v); 540 socklen_t len = sizeof(v);
536 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 541 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
537 int optname = protocol == SocketAddress::TYPE_IPV4 542 int optname = protocol == SocketAddress::TYPE_IPV4
538 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; 543 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS;
539 if (TEMP_FAILURE_RETRY(getsockopt(fd, 544 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd,
540 level, 545 level,
541 optname, 546 optname,
542 reinterpret_cast<char *>(&v), 547 reinterpret_cast<char *>(&v),
543 &len)) == 0) { 548 &len)) == 0) {
544 *value = v; 549 *value = v;
545 return true; 550 return true;
546 } 551 }
547 return false; 552 return false;
548 } 553 }
549 554
550 555
551 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { 556 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
552 int v = value; 557 int v = value;
553 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 558 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
554 int optname = protocol == SocketAddress::TYPE_IPV4 559 int optname = protocol == SocketAddress::TYPE_IPV4
555 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; 560 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS;
556 return TEMP_FAILURE_RETRY(setsockopt(fd, 561 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd,
557 level, 562 level,
558 optname, 563 optname,
559 reinterpret_cast<char *>(&v), 564 reinterpret_cast<char *>(&v),
560 sizeof(v))) == 0; 565 sizeof(v))) == 0;
561 } 566 }
562 567
563 568
564 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) { 569 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) {
565 int on; 570 int on;
566 socklen_t len = sizeof(on); 571 socklen_t len = sizeof(on);
567 int err = TEMP_FAILURE_RETRY(getsockopt(fd, 572 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(getsockopt(fd,
568 SOL_SOCKET, 573 SOL_SOCKET,
569 SO_BROADCAST, 574 SO_BROADCAST,
570 reinterpret_cast<char *>(&on), 575 reinterpret_cast<char *>(&on),
571 &len)); 576 &len));
572 if (err == 0) { 577 if (err == 0) {
573 *enabled = on == 1; 578 *enabled = on == 1;
574 } 579 }
575 return err == 0; 580 return err == 0;
576 } 581 }
577 582
578 583
579 bool Socket::SetBroadcast(intptr_t fd, bool enabled) { 584 bool Socket::SetBroadcast(intptr_t fd, bool enabled) {
580 int on = enabled ? 1 : 0; 585 int on = enabled ? 1 : 0;
581 return TEMP_FAILURE_RETRY(setsockopt(fd, 586 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(fd,
582 SOL_SOCKET, 587 SOL_SOCKET,
583 SO_BROADCAST, 588 SO_BROADCAST,
584 reinterpret_cast<char *>(&on), 589 reinterpret_cast<char *>(&on),
585 sizeof(on))) == 0; 590 sizeof(on))) == 0;
586 } 591 }
587 592
588 593
589 static bool JoinOrLeaveMulticast(intptr_t fd, 594 static bool JoinOrLeaveMulticast(intptr_t fd,
590 RawAddr* addr, 595 RawAddr* addr,
591 RawAddr* interface, 596 RawAddr* interface,
592 int interfaceIndex, 597 int interfaceIndex,
593 bool join) { 598 bool join) {
594 if (addr->addr.sa_family == AF_INET) { 599 if (addr->addr.sa_family == AF_INET) {
595 ASSERT(interface->addr.sa_family == AF_INET); 600 ASSERT(interface->addr.sa_family == AF_INET);
596 struct ip_mreq mreq; 601 struct ip_mreq mreq;
597 memmove(&mreq.imr_multiaddr, 602 memmove(&mreq.imr_multiaddr,
598 &addr->in.sin_addr, 603 &addr->in.sin_addr,
599 SocketAddress::GetAddrLength(addr)); 604 SocketAddress::GetAddrLength(addr));
600 memmove(&mreq.imr_interface, 605 memmove(&mreq.imr_interface,
601 &interface->in.sin_addr, 606 &interface->in.sin_addr,
602 SocketAddress::GetAddrLength(interface)); 607 SocketAddress::GetAddrLength(interface));
603 if (join) { 608 if (join) {
604 return TEMP_FAILURE_RETRY(setsockopt( 609 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(
605 fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) == 0; 610 fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) == 0;
606 } else { 611 } else {
607 return TEMP_FAILURE_RETRY(setsockopt( 612 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(
608 fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq))) == 0; 613 fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq))) == 0;
609 } 614 }
610 } else { 615 } else {
611 ASSERT(addr->addr.sa_family == AF_INET6); 616 ASSERT(addr->addr.sa_family == AF_INET6);
612 struct ipv6_mreq mreq; 617 struct ipv6_mreq mreq;
613 memmove(&mreq.ipv6mr_multiaddr, 618 memmove(&mreq.ipv6mr_multiaddr,
614 &addr->in6.sin6_addr, 619 &addr->in6.sin6_addr,
615 SocketAddress::GetAddrLength(addr)); 620 SocketAddress::GetAddrLength(addr));
616 mreq.ipv6mr_interface = interfaceIndex; 621 mreq.ipv6mr_interface = interfaceIndex;
617 if (join) { 622 if (join) {
618 return TEMP_FAILURE_RETRY(setsockopt( 623 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(
619 fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; 624 fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq))) == 0;
620 } else { 625 } else {
621 return TEMP_FAILURE_RETRY(setsockopt( 626 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(
622 fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0; 627 fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0;
623 } 628 }
624 } 629 }
625 } 630 }
626 631
627 bool Socket::JoinMulticast( 632 bool Socket::JoinMulticast(
628 intptr_t fd, RawAddr* addr, RawAddr* interface, int interfaceIndex) { 633 intptr_t fd, RawAddr* addr, RawAddr* interface, int interfaceIndex) {
629 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true); 634 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true);
630 if (addr->addr.sa_family == AF_INET) { 635 if (addr->addr.sa_family == AF_INET) {
631 ASSERT(interface->addr.sa_family == AF_INET); 636 ASSERT(interface->addr.sa_family == AF_INET);
632 struct ip_mreq mreq; 637 struct ip_mreq mreq;
633 memmove(&mreq.imr_multiaddr, 638 memmove(&mreq.imr_multiaddr,
634 &addr->in.sin_addr, 639 &addr->in.sin_addr,
635 SocketAddress::GetAddrLength(addr)); 640 SocketAddress::GetAddrLength(addr));
636 memmove(&mreq.imr_interface, 641 memmove(&mreq.imr_interface,
637 &interface->in.sin_addr, 642 &interface->in.sin_addr,
638 SocketAddress::GetAddrLength(interface)); 643 SocketAddress::GetAddrLength(interface));
639 return TEMP_FAILURE_RETRY(setsockopt( 644 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(
640 fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) == 0; 645 fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) == 0;
641 } else { 646 } else {
642 ASSERT(addr->addr.sa_family == AF_INET6); 647 ASSERT(addr->addr.sa_family == AF_INET6);
643 ASSERT(interface->addr.sa_family == AF_INET6); 648 ASSERT(interface->addr.sa_family == AF_INET6);
644 struct ipv6_mreq mreq; 649 struct ipv6_mreq mreq;
645 memmove(&mreq.ipv6mr_multiaddr, 650 memmove(&mreq.ipv6mr_multiaddr,
646 &addr->in6.sin6_addr, 651 &addr->in6.sin6_addr,
647 SocketAddress::GetAddrLength(addr)); 652 SocketAddress::GetAddrLength(addr));
648 mreq.ipv6mr_interface = interfaceIndex; 653 mreq.ipv6mr_interface = interfaceIndex;
649 return TEMP_FAILURE_RETRY(setsockopt( 654 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(setsockopt(
650 fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; 655 fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq))) == 0;
651 } 656 }
652 } 657 }
653 658
654 659
655 bool Socket::LeaveMulticast( 660 bool Socket::LeaveMulticast(
656 intptr_t fd, RawAddr* addr, RawAddr* interface, int interfaceIndex) { 661 intptr_t fd, RawAddr* addr, RawAddr* interface, int interfaceIndex) {
657 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false); 662 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false);
658 } 663 }
659 664
660 } // namespace bin 665 } // namespace bin
661 } // namespace dart 666 } // namespace dart
662 667
663 #endif // defined(TARGET_OS_MACOS) 668 #endif // defined(TARGET_OS_MACOS)
OLDNEW
« no previous file with comments | « runtime/bin/socket_linux.cc ('k') | runtime/bin/utils_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698