Index: runtime/bin/socket_android.cc |
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc |
index 7596f4f835c88f706eef96fd6a0d1266500a3284..e9650573cd341d77b2504363ef04fb67070c9e12 100644 |
--- a/runtime/bin/socket_android.cc |
+++ b/runtime/bin/socket_android.cc |
@@ -55,7 +55,7 @@ bool Socket::Initialize() { |
} |
-intptr_t Socket::Create(RawAddr addr) { |
+static intptr_t Create(RawAddr addr) { |
intptr_t fd; |
fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0)); |
if (fd < 0) { |
@@ -66,7 +66,7 @@ intptr_t Socket::Create(RawAddr addr) { |
} |
-intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) { |
+static intptr_t Connect(intptr_t fd, RawAddr addr, const intptr_t port) { |
SocketAddress::SetAddrPort(&addr, port); |
intptr_t result = TEMP_FAILURE_RETRY( |
connect(fd, &addr.addr, SocketAddress::GetAddrLength(&addr))); |
@@ -78,15 +78,34 @@ intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) { |
} |
-intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) { |
- intptr_t fd = Socket::Create(addr); |
+intptr_t Socket::CreateConnect(const RawAddr& addr, const intptr_t port) { |
+ intptr_t fd = Create(addr); |
if (fd < 0) { |
return fd; |
} |
FDUtils::SetNonBlocking(fd); |
- return Socket::Connect(fd, addr, port); |
+ return Connect(fd, addr, port); |
+} |
+ |
+ |
+intptr_t Socket::CreateBindConnect(const RawAddr& addr, |
+ const intptr_t port, |
+ const RawAddr& source_addr) { |
+ intptr_t fd = Create(addr); |
+ if (fd < 0) { |
+ return fd; |
+ } |
+ |
+ intptr_t result = TEMP_FAILURE_RETRY( |
+ bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(&source_addr))); |
+ if (result != 0 && errno != EINPROGRESS) { |
+ VOID_TEMP_FAILURE_RETRY(close(fd)); |
+ return -1; |
+ } |
+ |
+ return Connect(fd, addr, port); |
} |