a subset of folly now compiles with Windows mingw64 toolchain
authorKjell Schubert <kschubert@fb.com>
Mon, 29 Jun 2015 15:33:54 +0000 (08:33 -0700)
committerSara Golemon <sgolemon@fb.com>
Mon, 29 Jun 2015 18:00:33 +0000 (11:00 -0700)
Summary: a subset of folly now compiles with Windows mingw64 toolchain

Reviewed By: @djwatson

Differential Revision: D2171872

folly/SocketAddress.cpp
folly/SocketAddress.h
folly/String.cpp

index dbed1747d1e347f7f1e4b40b98cd83db608bab16..2425a7e54a0b05ca6e549f5e6eba29b85ea6a559 100644 (file)
@@ -201,11 +201,11 @@ void SocketAddress::setFromPath(const char* path, size_t len) {
   }
 }
 
-void SocketAddress::setFromPeerAddress(int socket) {
+void SocketAddress::setFromPeerAddress(SocketDesc socket) {
   setFromSocket(socket, getpeername);
 }
 
-void SocketAddress::setFromLocalAddress(int socket) {
+void SocketAddress::setFromLocalAddress(SocketDesc socket) {
   setFromSocket(socket, getsockname);
 }
 
@@ -605,8 +605,7 @@ void SocketAddress::setFromLocalAddr(const struct addrinfo* info) {
   setFromSockaddr(info->ai_addr, info->ai_addrlen);
 }
 
-void SocketAddress::setFromSocket(int socket,
-                                  int (*fn)(int, sockaddr*, socklen_t*)) {
+void SocketAddress::setFromSocket(SocketDesc socket, GetPeerNameFunc fn) {
   // Try to put the address into a local storage buffer.
   sockaddr_storage tmp_sock;
   socklen_t addrLen = sizeof(tmp_sock);
index 049cf2ff9e2faabd70f8f0a84920d68a6031c75d..8f93953ad9a61d41d92d612d1130a0d17a134f6b 100644 (file)
@@ -288,19 +288,22 @@ class SocketAddress {
 
   void setFromPath(const char* path, size_t length);
 
+  // a typedef that allow us to compile against both winsock & POSIX sockets:
+  using SocketDesc = decltype(socket(0,0,0)); // POSIX: int, winsock: unsigned
+
   /**
    * Initialize this SocketAddress from a socket's peer address.
    *
    * Raises std::system_error on error.
    */
-  void setFromPeerAddress(int socket);
+  void setFromPeerAddress(SocketDesc socket);
 
   /**
    * Initialize this SocketAddress from a socket's local address.
    *
    * Raises std::system_error on error.
    */
-  void setFromLocalAddress(int socket);
+  void setFromLocalAddress(SocketDesc socket);
 
   /**
    * Initialize this TSocketAddress from a struct sockaddr.
@@ -556,11 +559,19 @@ class SocketAddress {
     }
   };
 
+  // a typedef that allow us to compile against both winsock & POSIX sockets:
+  // (both arg types and calling conventions differ for both)
+  // POSIX: void setFromSocket(int socket,
+  //                  int(*fn)(int, struct sockaddr*, socklen_t*));
+  // mingw: void setFromSocket(unsigned socket,
+  //                  int(*fn)(unsigned, struct sockaddr*, socklen_t*));
+  using GetPeerNameFunc = decltype(getpeername);
+
   struct addrinfo* getAddrInfo(const char* host, uint16_t port, int flags);
   struct addrinfo* getAddrInfo(const char* host, const char* port, int flags);
   void setFromAddrInfo(const struct addrinfo* results);
   void setFromLocalAddr(const struct addrinfo* results);
-  void setFromSocket(int socket, int (*fn)(int, struct sockaddr*, socklen_t*));
+  void setFromSocket(SocketDesc socket, GetPeerNameFunc fn);
   std::string getIpString(int flags) const;
   void getIpString(char *buf, size_t buflen, int flags) const;
 
index 337b7e37dac94371203e3a3894861dcdb14bfa4c..66649caaaa5bdcb9f0b95de415bf4a59c81ff6d0 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdexcept>
 #include <iterator>
 #include <cctype>
+#include <string.h>
 #include <glog/logging.h>
 
 namespace folly {
@@ -329,7 +330,19 @@ fbstring errnoStr(int err) {
 
   // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/strerror_r.3.html
   // http://www.kernel.org/doc/man-pages/online/pages/man3/strerror.3.html
-#if defined(__APPLE__) || defined(__FreeBSD__) ||\
+#if defined(_WIN32) && defined(__MINGW32__)
+  // mingw64 has no strerror_r, but Windows has strerror_s, which C11 added
+  // as well. So maybe we should use this across all platforms (together
+  // with strerrorlen_s). Note strerror_r and _s have swapped args.
+  int r = strerror_s(buf, sizeof(buf), err);
+  if (r != 0) {
+    result = to<fbstring>(
+      "Unknown error ", err,
+      " (strerror_r failed with error ", errno, ")");
+  } else {
+    result.assign(buf);
+  }
+#elif defined(__APPLE__) || defined(__FreeBSD__) ||\
     defined(__CYGWIN__) || defined(__ANDROID__) ||\
     ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE)
   // Using XSI-compatible strerror_r