Support for Windows / MinGW

This commit is contained in:
Daniel Evers 2017-10-12 18:15:12 +02:00
parent fcf9ab2798
commit c2d9a1ed6f
5 changed files with 82 additions and 3 deletions

View File

@ -27,7 +27,9 @@
#include "nghttp2_config.h" #include "nghttp2_config.h"
#ifndef _WIN32
#include <sys/uio.h> #include <sys/uio.h>
#endif // !_WIN32
#include <cassert> #include <cassert>

View File

@ -25,6 +25,7 @@
#include "asio_common.h" #include "asio_common.h"
#include <memory> #include <memory>
#include <fcntl.h>
#include "util.h" #include "util.h"
#include "template.h" #include "template.h"

View File

@ -28,7 +28,15 @@
#include "nghttp2_config.h" #include "nghttp2_config.h"
#include <limits.h> #include <limits.h>
#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 <sys/uio.h> #include <sys/uio.h>
#endif // _WIN32
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>

View File

@ -33,7 +33,11 @@
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H #endif // HAVE_SYS_SOCKET_H
#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <sys/un.h> #include <sys/un.h>
#endif // _WIN32
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H #endif // HAVE_NETINET_IN_H
@ -48,7 +52,9 @@ union sockaddr_union {
sockaddr sa; sockaddr sa;
sockaddr_in6 in6; sockaddr_in6 in6;
sockaddr_in in; sockaddr_in in;
#ifndef _WIN32
sockaddr_un un; sockaddr_un un;
#endif // !_WIN32
}; };
struct Address { struct Address {

View File

@ -41,7 +41,12 @@
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H #endif // HAVE_NETINET_IN_H
#ifdef _WIN32
#include <ws2tcpip.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#else
#include <netinet/tcp.h> #include <netinet/tcp.h>
#endif // _WIN32
#ifdef HAVE_ARPA_INET_H #ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h> #include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H #endif // HAVE_ARPA_INET_H
@ -65,6 +70,28 @@ namespace nghttp2 {
namespace util { 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"; const char UPPER_XDIGITS[] = "0123456789ABCDEF";
bool in_rfc3986_unreserved_chars(const char c) { bool in_rfc3986_unreserved_chars(const char c) {
@ -352,13 +379,33 @@ char *iso8601_date(char *res, int64_t ms) {
return p; 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) { 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{}; tm tm{};
char *r = strptime(s.c_str(), "%a, %d %b %Y %H:%M:%S GMT", &tm); char *r = strptime(s.c_str(), "%a, %d %b %Y %H:%M:%S GMT", &tm);
if (r == 0) { if (r == 0) {
return 0; return 0;
} }
return nghttp2_timegm_without_yday(&tm); return nghttp2_timegm_without_yday(&tm);
#endif // _WIN32
} }
char upcase(char c) { 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) { std::string to_numeric_addr(const Address *addr) {
auto family = addr->su.storage.ss_family; auto family = addr->su.storage.ss_family;
#ifndef _WIN32
if (family == AF_UNIX) { if (family == AF_UNIX) {
return addr->su.un.sun_path; return addr->su.un.sun_path;
} }
#endif // !_WIN32
std::array<char, NI_MAXHOST> host; std::array<char, NI_MAXHOST> host;
std::array<char, NI_MAXSERV> serv; std::array<char, NI_MAXSERV> serv;
@ -818,6 +867,10 @@ std::vector<std::string> parse_config_str_list(const StringRef &s, char delim) {
} }
int make_socket_closeonexec(int fd) { int make_socket_closeonexec(int fd) {
#ifdef _WIN32
(void)fd;
return 0;
#else
int flags; int flags;
int rv; int rv;
while ((flags = fcntl(fd, F_GETFD)) == -1 && errno == EINTR) 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) while ((rv = fcntl(fd, F_SETFD, flags | FD_CLOEXEC)) == -1 && errno == EINTR)
; ;
return rv; return rv;
#endif // _WIN32
} }
int make_socket_nonblocking(int fd) { int make_socket_nonblocking(int fd) {
int flags;
int rv; 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 ((flags = fcntl(fd, F_GETFL, 0)) == -1 && errno == EINTR)
; ;
while ((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR) while ((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR)
; ;
#endif // _WIN32
return rv; return rv;
} }
@ -874,7 +936,7 @@ int create_nonblock_socket(int family) {
bool check_socket_connected(int fd) { bool check_socket_connected(int fd) {
int error; int error;
socklen_t len = sizeof(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; return false;
} }
@ -884,7 +946,7 @@ bool check_socket_connected(int fd) {
int get_socket_error(int fd) { int get_socket_error(int fd) {
int error; int error;
socklen_t len = sizeof(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; return -1;
} }