From c2d9a1ed6f215cc64c257628d2ceec04b2a4f6fa Mon Sep 17 00:00:00 2001 From: Daniel Evers Date: Thu, 12 Oct 2017 18:15:12 +0200 Subject: [PATCH] Support for Windows / MinGW --- src/allocator.h | 2 ++ src/asio_common.cc | 1 + src/memchunk.h | 8 ++++++ src/network.h | 6 ++++ src/util.cc | 68 ++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/allocator.h b/src/allocator.h index 7fa0b8ec86..029219aa35 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -27,7 +27,9 @@ #include "nghttp2_config.h" +#ifndef _WIN32 #include +#endif // !_WIN32 #include diff --git a/src/asio_common.cc b/src/asio_common.cc index c93b3619ec..9250229c45 100644 --- a/src/asio_common.cc +++ b/src/asio_common.cc @@ -25,6 +25,7 @@ #include "asio_common.h" #include +#include #include "util.h" #include "template.h" diff --git a/src/memchunk.h b/src/memchunk.h index b5fec00b83..9b5e014ac8 100644 --- a/src/memchunk.h +++ b/src/memchunk.h @@ -28,7 +28,15 @@ #include "nghttp2_config.h" #include +#ifdef _WIN32 +/* Structure for scatter/gather I/O. */ +struct iovec { + void *iov_base; /* Pointer to data. */ + size_t iov_len; /* Length of data. */ +}; +#else #include +#endif // _WIN32 #include #include diff --git a/src/network.h b/src/network.h index 3fb765d07c..44786a91c7 100644 --- a/src/network.h +++ b/src/network.h @@ -33,7 +33,11 @@ #ifdef HAVE_SYS_SOCKET_H #include #endif // HAVE_SYS_SOCKET_H +#ifdef _WIN32 +#include +#else #include +#endif // _WIN32 #ifdef HAVE_NETINET_IN_H #include #endif // HAVE_NETINET_IN_H @@ -48,7 +52,9 @@ union sockaddr_union { sockaddr sa; sockaddr_in6 in6; sockaddr_in in; +#ifndef _WIN32 sockaddr_un un; +#endif // !_WIN32 }; struct Address { diff --git a/src/util.cc b/src/util.cc index aeaddebb4c..8837274b03 100644 --- a/src/util.cc +++ b/src/util.cc @@ -41,7 +41,12 @@ #ifdef HAVE_NETINET_IN_H #include #endif // HAVE_NETINET_IN_H +#ifdef _WIN32 +#include +#include +#else #include +#endif // _WIN32 #ifdef HAVE_ARPA_INET_H #include #endif // HAVE_ARPA_INET_H @@ -65,6 +70,28 @@ namespace nghttp2 { namespace util { +#ifdef _WIN32 +// inet_pton-wrapper for Windows +static int inet_pton(int af, const char *src, void *dst) +{ +#if _WIN32_WINNT >= 0x0600 + return InetPtonA(af, src, dst); +#else + // the function takes a 'char*', so we need to make a copy + char addr[INET6_ADDRSTRLEN + 1]; + strncpy(addr, src, sizeof(addr)); + addr[sizeof(addr)-1] = 0; + + int size = sizeof(struct in6_addr); + + if (WSAStringToAddress(addr, af, NULL, (LPSOCKADDR)dst, &size) == 0) + return 1; + return 0; +#endif +} +#endif // _WIN32 + + const char UPPER_XDIGITS[] = "0123456789ABCDEF"; bool in_rfc3986_unreserved_chars(const char c) { @@ -352,13 +379,33 @@ char *iso8601_date(char *res, int64_t ms) { return p; } +#ifdef _WIN32 +namespace bt = boost::posix_time; +// one-time definition of the locale that is used to parse UTC strings +// (note that the time_input_facet is ref-counted and deleted automatically) +static const std::locale ptime_locale(std::locale::classic(), + new bt::time_input_facet("%a, %d %b %Y %H:%M:%S GMT")); +#endif //_WIN32 + time_t parse_http_date(const StringRef &s) { +#ifdef _WIN32 + // there is no strptime - use boost + std::stringstream sstr(s.str()); + sstr.imbue(ptime_locale); + bt::ptime ltime; + sstr >> ltime; + if (!sstr) + return 0; + + return boost::posix_time::to_time_t(ltime); +#else tm tm{}; char *r = strptime(s.c_str(), "%a, %d %b %Y %H:%M:%S GMT", &tm); if (r == 0) { return 0; } return nghttp2_timegm_without_yday(&tm); +#endif // _WIN32 } char upcase(char c) { @@ -628,9 +675,11 @@ std::string numeric_name(const struct sockaddr *sa, socklen_t salen) { std::string to_numeric_addr(const Address *addr) { auto family = addr->su.storage.ss_family; +#ifndef _WIN32 if (family == AF_UNIX) { return addr->su.un.sun_path; } +#endif // !_WIN32 std::array host; std::array serv; @@ -818,6 +867,10 @@ std::vector parse_config_str_list(const StringRef &s, char delim) { } int make_socket_closeonexec(int fd) { +#ifdef _WIN32 + (void)fd; + return 0; +#else int flags; int rv; while ((flags = fcntl(fd, F_GETFD)) == -1 && errno == EINTR) @@ -825,15 +878,24 @@ int make_socket_closeonexec(int fd) { while ((rv = fcntl(fd, F_SETFD, flags | FD_CLOEXEC)) == -1 && errno == EINTR) ; return rv; +#endif // _WIN32 } int make_socket_nonblocking(int fd) { - int flags; int rv; + +#ifdef _WIN32 + u_long mode = 1; + + rv = ioctlsocket(fd, FIONBIO, &mode); +#else + int flags; while ((flags = fcntl(fd, F_GETFL, 0)) == -1 && errno == EINTR) ; while ((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR) ; +#endif // _WIN32 + return rv; } @@ -874,7 +936,7 @@ int create_nonblock_socket(int family) { bool check_socket_connected(int fd) { int error; socklen_t len = sizeof(error); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) { + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) != 0) { return false; } @@ -884,7 +946,7 @@ bool check_socket_connected(int fd) { int get_socket_error(int fd) { int error; socklen_t len = sizeof(error); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) { + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) != 0) { return -1; }