Support read and write from blocking and non-blocking pipes and sockets
[folly.git] / folly / SocketAddress.cpp
index 5f63d8e0420f83ad512bcd33dee95f7a0746301c..034b1b6fe070559ab15cdad9af8e4e0761769a69 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <folly/SocketAddress.h>
 
+#include <folly/Exception.h>
 #include <folly/Hash.h>
 
 #include <boost/functional/hash.hpp>
@@ -28,6 +29,7 @@
 #include <errno.h>
 #include <sstream>
 #include <string>
+#include <system_error>
 
 namespace {
 
@@ -179,6 +181,39 @@ void SocketAddress::setFromHostPort(const char* hostAndPort) {
   setFromAddrInfo(results.info);
 }
 
+int SocketAddress::getPortFrom(const struct sockaddr* address) {
+  switch (address->sa_family) {
+    case AF_INET:
+      return ntohs(((sockaddr_in*)address)->sin_port);
+
+    case AF_INET6:
+      return ntohs(((sockaddr_in6*)address)->sin6_port);
+
+    default:
+      return -1;
+  }
+}
+
+const char* SocketAddress::getFamilyNameFrom(
+    const struct sockaddr* address,
+    const char* defaultResult) {
+#define GETFAMILYNAMEFROM_IMPL(Family) \
+  case Family:                         \
+    return #Family
+
+  switch (address->sa_family) {
+    GETFAMILYNAMEFROM_IMPL(AF_INET);
+    GETFAMILYNAMEFROM_IMPL(AF_INET6);
+    GETFAMILYNAMEFROM_IMPL(AF_UNIX);
+    GETFAMILYNAMEFROM_IMPL(AF_UNSPEC);
+
+    default:
+      return defaultResult;
+  }
+
+#undef GETFAMILYNAMEFROM_IMPL
+}
+
 void SocketAddress::setFromPath(StringPiece path) {
   // Before we touch storage_, check to see if the length is too big.
   // Note that "storage_.un.addr->sun_path" may not be safe to evaluate here,
@@ -205,11 +240,11 @@ void SocketAddress::setFromPath(StringPiece path) {
   }
 }
 
-void SocketAddress::setFromPeerAddress(SocketDesc socket) {
+void SocketAddress::setFromPeerAddress(int socket) {
   setFromSocket(socket, getpeername);
 }
 
-void SocketAddress::setFromLocalAddress(SocketDesc socket) {
+void SocketAddress::setFromLocalAddress(int socket) {
   setFromSocket(socket, getsockname);
 }
 
@@ -609,7 +644,9 @@ void SocketAddress::setFromLocalAddr(const struct addrinfo* info) {
   setFromSockaddr(info->ai_addr, info->ai_addrlen);
 }
 
-void SocketAddress::setFromSocket(SocketDesc socket, GetPeerNameFunc fn) {
+void SocketAddress::setFromSocket(
+    int socket,
+    int (*fn)(int, struct sockaddr*, socklen_t*)) {
   // Try to put the address into a local storage buffer.
   sockaddr_storage tmp_sock;
   socklen_t addrLen = sizeof(tmp_sock);