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

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

Issue 2495003003: Adds some error handling to the socket implementation. (Closed)
Patch Set: Add perror calls for fcntl Created 4 years, 1 month 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
« no previous file with comments | « runtime/bin/fdutils_macos.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 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "platform/globals.h" 7 #include "platform/globals.h"
8 #if defined(TARGET_OS_ANDROID) 8 #if defined(TARGET_OS_ANDROID)
9 9
10 #include "bin/socket.h" 10 #include "bin/socket.h"
11 #include "bin/socket_android.h" 11 #include "bin/socket_android.h"
12 12
13 #include <errno.h> // NOLINT 13 #include <errno.h> // NOLINT
14 #include <netinet/tcp.h> // NOLINT 14 #include <netinet/tcp.h> // NOLINT
15 #include <stdio.h> // NOLINT 15 #include <stdio.h> // NOLINT
16 #include <stdlib.h> // NOLINT 16 #include <stdlib.h> // NOLINT
17 #include <string.h> // NOLINT 17 #include <string.h> // NOLINT
18 #include <sys/stat.h> // NOLINT 18 #include <sys/stat.h> // NOLINT
19 #include <unistd.h> // NOLINT 19 #include <unistd.h> // NOLINT
20 20
21 #include "bin/fdutils.h" 21 #include "bin/fdutils.h"
22 #include "bin/file.h" 22 #include "bin/file.h"
23 #include "platform/signal_blocker.h" 23 #include "platform/signal_blocker.h"
24 24
25 namespace dart { 25 namespace dart {
26 namespace bin { 26 namespace bin {
27 27
28 static void SaveErrorAndClose(intptr_t fd) {
29 int err = errno;
30 VOID_TEMP_FAILURE_RETRY(close(fd));
31 errno = err;
32 }
33
34
28 SocketAddress::SocketAddress(struct sockaddr* sa) { 35 SocketAddress::SocketAddress(struct sockaddr* sa) {
29 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); 36 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
30 if (!Socket::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), as_string_, 37 if (!Socket::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), as_string_,
31 INET6_ADDRSTRLEN)) { 38 INET6_ADDRSTRLEN)) {
32 as_string_[0] = 0; 39 as_string_[0] = 0;
33 } 40 }
34 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa)); 41 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa));
35 memmove(reinterpret_cast<void*>(&addr_), sa, salen); 42 memmove(reinterpret_cast<void*>(&addr_), sa, salen);
36 } 43 }
37 44
(...skipping 10 matching lines...) Expand all
48 return true; 55 return true;
49 } 56 }
50 57
51 58
52 static intptr_t Create(const RawAddr& addr) { 59 static intptr_t Create(const RawAddr& addr) {
53 intptr_t fd; 60 intptr_t fd;
54 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0)); 61 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0));
55 if (fd < 0) { 62 if (fd < 0) {
56 return -1; 63 return -1;
57 } 64 }
58 FDUtils::SetCloseOnExec(fd); 65 if (!FDUtils::SetCloseOnExec(fd)) {
66 SaveErrorAndClose(fd);
67 return -1;
68 }
59 return fd; 69 return fd;
60 } 70 }
61 71
62 72
63 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { 73 static intptr_t Connect(intptr_t fd, const RawAddr& addr) {
64 intptr_t result = TEMP_FAILURE_RETRY( 74 intptr_t result = TEMP_FAILURE_RETRY(
65 connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); 75 connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr)));
66 if ((result == 0) || (errno == EINPROGRESS)) { 76 if ((result == 0) || (errno == EINPROGRESS)) {
67 return fd; 77 return fd;
68 } 78 }
69 VOID_TEMP_FAILURE_RETRY(close(fd)); 79 SaveErrorAndClose(fd);
70 return -1; 80 return -1;
71 } 81 }
72 82
73 83
74 intptr_t Socket::CreateConnect(const RawAddr& addr) { 84 intptr_t Socket::CreateConnect(const RawAddr& addr) {
75 intptr_t fd = Create(addr); 85 intptr_t fd = Create(addr);
76 if (fd < 0) { 86 if (fd < 0) {
77 return fd; 87 return fd;
78 } 88 }
79 89
80 FDUtils::SetNonBlocking(fd); 90 if (!FDUtils::SetNonBlocking(fd)) {
81 91 SaveErrorAndClose(fd);
92 return -1;
93 }
82 return Connect(fd, addr); 94 return Connect(fd, addr);
83 } 95 }
84 96
85 97
86 intptr_t Socket::CreateBindConnect(const RawAddr& addr, 98 intptr_t Socket::CreateBindConnect(const RawAddr& addr,
87 const RawAddr& source_addr) { 99 const RawAddr& source_addr) {
88 intptr_t fd = Create(addr); 100 intptr_t fd = Create(addr);
89 if (fd < 0) { 101 if (fd < 0) {
90 return fd; 102 return fd;
91 } 103 }
92 104
93 intptr_t result = TEMP_FAILURE_RETRY( 105 intptr_t result = TEMP_FAILURE_RETRY(
94 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); 106 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr)));
95 if ((result != 0) && (errno != EINPROGRESS)) { 107 if ((result != 0) && (errno != EINPROGRESS)) {
96 VOID_TEMP_FAILURE_RETRY(close(fd)); 108 SaveErrorAndClose(fd);
97 return -1; 109 return -1;
98 } 110 }
99 111
100 return Connect(fd, addr); 112 return Connect(fd, addr);
101 } 113 }
102 114
103 115
104 bool Socket::IsBindError(intptr_t error_number) { 116 bool Socket::IsBindError(intptr_t error_number) {
105 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || 117 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
106 error_number == EINVAL; 118 error_number == EINVAL;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 315
304 316
305 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { 317 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) {
306 intptr_t fd; 318 intptr_t fd;
307 319
308 fd = NO_RETRY_EXPECTED(socket(addr.addr.sa_family, SOCK_DGRAM, IPPROTO_UDP)); 320 fd = NO_RETRY_EXPECTED(socket(addr.addr.sa_family, SOCK_DGRAM, IPPROTO_UDP));
309 if (fd < 0) { 321 if (fd < 0) {
310 return -1; 322 return -1;
311 } 323 }
312 324
313 FDUtils::SetCloseOnExec(fd); 325 if (!FDUtils::SetCloseOnExec(fd)) {
326 SaveErrorAndClose(fd);
327 return -1;
328 }
314 329
315 if (reuseAddress) { 330 if (reuseAddress) {
316 int optval = 1; 331 int optval = 1;
317 VOID_NO_RETRY_EXPECTED( 332 VOID_NO_RETRY_EXPECTED(
318 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); 333 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
319 } 334 }
320 335
321 if (NO_RETRY_EXPECTED( 336 if (NO_RETRY_EXPECTED(
322 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { 337 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) {
323 VOID_TEMP_FAILURE_RETRY(close(fd)); 338 SaveErrorAndClose(fd);
324 return -1; 339 return -1;
325 } 340 }
326 341
327 FDUtils::SetNonBlocking(fd); 342 if (!FDUtils::SetNonBlocking(fd)) {
343 SaveErrorAndClose(fd);
344 return -1;
345 }
328 return fd; 346 return fd;
329 } 347 }
330 348
331 349
332 bool Socket::ListInterfacesSupported() { 350 bool Socket::ListInterfacesSupported() {
333 return false; 351 return false;
334 } 352 }
335 353
336 354
337 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( 355 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
(...skipping 13 matching lines...) Expand all
351 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, 369 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr,
352 intptr_t backlog, 370 intptr_t backlog,
353 bool v6_only) { 371 bool v6_only) {
354 intptr_t fd; 372 intptr_t fd;
355 373
356 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0)); 374 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0));
357 if (fd < 0) { 375 if (fd < 0) {
358 return -1; 376 return -1;
359 } 377 }
360 378
361 FDUtils::SetCloseOnExec(fd); 379 if (!FDUtils::SetCloseOnExec(fd)) {
380 SaveErrorAndClose(fd);
381 return -1;
382 }
362 383
363 int optval = 1; 384 int optval = 1;
364 VOID_NO_RETRY_EXPECTED( 385 VOID_NO_RETRY_EXPECTED(
365 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); 386 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
366 387
367 if (addr.ss.ss_family == AF_INET6) { 388 if (addr.ss.ss_family == AF_INET6) {
368 optval = v6_only ? 1 : 0; 389 optval = v6_only ? 1 : 0;
369 VOID_NO_RETRY_EXPECTED( 390 VOID_NO_RETRY_EXPECTED(
370 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))); 391 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
371 } 392 }
372 393
373 if (NO_RETRY_EXPECTED( 394 if (NO_RETRY_EXPECTED(
374 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { 395 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) {
375 VOID_TEMP_FAILURE_RETRY(close(fd)); 396 SaveErrorAndClose(fd);
376 return -1; 397 return -1;
377 } 398 }
378 399
379 // Test for invalid socket port 65535 (some browsers disallow it). 400 // Test for invalid socket port 65535 (some browsers disallow it).
380 if ((SocketAddress::GetAddrPort(addr)) == 0 && 401 if ((SocketAddress::GetAddrPort(addr)) == 0 &&
381 (Socket::GetPort(fd) == 65535)) { 402 (Socket::GetPort(fd) == 65535)) {
382 // Don't close the socket until we have created a new socket, ensuring 403 // Don't close the socket until we have created a new socket, ensuring
383 // that we do not get the bad port number again. 404 // that we do not get the bad port number again.
384 intptr_t new_fd = CreateBindListen(addr, backlog, v6_only); 405 intptr_t new_fd = CreateBindListen(addr, backlog, v6_only);
385 int err = errno; 406 SaveErrorAndClose(fd);
386 VOID_TEMP_FAILURE_RETRY(close(fd));
387 errno = err;
388 return new_fd; 407 return new_fd;
389 } 408 }
390 409
391 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { 410 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
392 VOID_TEMP_FAILURE_RETRY(close(fd)); 411 SaveErrorAndClose(fd);
393 return -1; 412 return -1;
394 } 413 }
395 414
396 FDUtils::SetNonBlocking(fd); 415 if (!FDUtils::SetNonBlocking(fd)) {
416 SaveErrorAndClose(fd);
417 return -1;
418 }
397 return fd; 419 return fd;
398 } 420 }
399 421
400 422
401 bool ServerSocket::StartAccept(intptr_t fd) { 423 bool ServerSocket::StartAccept(intptr_t fd) {
402 USE(fd); 424 USE(fd);
403 return true; 425 return true;
404 } 426 }
405 427
406 428
(...skipping 14 matching lines...) Expand all
421 socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen)); 443 socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen));
422 if (socket == -1) { 444 if (socket == -1) {
423 if (IsTemporaryAcceptError(errno)) { 445 if (IsTemporaryAcceptError(errno)) {
424 // We need to signal to the caller that this is actually not an 446 // We need to signal to the caller that this is actually not an
425 // error. We got woken up from the poll on the listening socket, 447 // error. We got woken up from the poll on the listening socket,
426 // but there is no connection ready to be accepted. 448 // but there is no connection ready to be accepted.
427 ASSERT(kTemporaryFailure != -1); 449 ASSERT(kTemporaryFailure != -1);
428 socket = kTemporaryFailure; 450 socket = kTemporaryFailure;
429 } 451 }
430 } else { 452 } else {
431 FDUtils::SetCloseOnExec(socket); 453 if (!FDUtils::SetCloseOnExec(socket)) {
432 FDUtils::SetNonBlocking(socket); 454 SaveErrorAndClose(socket);
455 return -1;
456 }
457 if (!FDUtils::SetNonBlocking(socket)) {
458 SaveErrorAndClose(socket);
459 return -1;
460 }
433 } 461 }
434 return socket; 462 return socket;
435 } 463 }
436 464
437 465
438 void Socket::Close(intptr_t fd) { 466 void Socket::Close(intptr_t fd) {
439 ASSERT(fd >= 0); 467 ASSERT(fd >= 0);
440 VOID_TEMP_FAILURE_RETRY(close(fd)); 468 VOID_TEMP_FAILURE_RETRY(close(fd));
441 } 469 }
442 470
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, 583 return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq,
556 sizeof(mreq))) == 0; 584 sizeof(mreq))) == 0;
557 } 585 }
558 586
559 } // namespace bin 587 } // namespace bin
560 } // namespace dart 588 } // namespace dart
561 589
562 #endif // defined(TARGET_OS_ANDROID) 590 #endif // defined(TARGET_OS_ANDROID)
563 591
564 #endif // !defined(DART_IO_DISABLED) 592 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/fdutils_macos.cc ('k') | runtime/bin/socket_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698