Merge pull request #1027 from dermojo/mingw
Support for Windows / MinGW
This commit is contained in:
commit
56ee3d4820
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
68
src/util.cc
68
src/util.cc
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue