}
}
-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);
}
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);
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.
}
};
+ // 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;
#include <stdexcept>
#include <iterator>
#include <cctype>
+#include <string.h>
#include <glog/logging.h>
namespace folly {
// 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