Skip to content

Commit

Permalink
Support for Windows / MinGW
Browse files Browse the repository at this point in the history
  • Loading branch information
dermojo committed Oct 12, 2017
1 parent fcf9ab2 commit c2d9a1e
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/allocator.h
Expand Up @@ -27,7 +27,9 @@

#include "nghttp2_config.h"

#ifndef _WIN32
#include <sys/uio.h>
#endif // !_WIN32

#include <cassert>

Expand Down
1 change: 1 addition & 0 deletions src/asio_common.cc
Expand Up @@ -25,6 +25,7 @@
#include "asio_common.h"

#include <memory>
#include <fcntl.h>

#include "util.h"
#include "template.h"
Expand Down
8 changes: 8 additions & 0 deletions src/memchunk.h
Expand Up @@ -28,7 +28,15 @@
#include "nghttp2_config.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>
#endif // _WIN32

#include <cassert>
#include <cstring>
Expand Down
6 changes: 6 additions & 0 deletions src/network.h
Expand Up @@ -33,7 +33,11 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <sys/un.h>
#endif // _WIN32
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
Expand All @@ -48,7 +52,9 @@ union sockaddr_union {
sockaddr sa;
sockaddr_in6 in6;
sockaddr_in in;
#ifndef _WIN32
sockaddr_un un;
#endif // !_WIN32
};

struct Address {
Expand Down
68 changes: 65 additions & 3 deletions src/util.cc
Expand Up @@ -41,7 +41,12 @@
#ifdef HAVE_NETINET_IN_H
#include <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>
#endif // _WIN32
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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<char, NI_MAXHOST> host;
std::array<char, NI_MAXSERV> serv;
Expand Down Expand Up @@ -818,22 +867,35 @@ std::vector<std::string> 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)
;
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;
}

Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down

0 comments on commit c2d9a1e

Please sign in to comment.