| OLD | NEW | 
|---|
| 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 #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(HOST_OS_LINUX) | 8 #if defined(HOST_OS_LINUX) | 
| 9 | 9 | 
| 10 #include "bin/socket.h" | 10 #include "bin/socket.h" | 
| 11 | 11 | 
| 12 #include <errno.h>        // NOLINT | 12 #include <errno.h>  // NOLINT | 
| 13 | 13 | 
| 14 #include "bin/fdutils.h" | 14 #include "bin/fdutils.h" | 
| 15 #include "platform/signal_blocker.h" | 15 #include "platform/signal_blocker.h" | 
| 16 | 16 | 
| 17 namespace dart { | 17 namespace dart { | 
| 18 namespace bin { | 18 namespace bin { | 
| 19 | 19 | 
| 20 Socket::Socket(intptr_t fd) | 20 Socket::Socket(intptr_t fd) | 
| 21     : ReferenceCounted(), fd_(fd), port_(ILLEGAL_PORT) {} | 21     : ReferenceCounted(), fd_(fd), port_(ILLEGAL_PORT) {} | 
| 22 | 22 | 
| 23 |  | 
| 24 void Socket::SetClosedFd() { | 23 void Socket::SetClosedFd() { | 
| 25   fd_ = kClosedFd; | 24   fd_ = kClosedFd; | 
| 26 } | 25 } | 
| 27 | 26 | 
| 28 |  | 
| 29 static intptr_t Create(const RawAddr& addr) { | 27 static intptr_t Create(const RawAddr& addr) { | 
| 30   intptr_t fd; | 28   intptr_t fd; | 
| 31   intptr_t type = SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC; | 29   intptr_t type = SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC; | 
| 32   fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, type, 0)); | 30   fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, type, 0)); | 
| 33   if (fd < 0) { | 31   if (fd < 0) { | 
| 34     return -1; | 32     return -1; | 
| 35   } | 33   } | 
| 36   return fd; | 34   return fd; | 
| 37 } | 35 } | 
| 38 | 36 | 
| 39 |  | 
| 40 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { | 37 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { | 
| 41   intptr_t result = TEMP_FAILURE_RETRY( | 38   intptr_t result = TEMP_FAILURE_RETRY( | 
| 42       connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); | 39       connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); | 
| 43   if ((result == 0) || (errno == EINPROGRESS)) { | 40   if ((result == 0) || (errno == EINPROGRESS)) { | 
| 44     return fd; | 41     return fd; | 
| 45   } | 42   } | 
| 46   FDUtils::FDUtils::SaveErrorAndClose(fd); | 43   FDUtils::FDUtils::SaveErrorAndClose(fd); | 
| 47   return -1; | 44   return -1; | 
| 48 } | 45 } | 
| 49 | 46 | 
| 50 |  | 
| 51 intptr_t Socket::CreateConnect(const RawAddr& addr) { | 47 intptr_t Socket::CreateConnect(const RawAddr& addr) { | 
| 52   intptr_t fd = Create(addr); | 48   intptr_t fd = Create(addr); | 
| 53   if (fd < 0) { | 49   if (fd < 0) { | 
| 54     return fd; | 50     return fd; | 
| 55   } | 51   } | 
| 56   return Connect(fd, addr); | 52   return Connect(fd, addr); | 
| 57 } | 53 } | 
| 58 | 54 | 
| 59 |  | 
| 60 intptr_t Socket::CreateBindConnect(const RawAddr& addr, | 55 intptr_t Socket::CreateBindConnect(const RawAddr& addr, | 
| 61                                    const RawAddr& source_addr) { | 56                                    const RawAddr& source_addr) { | 
| 62   intptr_t fd = Create(addr); | 57   intptr_t fd = Create(addr); | 
| 63   if (fd < 0) { | 58   if (fd < 0) { | 
| 64     return fd; | 59     return fd; | 
| 65   } | 60   } | 
| 66 | 61 | 
| 67   intptr_t result = TEMP_FAILURE_RETRY( | 62   intptr_t result = TEMP_FAILURE_RETRY( | 
| 68       bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); | 63       bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); | 
| 69   if ((result != 0) && (errno != EINPROGRESS)) { | 64   if ((result != 0) && (errno != EINPROGRESS)) { | 
| 70     FDUtils::SaveErrorAndClose(fd); | 65     FDUtils::SaveErrorAndClose(fd); | 
| 71     return -1; | 66     return -1; | 
| 72   } | 67   } | 
| 73 | 68 | 
| 74   return Connect(fd, addr); | 69   return Connect(fd, addr); | 
| 75 } | 70 } | 
| 76 | 71 | 
| 77 |  | 
| 78 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { | 72 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { | 
| 79   intptr_t fd; | 73   intptr_t fd; | 
| 80 | 74 | 
| 81   fd = NO_RETRY_EXPECTED(socket(addr.addr.sa_family, | 75   fd = NO_RETRY_EXPECTED(socket(addr.addr.sa_family, | 
| 82                                 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, | 76                                 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, | 
| 83                                 IPPROTO_UDP)); | 77                                 IPPROTO_UDP)); | 
| 84   if (fd < 0) { | 78   if (fd < 0) { | 
| 85     return -1; | 79     return -1; | 
| 86   } | 80   } | 
| 87 | 81 | 
| 88   if (reuseAddress) { | 82   if (reuseAddress) { | 
| 89     int optval = 1; | 83     int optval = 1; | 
| 90     VOID_NO_RETRY_EXPECTED( | 84     VOID_NO_RETRY_EXPECTED( | 
| 91         setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 85         setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 
| 92   } | 86   } | 
| 93 | 87 | 
| 94   if (NO_RETRY_EXPECTED( | 88   if (NO_RETRY_EXPECTED( | 
| 95           bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { | 89           bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { | 
| 96     FDUtils::SaveErrorAndClose(fd); | 90     FDUtils::SaveErrorAndClose(fd); | 
| 97     return -1; | 91     return -1; | 
| 98   } | 92   } | 
| 99   return fd; | 93   return fd; | 
| 100 } | 94 } | 
| 101 | 95 | 
| 102 |  | 
| 103 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, | 96 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, | 
| 104                                         intptr_t backlog, | 97                                         intptr_t backlog, | 
| 105                                         bool v6_only) { | 98                                         bool v6_only) { | 
| 106   intptr_t fd; | 99   intptr_t fd; | 
| 107 | 100 | 
| 108   fd = NO_RETRY_EXPECTED( | 101   fd = NO_RETRY_EXPECTED( | 
| 109       socket(addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)); | 102       socket(addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)); | 
| 110   if (fd < 0) { | 103   if (fd < 0) { | 
| 111     return -1; | 104     return -1; | 
| 112   } | 105   } | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 138   } | 131   } | 
| 139 | 132 | 
| 140   if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { | 133   if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { | 
| 141     FDUtils::SaveErrorAndClose(fd); | 134     FDUtils::SaveErrorAndClose(fd); | 
| 142     return -1; | 135     return -1; | 
| 143   } | 136   } | 
| 144 | 137 | 
| 145   return fd; | 138   return fd; | 
| 146 } | 139 } | 
| 147 | 140 | 
| 148 |  | 
| 149 bool ServerSocket::StartAccept(intptr_t fd) { | 141 bool ServerSocket::StartAccept(intptr_t fd) { | 
| 150   USE(fd); | 142   USE(fd); | 
| 151   return true; | 143   return true; | 
| 152 } | 144 } | 
| 153 | 145 | 
| 154 |  | 
| 155 static bool IsTemporaryAcceptError(int error) { | 146 static bool IsTemporaryAcceptError(int error) { | 
| 156   // On Linux a number of protocol errors should be treated as EAGAIN. | 147   // On Linux a number of protocol errors should be treated as EAGAIN. | 
| 157   // These are the ones for TCP/IP. | 148   // These are the ones for TCP/IP. | 
| 158   return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) || | 149   return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) || | 
| 159          (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) || | 150          (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) || | 
| 160          (error == EHOSTUNREACH) || (error == EOPNOTSUPP) || | 151          (error == EHOSTUNREACH) || (error == EOPNOTSUPP) || | 
| 161          (error == ENETUNREACH); | 152          (error == ENETUNREACH); | 
| 162 } | 153 } | 
| 163 | 154 | 
| 164 |  | 
| 165 intptr_t ServerSocket::Accept(intptr_t fd) { | 155 intptr_t ServerSocket::Accept(intptr_t fd) { | 
| 166   intptr_t socket; | 156   intptr_t socket; | 
| 167   struct sockaddr clientaddr; | 157   struct sockaddr clientaddr; | 
| 168   socklen_t addrlen = sizeof(clientaddr); | 158   socklen_t addrlen = sizeof(clientaddr); | 
| 169   socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen)); | 159   socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen)); | 
| 170   if (socket == -1) { | 160   if (socket == -1) { | 
| 171     if (IsTemporaryAcceptError(errno)) { | 161     if (IsTemporaryAcceptError(errno)) { | 
| 172       // We need to signal to the caller that this is actually not an | 162       // We need to signal to the caller that this is actually not an | 
| 173       // error. We got woken up from the poll on the listening socket, | 163       // error. We got woken up from the poll on the listening socket, | 
| 174       // but there is no connection ready to be accepted. | 164       // but there is no connection ready to be accepted. | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 187   } | 177   } | 
| 188   return socket; | 178   return socket; | 
| 189 } | 179 } | 
| 190 | 180 | 
| 191 }  // namespace bin | 181 }  // namespace bin | 
| 192 }  // namespace dart | 182 }  // namespace dart | 
| 193 | 183 | 
| 194 #endif  // defined(HOST_OS_LINUX) | 184 #endif  // defined(HOST_OS_LINUX) | 
| 195 | 185 | 
| 196 #endif  // !defined(DART_IO_DISABLED) | 186 #endif  // !defined(DART_IO_DISABLED) | 
| OLD | NEW | 
|---|