Index: runtime/bin/socket.h |
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h |
index 507acd90fcb59b7e09c5a5efd999cc3601d523da..3bbe37346f4e0bcc76d0d8426397434153553147 100644 |
--- a/runtime/bin/socket.h |
+++ b/runtime/bin/socket.h |
@@ -33,6 +33,7 @@ namespace bin { |
union RawAddr { |
struct sockaddr_in in; |
struct sockaddr_in6 in6; |
+ struct sockaddr_un un; |
struct sockaddr_storage ss; |
struct sockaddr addr; |
}; |
@@ -43,6 +44,7 @@ class SocketAddress { |
TYPE_ANY = -1, |
TYPE_IPV4, |
TYPE_IPV6, |
+ TYPE_UNIX, |
}; |
enum { |
@@ -59,17 +61,38 @@ class SocketAddress { |
~SocketAddress() {} |
int GetType() { |
- if (addr_.ss.ss_family == AF_INET6) return TYPE_IPV6; |
- return TYPE_IPV4; |
+ switch (addr_.ss.ss_family) { |
+ case AF_INET: return TYPE_IPV4; |
+ case AF_INET6: return TYPE_IPV6; |
+ case AF_UNIX: return TYPE_UNIX; |
+ default: |
+ UNREACHABLE(); |
+ return TYPE_ANY; |
+ } |
+ } |
+ |
+ const char* as_string() const { |
+ if (addr_.ss.ss_family == AF_UNIX) { |
+ return addr_.un.sun_path; |
+ } else { |
+ return as_string_; |
+ } |
} |
- const char* as_string() const { return as_string_; } |
const RawAddr& addr() const { return addr_; } |
static intptr_t GetAddrLength(const RawAddr& addr) { |
- ASSERT(addr.ss.ss_family == AF_INET || addr.ss.ss_family == AF_INET6); |
- return addr.ss.ss_family == AF_INET6 ? |
- sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); |
+ ASSERT(addr.ss.ss_family == AF_INET || |
+ addr.ss.ss_family == AF_INET6 || |
+ addr.ss.ss_family == AF_UNIX); |
+ switch (addr.ss.ss_family) { |
+ case AF_INET: return sizeof(struct sockaddr_in); |
+ case AF_INET6: return sizeof(struct sockaddr_in6); |
+ case AF_UNIX: return sizeof(struct sockaddr_un); |
+ default: |
+ UNREACHABLE(); |
+ return 0; |
+ } |
} |
static intptr_t GetInAddrLength(const RawAddr& addr) { |
@@ -87,6 +110,13 @@ class SocketAddress { |
return memcmp(&a.in6.sin6_addr, |
&b.in6.sin6_addr, |
sizeof(a.in6.sin6_addr)) == 0; |
+ } else if (a.ss.ss_family == AF_UNIX) { |
+ int len = sizeof(a.un.sun_path); |
+ for (int i = 0; i < len; i++) { |
+ if (a.un.sun_path[i] != b.un.sun_path[i]) return false; |
+ if (a.un.sun_path[i] == '\0') return true; |
+ } |
+ return true; |
} else { |
UNREACHABLE(); |
return false; |
@@ -127,16 +157,23 @@ class SocketAddress { |
static void SetAddrPort(RawAddr* addr, intptr_t port) { |
if (addr->ss.ss_family == AF_INET) { |
addr->in.sin_port = htons(port); |
- } else { |
+ } else if (addr->ss.ss_family == AF_INET6) { |
addr->in6.sin6_port = htons(port); |
+ } else { |
+ UNREACHABLE(); |
} |
} |
static intptr_t GetAddrPort(const RawAddr& addr) { |
if (addr.ss.ss_family == AF_INET) { |
return ntohs(addr.in.sin_port); |
- } else { |
+ } else if (addr.ss.ss_family == AF_INET6) { |
return ntohs(addr.in6.sin6_port); |
+ } else if (addr.ss.ss_family == AF_UNIX) { |
+ return 1; // TODO(sgjesse): Should be -1. |
+ } else { |
+ UNREACHABLE(); |
+ return -1; |
} |
} |
@@ -256,6 +293,7 @@ class Socket { |
// specified as the port component of the passed RawAddr structure. |
static intptr_t CreateBindConnect(const RawAddr& addr, |
const RawAddr& source_addr); |
+ static intptr_t CreateConnectUnix(const RawAddr& addr); |
// Creates a datagram socket which is bound. The port to bind |
// to is specified as the port component of the RawAddr structure. |
static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress); |
@@ -333,6 +371,9 @@ class ServerSocket { |
intptr_t backlog, |
bool v6_only = false); |
+ static intptr_t CreateBindListenUnix(const RawAddr& addr, |
+ intptr_t backlog); |
+ |
// Start accepting on a newly created listening socket. If it was unable to |
// start accepting incoming sockets, the fd is invalidated. |
static bool StartAccept(intptr_t fd); |
@@ -383,7 +424,8 @@ class ListeningSocketRegistry { |
RawAddr addr, |
intptr_t backlog, |
bool v6_only, |
- bool shared); |
+ bool shared, |
+ bool uds); |
// This should be called from the event handler for every kCloseEvent it gets |
// on listening sockets. |