Index: runtime/bin/socket_linux.cc |
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc |
index 87df8ff51047241b4724aa098fb9957f048d994d..151ac5bb8a77fcabbfbf126954264c1fcff30d86 100644 |
--- a/runtime/bin/socket_linux.cc |
+++ b/runtime/bin/socket_linux.cc |
@@ -52,7 +52,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 | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); |
@@ -63,7 +63,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))); |
@@ -75,12 +75,31 @@ 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; |
} |
- 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); |
} |