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

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

Powered by Google App Engine
This is Rietveld 408576698