| OLD | NEW | 
|---|
| 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) { | 28 static void FDUtils::SaveErrorAndClose(intptr_t fd) { | 
| 29   int err = errno; | 29   int err = errno; | 
| 30   VOID_TEMP_FAILURE_RETRY(close(fd)); | 30   VOID_TEMP_FAILURE_RETRY(close(fd)); | 
| 31   errno = err; | 31   errno = err; | 
| 32 } | 32 } | 
| 33 | 33 | 
| 34 | 34 | 
| 35 SocketAddress::SocketAddress(struct sockaddr* sa) { | 35 SocketAddress::SocketAddress(struct sockaddr* sa) { | 
| 36   ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); | 36   ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); | 
| 37   if (!Socket::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), as_string_, | 37   if (!Socket::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), as_string_, | 
| 38                                     INET6_ADDRSTRLEN)) { | 38                                     INET6_ADDRSTRLEN)) { | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 56 } | 56 } | 
| 57 | 57 | 
| 58 | 58 | 
| 59 static intptr_t Create(const RawAddr& addr) { | 59 static intptr_t Create(const RawAddr& addr) { | 
| 60   intptr_t fd; | 60   intptr_t fd; | 
| 61   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)); | 
| 62   if (fd < 0) { | 62   if (fd < 0) { | 
| 63     return -1; | 63     return -1; | 
| 64   } | 64   } | 
| 65   if (!FDUtils::SetCloseOnExec(fd)) { | 65   if (!FDUtils::SetCloseOnExec(fd)) { | 
| 66     SaveErrorAndClose(fd); | 66     FDUtils::SaveErrorAndClose(fd); | 
| 67     return -1; | 67     return -1; | 
| 68   } | 68   } | 
| 69   return fd; | 69   return fd; | 
| 70 } | 70 } | 
| 71 | 71 | 
| 72 | 72 | 
| 73 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { | 73 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { | 
| 74   intptr_t result = TEMP_FAILURE_RETRY( | 74   intptr_t result = TEMP_FAILURE_RETRY( | 
| 75       connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); | 75       connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); | 
| 76   if ((result == 0) || (errno == EINPROGRESS)) { | 76   if ((result == 0) || (errno == EINPROGRESS)) { | 
| 77     return fd; | 77     return fd; | 
| 78   } | 78   } | 
| 79   SaveErrorAndClose(fd); | 79   FDUtils::SaveErrorAndClose(fd); | 
| 80   return -1; | 80   return -1; | 
| 81 } | 81 } | 
| 82 | 82 | 
| 83 | 83 | 
| 84 intptr_t Socket::CreateConnect(const RawAddr& addr) { | 84 intptr_t Socket::CreateConnect(const RawAddr& addr) { | 
| 85   intptr_t fd = Create(addr); | 85   intptr_t fd = Create(addr); | 
| 86   if (fd < 0) { | 86   if (fd < 0) { | 
| 87     return fd; | 87     return fd; | 
| 88   } | 88   } | 
| 89 | 89 | 
| 90   if (!FDUtils::SetNonBlocking(fd)) { | 90   if (!FDUtils::SetNonBlocking(fd)) { | 
| 91     SaveErrorAndClose(fd); | 91     FDUtils::SaveErrorAndClose(fd); | 
| 92     return -1; | 92     return -1; | 
| 93   } | 93   } | 
| 94   return Connect(fd, addr); | 94   return Connect(fd, addr); | 
| 95 } | 95 } | 
| 96 | 96 | 
| 97 | 97 | 
| 98 intptr_t Socket::CreateBindConnect(const RawAddr& addr, | 98 intptr_t Socket::CreateBindConnect(const RawAddr& addr, | 
| 99                                    const RawAddr& source_addr) { | 99                                    const RawAddr& source_addr) { | 
| 100   intptr_t fd = Create(addr); | 100   intptr_t fd = Create(addr); | 
| 101   if (fd < 0) { | 101   if (fd < 0) { | 
| 102     return fd; | 102     return fd; | 
| 103   } | 103   } | 
| 104 | 104 | 
| 105   intptr_t result = TEMP_FAILURE_RETRY( | 105   intptr_t result = TEMP_FAILURE_RETRY( | 
| 106       bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); | 106       bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); | 
| 107   if ((result != 0) && (errno != EINPROGRESS)) { | 107   if ((result != 0) && (errno != EINPROGRESS)) { | 
| 108     SaveErrorAndClose(fd); | 108     FDUtils::SaveErrorAndClose(fd); | 
| 109     return -1; | 109     return -1; | 
| 110   } | 110   } | 
| 111 | 111 | 
| 112   return Connect(fd, addr); | 112   return Connect(fd, addr); | 
| 113 } | 113 } | 
| 114 | 114 | 
| 115 | 115 | 
| 116 bool Socket::IsBindError(intptr_t error_number) { | 116 bool Socket::IsBindError(intptr_t error_number) { | 
| 117   return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || | 117   return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || | 
| 118          error_number == EINVAL; | 118          error_number == EINVAL; | 
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 316 | 316 | 
| 317 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { | 317 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { | 
| 318   intptr_t fd; | 318   intptr_t fd; | 
| 319 | 319 | 
| 320   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)); | 
| 321   if (fd < 0) { | 321   if (fd < 0) { | 
| 322     return -1; | 322     return -1; | 
| 323   } | 323   } | 
| 324 | 324 | 
| 325   if (!FDUtils::SetCloseOnExec(fd)) { | 325   if (!FDUtils::SetCloseOnExec(fd)) { | 
| 326     SaveErrorAndClose(fd); | 326     FDUtils::SaveErrorAndClose(fd); | 
| 327     return -1; | 327     return -1; | 
| 328   } | 328   } | 
| 329 | 329 | 
| 330   if (reuseAddress) { | 330   if (reuseAddress) { | 
| 331     int optval = 1; | 331     int optval = 1; | 
| 332     VOID_NO_RETRY_EXPECTED( | 332     VOID_NO_RETRY_EXPECTED( | 
| 333         setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 333         setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 
| 334   } | 334   } | 
| 335 | 335 | 
| 336   if (NO_RETRY_EXPECTED( | 336   if (NO_RETRY_EXPECTED( | 
| 337           bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { | 337           bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { | 
| 338     SaveErrorAndClose(fd); | 338     FDUtils::SaveErrorAndClose(fd); | 
| 339     return -1; | 339     return -1; | 
| 340   } | 340   } | 
| 341 | 341 | 
| 342   if (!FDUtils::SetNonBlocking(fd)) { | 342   if (!FDUtils::SetNonBlocking(fd)) { | 
| 343     SaveErrorAndClose(fd); | 343     FDUtils::SaveErrorAndClose(fd); | 
| 344     return -1; | 344     return -1; | 
| 345   } | 345   } | 
| 346   return fd; | 346   return fd; | 
| 347 } | 347 } | 
| 348 | 348 | 
| 349 | 349 | 
| 350 bool Socket::ListInterfacesSupported() { | 350 bool Socket::ListInterfacesSupported() { | 
| 351   return false; | 351   return false; | 
| 352 } | 352 } | 
| 353 | 353 | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 370                                         intptr_t backlog, | 370                                         intptr_t backlog, | 
| 371                                         bool v6_only) { | 371                                         bool v6_only) { | 
| 372   intptr_t fd; | 372   intptr_t fd; | 
| 373 | 373 | 
| 374   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)); | 
| 375   if (fd < 0) { | 375   if (fd < 0) { | 
| 376     return -1; | 376     return -1; | 
| 377   } | 377   } | 
| 378 | 378 | 
| 379   if (!FDUtils::SetCloseOnExec(fd)) { | 379   if (!FDUtils::SetCloseOnExec(fd)) { | 
| 380     SaveErrorAndClose(fd); | 380     FDUtils::SaveErrorAndClose(fd); | 
| 381     return -1; | 381     return -1; | 
| 382   } | 382   } | 
| 383 | 383 | 
| 384   int optval = 1; | 384   int optval = 1; | 
| 385   VOID_NO_RETRY_EXPECTED( | 385   VOID_NO_RETRY_EXPECTED( | 
| 386       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 386       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 
| 387 | 387 | 
| 388   if (addr.ss.ss_family == AF_INET6) { | 388   if (addr.ss.ss_family == AF_INET6) { | 
| 389     optval = v6_only ? 1 : 0; | 389     optval = v6_only ? 1 : 0; | 
| 390     VOID_NO_RETRY_EXPECTED( | 390     VOID_NO_RETRY_EXPECTED( | 
| 391         setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))); | 391         setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))); | 
| 392   } | 392   } | 
| 393 | 393 | 
| 394   if (NO_RETRY_EXPECTED( | 394   if (NO_RETRY_EXPECTED( | 
| 395           bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { | 395           bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { | 
| 396     SaveErrorAndClose(fd); | 396     FDUtils::SaveErrorAndClose(fd); | 
| 397     return -1; | 397     return -1; | 
| 398   } | 398   } | 
| 399 | 399 | 
| 400   // Test for invalid socket port 65535 (some browsers disallow it). | 400   // Test for invalid socket port 65535 (some browsers disallow it). | 
| 401   if ((SocketAddress::GetAddrPort(addr)) == 0 && | 401   if ((SocketAddress::GetAddrPort(addr)) == 0 && | 
| 402       (Socket::GetPort(fd) == 65535)) { | 402       (Socket::GetPort(fd) == 65535)) { | 
| 403     // 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 | 
| 404     // that we do not get the bad port number again. | 404     // that we do not get the bad port number again. | 
| 405     intptr_t new_fd = CreateBindListen(addr, backlog, v6_only); | 405     intptr_t new_fd = CreateBindListen(addr, backlog, v6_only); | 
| 406     SaveErrorAndClose(fd); | 406     FDUtils::SaveErrorAndClose(fd); | 
| 407     return new_fd; | 407     return new_fd; | 
| 408   } | 408   } | 
| 409 | 409 | 
| 410   if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { | 410   if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { | 
| 411     SaveErrorAndClose(fd); | 411     FDUtils::SaveErrorAndClose(fd); | 
| 412     return -1; | 412     return -1; | 
| 413   } | 413   } | 
| 414 | 414 | 
| 415   if (!FDUtils::SetNonBlocking(fd)) { | 415   if (!FDUtils::SetNonBlocking(fd)) { | 
| 416     SaveErrorAndClose(fd); | 416     FDUtils::SaveErrorAndClose(fd); | 
| 417     return -1; | 417     return -1; | 
| 418   } | 418   } | 
| 419   return fd; | 419   return fd; | 
| 420 } | 420 } | 
| 421 | 421 | 
| 422 | 422 | 
| 423 bool ServerSocket::StartAccept(intptr_t fd) { | 423 bool ServerSocket::StartAccept(intptr_t fd) { | 
| 424   USE(fd); | 424   USE(fd); | 
| 425   return true; | 425   return true; | 
| 426 } | 426 } | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 444   if (socket == -1) { | 444   if (socket == -1) { | 
| 445     if (IsTemporaryAcceptError(errno)) { | 445     if (IsTemporaryAcceptError(errno)) { | 
| 446       // 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 | 
| 447       // 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, | 
| 448       // but there is no connection ready to be accepted. | 448       // but there is no connection ready to be accepted. | 
| 449       ASSERT(kTemporaryFailure != -1); | 449       ASSERT(kTemporaryFailure != -1); | 
| 450       socket = kTemporaryFailure; | 450       socket = kTemporaryFailure; | 
| 451     } | 451     } | 
| 452   } else { | 452   } else { | 
| 453     if (!FDUtils::SetCloseOnExec(socket)) { | 453     if (!FDUtils::SetCloseOnExec(socket)) { | 
| 454       SaveErrorAndClose(socket); | 454       FDUtils::SaveErrorAndClose(socket); | 
| 455       return -1; | 455       return -1; | 
| 456     } | 456     } | 
| 457     if (!FDUtils::SetNonBlocking(socket)) { | 457     if (!FDUtils::SetNonBlocking(socket)) { | 
| 458       SaveErrorAndClose(socket); | 458       FDUtils::SaveErrorAndClose(socket); | 
| 459       return -1; | 459       return -1; | 
| 460     } | 460     } | 
| 461   } | 461   } | 
| 462   return socket; | 462   return socket; | 
| 463 } | 463 } | 
| 464 | 464 | 
| 465 | 465 | 
| 466 void Socket::Close(intptr_t fd) { | 466 void Socket::Close(intptr_t fd) { | 
| 467   ASSERT(fd >= 0); | 467   ASSERT(fd >= 0); | 
| 468   VOID_TEMP_FAILURE_RETRY(close(fd)); | 468   VOID_TEMP_FAILURE_RETRY(close(fd)); | 
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 583   return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, | 583   return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, | 
| 584                                       sizeof(mreq))) == 0; | 584                                       sizeof(mreq))) == 0; | 
| 585 } | 585 } | 
| 586 | 586 | 
| 587 }  // namespace bin | 587 }  // namespace bin | 
| 588 }  // namespace dart | 588 }  // namespace dart | 
| 589 | 589 | 
| 590 #endif  // defined(TARGET_OS_ANDROID) | 590 #endif  // defined(TARGET_OS_ANDROID) | 
| 591 | 591 | 
| 592 #endif  // !defined(DART_IO_DISABLED) | 592 #endif  // !defined(DART_IO_DISABLED) | 
| OLD | NEW | 
|---|