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

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

Powered by Google App Engine
This is Rietveld 408576698