Index: runtime/bin/socket_linux.cc |
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc |
index c6e1fe1a885298ce14ab11e6416deb64d4c82ecd..74f7fbb3a9a58e11e41f7dbfa7c105e83298838a 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))); |
@@ -76,11 +76,30 @@ 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 fd = Create(addr); |
if (fd < 0) { |
return fd; |
} |
- return Socket::Connect(fd, addr, port); |
+ return Connect(fd, addr, port); |
+} |
+ |
+ |
+intptr_t Socket::CreateBindConnect(RawAddr addr, |
+ const intptr_t port, |
+ 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); |
} |