868 lines
25 KiB
Diff
868 lines
25 KiB
Diff
From a8fd6112b32cc1130df54b668fc05b7f65bc92ee Mon Sep 17 00:00:00 2001
|
|
From: Martell Malone <martellmalone@gmail.com>
|
|
Date: Thu, 25 Jun 2015 23:43:29 +0100
|
|
Subject: [PATCH 2/8] basic windows support
|
|
|
|
---
|
|
CMakeLists.txt | 4 ++
|
|
examples/libh2o/http1client.c | 6 +++
|
|
examples/libh2o/simple.c | 11 ++++-
|
|
include/h2o.h | 6 ++-
|
|
include/h2o/hostinfo.h | 17 ++++---
|
|
include/h2o/socket.h | 6 ++-
|
|
include/h2o/socketpool.h | 2 +
|
|
lib/common/http1client.c | 20 ++++++---
|
|
lib/common/multithread.c | 5 +++
|
|
lib/common/socket.c | 15 +++++--
|
|
lib/common/socket/evloop.c.h | 59 +++++++++++++++++++++++-
|
|
lib/common/socket/evloop/select.c.h | 2 +
|
|
lib/common/socketpool.c | 10 +++++
|
|
lib/core/proxy.c | 4 +-
|
|
lib/handler/access_log.c | 12 ++++-
|
|
lib/handler/configurator/fastcgi.c | 20 +++++++--
|
|
src/main.c | 90 ++++++++++++++++++++++++++++++++-----
|
|
17 files changed, 252 insertions(+), 37 deletions(-)
|
|
|
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
index 90b6338..c847a2d 100644
|
|
--- a/CMakeLists.txt
|
|
+++ b/CMakeLists.txt
|
|
@@ -217,6 +217,10 @@ LIST(REMOVE_ITEM UNIT_TEST_SOURCE_FILES
|
|
|
|
SET(EXTRA_LIBRARIES ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
|
|
|
|
+IF (WIN32)
|
|
+ SET(EXTRA_LIBRARIES ${EXTRA_LIBRARIES} ws2_32)
|
|
+ENDIF()
|
|
+
|
|
ADD_LIBRARY(libh2o ${LIB_SOURCE_FILES})
|
|
ADD_LIBRARY(libh2o-evloop ${LIB_SOURCE_FILES})
|
|
SET_TARGET_PROPERTIES(libh2o PROPERTIES OUTPUT_NAME h2o)
|
|
diff --git a/examples/libh2o/http1client.c b/examples/libh2o/http1client.c
|
|
index 261241f..20a2f1e 100644
|
|
--- a/examples/libh2o/http1client.c
|
|
+++ b/examples/libh2o/http1client.c
|
|
@@ -141,6 +141,12 @@ h2o_http1client_head_cb on_connect(h2o_http1client_t *client, const char *errstr
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
+
|
|
+#ifdef _WIN32
|
|
+ WSADATA wsaData;
|
|
+ WSAStartup(MAKEWORD(2, 0), &wsaData);
|
|
+#endif
|
|
+
|
|
h2o_multithread_queue_t *queue;
|
|
h2o_multithread_receiver_t getaddr_receiver;
|
|
h2o_timeout_t io_timeout;
|
|
diff --git a/examples/libh2o/simple.c b/examples/libh2o/simple.c
|
|
index 48d6448..d74dc40 100644
|
|
--- a/examples/libh2o/simple.c
|
|
+++ b/examples/libh2o/simple.c
|
|
@@ -21,11 +21,15 @@
|
|
*/
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
-#include <netinet/in.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
+#ifdef _WIN32
|
|
+#include <winsock2.h>
|
|
+#else
|
|
+#include <netinet/in.h>
|
|
#include <sys/socket.h>
|
|
+#endif
|
|
#include <sys/stat.h>
|
|
#include "h2o.h"
|
|
#include "h2o/http1.h"
|
|
@@ -215,7 +219,12 @@ int main(int argc, char **argv)
|
|
{
|
|
h2o_hostconf_t *hostconf;
|
|
|
|
+#ifdef _WIN32
|
|
+ WSADATA wsaData;
|
|
+ WSAStartup(MAKEWORD(2, 0), &wsaData);
|
|
+#else
|
|
signal(SIGPIPE, SIG_IGN);
|
|
+#endif
|
|
|
|
h2o_config_init(&config);
|
|
hostconf = h2o_config_register_host(&config, h2o_iovec_init(H2O_STRLIT("default")), 65535);
|
|
diff --git a/include/h2o.h b/include/h2o.h
|
|
index 176aa84..0e3b766 100644
|
|
--- a/include/h2o.h
|
|
+++ b/include/h2o.h
|
|
@@ -32,7 +32,11 @@ extern "C" {
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <sys/time.h>
|
|
-#include <sys/socket.h>
|
|
+#ifdef _WIN32
|
|
+# include <winsock2.h>
|
|
+#else
|
|
+# include <sys/socket.h>
|
|
+#endif
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include <openssl/ssl.h>
|
|
diff --git a/include/h2o/hostinfo.h b/include/h2o/hostinfo.h
|
|
index 14ac30c..d12b4db 100644
|
|
--- a/include/h2o/hostinfo.h
|
|
+++ b/include/h2o/hostinfo.h
|
|
@@ -22,13 +22,16 @@
|
|
#ifndef h2o__hostinfo_h
|
|
#define h2o__hostinfo_h
|
|
|
|
-#include <arpa/inet.h>
|
|
-#include <netdb.h>
|
|
-#include <netinet/in.h>
|
|
-#include <stdlib.h>
|
|
-#include <string.h>
|
|
-#include <sys/socket.h>
|
|
-#include <sys/types.h>
|
|
+#ifdef _WIN32
|
|
+# include <ws2tcpip.h>
|
|
+#else
|
|
+# include <netdb.h>
|
|
+# include <netinet/in.h>
|
|
+# include <stdlib.h>
|
|
+# include <string.h>
|
|
+# include <sys/socket.h>
|
|
+# include <sys/types.h>
|
|
+#endif
|
|
#include "h2o/multithread.h"
|
|
|
|
typedef struct st_h2o_hostinfo_getaddr_req_t h2o_hostinfo_getaddr_req_t;
|
|
diff --git a/include/h2o/socket.h b/include/h2o/socket.h
|
|
index 2d1e99c..42cd530 100644
|
|
--- a/include/h2o/socket.h
|
|
+++ b/include/h2o/socket.h
|
|
@@ -27,7 +27,11 @@ extern "C" {
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
-#include <sys/socket.h>
|
|
+#ifdef _WIN32
|
|
+# include <ws2tcpip.h>
|
|
+#else
|
|
+# include <sys/socket.h>
|
|
+#endif
|
|
#include <openssl/ssl.h>
|
|
#include "h2o/memory.h"
|
|
|
|
diff --git a/include/h2o/socketpool.h b/include/h2o/socketpool.h
|
|
index 1220c96..d84091f 100644
|
|
--- a/include/h2o/socketpool.h
|
|
+++ b/include/h2o/socketpool.h
|
|
@@ -26,8 +26,10 @@
|
|
extern "C" {
|
|
#endif
|
|
|
|
+#ifndef _WIN32
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
+#endif
|
|
#include <pthread.h>
|
|
#include "h2o/linklist.h"
|
|
#include "h2o/multithread.h"
|
|
diff --git a/lib/common/http1client.c b/lib/common/http1client.c
|
|
index fb5dcee..3a60a67 100644
|
|
--- a/lib/common/http1client.c
|
|
+++ b/lib/common/http1client.c
|
|
@@ -19,11 +19,21 @@
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
-#include <arpa/inet.h>
|
|
-#include <netdb.h>
|
|
-#include <netinet/in.h>
|
|
-#include <sys/socket.h>
|
|
-#include <sys/types.h>
|
|
+#ifdef _WIN32
|
|
+# include <ws2tcpip.h>
|
|
+# ifndef AI_ADDRCONFIG
|
|
+# define AI_ADDRCONFIG 0
|
|
+# endif
|
|
+# ifndef AI_NUMERICSERV
|
|
+# define AI_NUMERICSERV 8
|
|
+# endif
|
|
+#else
|
|
+# include <arpa/inet.h>
|
|
+# include <netdb.h>
|
|
+# include <netinet/in.h>
|
|
+# include <sys/socket.h>
|
|
+# include <sys/types.h>
|
|
+#endif
|
|
#include "picohttpparser.h"
|
|
#include "h2o/string_.h"
|
|
#include "h2o/hostinfo.h"
|
|
diff --git a/lib/common/multithread.c b/lib/common/multithread.c
|
|
index c20ca55..0862829 100644
|
|
--- a/lib/common/multithread.c
|
|
+++ b/lib/common/multithread.c
|
|
@@ -87,11 +87,16 @@ static void init_async(h2o_multithread_queue_t *queue, h2o_loop_t *loop)
|
|
{
|
|
int fds[2];
|
|
|
|
+#ifndef _WIN32
|
|
if (cloexec_pipe(fds) != 0) {
|
|
perror("pipe");
|
|
abort();
|
|
}
|
|
fcntl(fds[1], F_SETFL, O_NONBLOCK);
|
|
+#else
|
|
+ u_long nonblock = 1;
|
|
+ ioctlsocket(fds[1], FIONBIO, &nonblock);
|
|
+#endif
|
|
queue->async.write = fds[1];
|
|
queue->async.read = h2o_evloop_socket_create(loop, fds[0], NULL, 0, 0);
|
|
queue->async.read->data = queue;
|
|
diff --git a/lib/common/socket.c b/lib/common/socket.c
|
|
index 9a427c0..b0618fe 100644
|
|
--- a/lib/common/socket.c
|
|
+++ b/lib/common/socket.c
|
|
@@ -22,9 +22,14 @@
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <limits.h>
|
|
-#include <netdb.h>
|
|
#include <string.h>
|
|
-#include <sys/un.h>
|
|
+#ifdef _WIN32
|
|
+# include <ws2tcpip.h>
|
|
+# define IOV_MAX 65536
|
|
+#else
|
|
+# include <netdb.h>
|
|
+# include <sys/un.h>
|
|
+#endif
|
|
#include <unistd.h>
|
|
#include <openssl/err.h>
|
|
#include "h2o/socket.h"
|
|
@@ -404,12 +409,16 @@ int h2o_socket_compare_address(struct sockaddr *x, struct sockaddr *y)
|
|
|
|
CMP(x->sa_family, y->sa_family);
|
|
|
|
+#ifndef _WIN32
|
|
if (x->sa_family == AF_UNIX) {
|
|
struct sockaddr_un *xun = (void *)x, *yun = (void *)y;
|
|
int r = strcmp(xun->sun_path, yun->sun_path);
|
|
if (r != 0)
|
|
return r;
|
|
- } else if (x->sa_family == AF_INET) {
|
|
+ } else
|
|
+#endif
|
|
+
|
|
+ if (x->sa_family == AF_INET) {
|
|
struct sockaddr_in *xin = (void *)x, *yin = (void *)y;
|
|
CMP(ntohl(xin->sin_addr.s_addr), ntohl(yin->sin_addr.s_addr));
|
|
CMP(ntohs(xin->sin_port), ntohs(yin->sin_port));
|
|
diff --git a/lib/common/socket/evloop.c.h b/lib/common/socket/evloop.c.h
|
|
index bfb6f62..fb859e1 100644
|
|
--- a/lib/common/socket/evloop.c.h
|
|
+++ b/lib/common/socket/evloop.c.h
|
|
@@ -19,11 +19,37 @@
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
+
|
|
+#include <stdlib.h>
|
|
+#ifdef _WIN32
|
|
+
|
|
+struct iovec {
|
|
+ char *buf;
|
|
+ unsigned long len;
|
|
+};
|
|
+
|
|
+static ssize_t
|
|
+writev(SOCKET fd, const struct iovec *iov, int iovcnt) {
|
|
+ DWORD sent = 0;
|
|
+ h2o_iovec_t* psend = (h2o_iovec_t*) iov;
|
|
+ LPWSABUF pbuf = alloca(sizeof(WSABUF) * iovcnt);
|
|
+ int i;
|
|
+ for (i = 0; i < iovcnt; ++i) {
|
|
+ pbuf[i].len = psend[i].len;
|
|
+ pbuf[i].buf = psend[i].base;
|
|
+ sent += pbuf[i].len;
|
|
+ }
|
|
+ if (WSASend(fd, pbuf, iovcnt, NULL, 0, NULL, NULL) == 0)
|
|
+ return (ssize_t) sent;
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+#else
|
|
#include <netinet/in.h>
|
|
#include <netinet/tcp.h>
|
|
-#include <stdlib.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/uio.h>
|
|
+#endif
|
|
#include <unistd.h>
|
|
#include "cloexec.h"
|
|
#include "h2o/linklist.h"
|
|
@@ -358,7 +384,12 @@ struct st_h2o_evloop_socket_t *create_socket(h2o_evloop_t *loop, int fd, struct
|
|
{
|
|
struct st_h2o_evloop_socket_t *sock;
|
|
|
|
+#ifdef _WIN32
|
|
+ u_long nonblock = 1;
|
|
+ ioctlsocket(fd, FIONBIO, &nonblock);
|
|
+#else
|
|
fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
+#endif
|
|
|
|
sock = h2o_mem_alloc(sizeof(*sock));
|
|
memset(sock, 0, sizeof(*sock));
|
|
@@ -381,14 +412,23 @@ struct st_h2o_evloop_socket_t *create_socket(h2o_evloop_t *loop, int fd, struct
|
|
static struct st_h2o_evloop_socket_t *create_socket_set_nodelay(h2o_evloop_t *loop, int fd, struct sockaddr *addr,
|
|
socklen_t addrlen, int flags)
|
|
{
|
|
+#ifdef _WIN32
|
|
+ char on = 1;
|
|
+#else
|
|
int on = 1;
|
|
+#endif
|
|
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
|
return create_socket(loop, fd, addr, addrlen, flags);
|
|
}
|
|
|
|
h2o_socket_t *h2o_evloop_socket_create(h2o_evloop_t *loop, int fd, struct sockaddr *addr, socklen_t addrlen, int flags)
|
|
{
|
|
+#ifdef _WIN32
|
|
+ u_long nonblock = 1;
|
|
+ ioctlsocket(fd, FIONBIO, &nonblock);
|
|
+#else
|
|
fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
+#endif
|
|
return &create_socket(loop, fd, addr, addrlen, flags)->super;
|
|
}
|
|
|
|
@@ -405,7 +445,13 @@ h2o_socket_t *h2o_evloop_socket_accept(h2o_socket_t *_listener)
|
|
#else
|
|
if ((fd = cloexec_accept(listener->fd, (void *)&addr, &addrlen)) == -1)
|
|
return NULL;
|
|
+
|
|
+# ifdef _WIN32
|
|
+ u_long nonblock = 1;
|
|
+ ioctlsocket(fd, FIONBIO, &nonblock);
|
|
+# else
|
|
fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
+# endif
|
|
#endif
|
|
|
|
return &create_socket_set_nodelay(listener->loop, fd, (void *)&addr, addrlen, 0)->super;
|
|
@@ -418,7 +464,14 @@ h2o_socket_t *h2o_socket_connect(h2o_loop_t *loop, struct sockaddr *addr, sockle
|
|
|
|
if ((fd = cloexec_socket(addr->sa_family, SOCK_STREAM, 0)) == -1)
|
|
return NULL;
|
|
+
|
|
+#ifdef _WIN32
|
|
+ u_long nonblock = 1;
|
|
+ ioctlsocket(fd, FIONBIO, &nonblock);
|
|
+#else
|
|
fcntl(fd, F_SETFL, O_NONBLOCK);
|
|
+#endif
|
|
+
|
|
if (!(connect(fd, addr, addrlen) == 0 || errno == EINPROGRESS)) {
|
|
close(fd);
|
|
return NULL;
|
|
@@ -475,7 +528,11 @@ static void run_socket(struct st_h2o_evloop_socket_t *sock)
|
|
}
|
|
|
|
if (sock->super._cb.write != NULL && sock->_wreq.cnt == 0) {
|
|
+#ifdef _WIN32
|
|
+ char status;
|
|
+#else
|
|
int status;
|
|
+#endif
|
|
if ((sock->_flags & H2O_SOCKET_FLAG_IS_CONNECTING) != 0) {
|
|
socklen_t l = sizeof(status);
|
|
getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &status, &l);
|
|
diff --git a/lib/common/socket/evloop/select.c.h b/lib/common/socket/evloop/select.c.h
|
|
index 2036178..ef3eac5 100644
|
|
--- a/lib/common/socket/evloop/select.c.h
|
|
+++ b/lib/common/socket/evloop/select.c.h
|
|
@@ -20,7 +20,9 @@
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
#include <stdio.h>
|
|
+#ifndef _WIN32
|
|
#include <sys/select.h>
|
|
+#endif
|
|
|
|
#if 0
|
|
#define DEBUG_LOG(...) fprintf(stderr, __VA_ARGS__)
|
|
diff --git a/lib/common/socketpool.c b/lib/common/socketpool.c
|
|
index 4fb8051..be035fe 100644
|
|
--- a/lib/common/socketpool.c
|
|
+++ b/lib/common/socketpool.c
|
|
@@ -20,11 +20,21 @@
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
#include <assert.h>
|
|
+#ifdef _WIN32
|
|
+# include <ws2tcpip.h>
|
|
+# ifndef AI_ADDRCONFIG
|
|
+# define AI_ADDRCONFIG 0
|
|
+# endif
|
|
+# ifndef AI_NUMERICSERV
|
|
+# define AI_NUMERICSERV 8
|
|
+# endif
|
|
+#else
|
|
#include <netdb.h>
|
|
#include <stdlib.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <netinet/in.h>
|
|
+#endif
|
|
#include "h2o/hostinfo.h"
|
|
#include "h2o/linklist.h"
|
|
#include "h2o/socketpool.h"
|
|
diff --git a/lib/core/proxy.c b/lib/core/proxy.c
|
|
index 386d4cc..1d612ac 100644
|
|
--- a/lib/core/proxy.c
|
|
+++ b/lib/core/proxy.c
|
|
@@ -19,10 +19,12 @@
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
-#include <netdb.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
+#ifndef _WIN32
|
|
+#include <netdb.h>
|
|
#include <sys/socket.h>
|
|
+#endif
|
|
#include "picohttpparser.h"
|
|
#include "h2o.h"
|
|
#include "h2o/http1client.h"
|
|
diff --git a/lib/handler/access_log.c b/lib/handler/access_log.c
|
|
index 1100c22..dc1fd2d 100644
|
|
--- a/lib/handler/access_log.c
|
|
+++ b/lib/handler/access_log.c
|
|
@@ -21,13 +21,15 @@
|
|
*/
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#ifndef _WIN32
|
|
#include <netdb.h>
|
|
#include <netinet/in.h>
|
|
#include <spawn.h>
|
|
-#include <stdio.h>
|
|
-#include <stdlib.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
+#endif
|
|
#include "h2o.h"
|
|
#include "h2o/serverutil.h"
|
|
|
|
@@ -397,6 +399,7 @@ int h2o_access_log_open_log(const char *path)
|
|
{
|
|
int fd;
|
|
|
|
+#ifndef _WIN32
|
|
if (path[0] == '|') {
|
|
int pipefds[2];
|
|
pid_t pid;
|
|
@@ -422,11 +425,16 @@ int h2o_access_log_open_log(const char *path)
|
|
close(pipefds[0]);
|
|
fd = pipefds[1];
|
|
} else {
|
|
+#else
|
|
+#define O_CLOEXEC 0
|
|
+#endif
|
|
if ((fd = open(path, O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC, 0644)) == -1) {
|
|
fprintf(stderr, "failed to open log file:%s:%s\n", path, strerror(errno));
|
|
return -1;
|
|
}
|
|
+#ifndef _WIN32
|
|
}
|
|
+#endif
|
|
|
|
return fd;
|
|
}
|
|
diff --git a/lib/handler/configurator/fastcgi.c b/lib/handler/configurator/fastcgi.c
|
|
index 320e401..3bd637a 100644
|
|
--- a/lib/handler/configurator/fastcgi.c
|
|
+++ b/lib/handler/configurator/fastcgi.c
|
|
@@ -19,15 +19,17 @@
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
-#include <arpa/inet.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <inttypes.h>
|
|
-#include <netinet/in.h>
|
|
-#include <netinet/tcp.h>
|
|
#include <stdlib.h>
|
|
#include <sys/stat.h>
|
|
+#ifndef _WIN32
|
|
+#include <arpa/inet.h>
|
|
+#include <netinet/in.h>
|
|
+#include <netinet/tcp.h>
|
|
#include <sys/un.h>
|
|
+#endif
|
|
#include "h2o.h"
|
|
#include "h2o/configurator.h"
|
|
#include "h2o/serverutil.h"
|
|
@@ -120,6 +122,7 @@ static int on_config_connect(h2o_configurator_command_t *cmd, h2o_configurator_c
|
|
return -1;
|
|
}
|
|
|
|
+#ifndef _WIN32
|
|
if (strcmp(type, "unix") == 0) {
|
|
/* unix socket */
|
|
struct sockaddr_un sun = {};
|
|
@@ -130,7 +133,10 @@ static int on_config_connect(h2o_configurator_command_t *cmd, h2o_configurator_c
|
|
sun.sun_family = AF_UNIX;
|
|
strcpy(sun.sun_path, servname);
|
|
h2o_fastcgi_register_by_address(ctx->pathconf, (void *)&sun, sizeof(sun), self->vars);
|
|
- } else if (strcmp(type, "tcp") == 0) {
|
|
+ } else
|
|
+#endif
|
|
+
|
|
+ if (strcmp(type, "tcp") == 0) {
|
|
/* tcp socket */
|
|
uint16_t port;
|
|
if (sscanf(servname, "%" SCNu16, &port) != 1) {
|
|
@@ -146,6 +152,7 @@ static int on_config_connect(h2o_configurator_command_t *cmd, h2o_configurator_c
|
|
return 0;
|
|
}
|
|
|
|
+#ifndef _WIN32
|
|
static int create_spawnproc(h2o_configurator_command_t *cmd, yoml_t *node, const char *dirname, char **argv,
|
|
struct sockaddr_un *sun)
|
|
{
|
|
@@ -206,6 +213,7 @@ Error:
|
|
unlink(sun->sun_path);
|
|
return -1;
|
|
}
|
|
+#endif
|
|
|
|
void spawnproc_on_dispose(h2o_fastcgi_handler_t *handler, void *data)
|
|
{
|
|
@@ -213,6 +221,7 @@ void spawnproc_on_dispose(h2o_fastcgi_handler_t *handler, void *data)
|
|
close(pipe_fd);
|
|
}
|
|
|
|
+#ifndef _WIN32
|
|
static int on_config_spawn(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node)
|
|
{
|
|
struct fastcgi_configurator_t *self = (void *)cmd->configurator;
|
|
@@ -248,6 +257,7 @@ Exit:
|
|
free(argv[0]);
|
|
return ret;
|
|
}
|
|
+#endif
|
|
|
|
static int on_config_enter(h2o_configurator_t *_self, h2o_configurator_context_t *ctx, yoml_t *node)
|
|
{
|
|
@@ -282,10 +292,12 @@ void h2o_fastcgi_register_configurator(h2o_globalconf_t *conf)
|
|
h2o_configurator_define_command(&c->super, "fastcgi.connect",
|
|
H2O_CONFIGURATOR_FLAG_PATH | H2O_CONFIGURATOR_FLAG_EXTENSION | H2O_CONFIGURATOR_FLAG_DEFERRED,
|
|
on_config_connect);
|
|
+#ifndef _WIN32
|
|
h2o_configurator_define_command(&c->super, "fastcgi.spawn",
|
|
H2O_CONFIGURATOR_FLAG_PATH | H2O_CONFIGURATOR_FLAG_EXTENSION | H2O_CONFIGURATOR_FLAG_DEFERRED
|
|
| H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR,
|
|
on_config_spawn);
|
|
+#endif
|
|
h2o_configurator_define_command(&c->super, "fastcgi.timeout.io",
|
|
H2O_CONFIGURATOR_FLAG_ALL_LEVELS | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR, on_config_timeout_io);
|
|
h2o_configurator_define_command(&c->super, "fastcgi.timeout.keepalive",
|
|
diff --git a/src/main.c b/src/main.c
|
|
index 82e834d..4ba83db 100644
|
|
--- a/src/main.c
|
|
+++ b/src/main.c
|
|
@@ -21,35 +21,52 @@
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
-#include <arpa/inet.h>
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <getopt.h>
|
|
#include <inttypes.h>
|
|
#include <limits.h>
|
|
-#include <netdb.h>
|
|
-#include <netinet/in.h>
|
|
-#include <netinet/tcp.h>
|
|
#include <pthread.h>
|
|
-#include <pwd.h>
|
|
#include <signal.h>
|
|
-#include <spawn.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
-#include <sys/resource.h>
|
|
#include <sys/stat.h>
|
|
-#include <sys/socket.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
-#include <sys/un.h>
|
|
-#include <sys/wait.h>
|
|
#include <openssl/crypto.h>
|
|
#include <openssl/err.h>
|
|
#include <openssl/ssl.h>
|
|
#ifdef __linux__
|
|
#include <execinfo.h>
|
|
#endif
|
|
+#ifdef _WIN32
|
|
+# include <winsock2.h>
|
|
+# ifndef AI_ADDRCONFIG
|
|
+# define AI_ADDRCONFIG 0
|
|
+# endif
|
|
+# ifndef AI_NUMERICSERV
|
|
+# define AI_NUMERICSERV 8
|
|
+# endif
|
|
+# include <stdlib.h>
|
|
+# define WEXITSTATUS(val) ((val) & 255)
|
|
+# define WIFEXITED(val) (((val) & 0xC0000000) == 0)
|
|
+# define WIFSIGNALED(val) (((val) & 0xC0000000) != 0)
|
|
+# define WTERMSIG(val) ((val > 0xC0000200) ? val - 0xC0000200 : val)
|
|
+# define WIFSTOPPED(val) (0)
|
|
+# define WSTOPSIG(var) (0)
|
|
+#else
|
|
+# include <arpa/inet.h>
|
|
+# include <netdb.h>
|
|
+# include <netinet/in.h>
|
|
+# include <netinet/tcp.h>
|
|
+# include <pwd.h>
|
|
+# include <spawn.h>
|
|
+# include <sys/resource.h>
|
|
+# include <sys/socket.h>
|
|
+# include <sys/wait.h>
|
|
+# include <sys/un.h>
|
|
+#endif
|
|
#include "cloexec.h"
|
|
#include "yoml-parser.h"
|
|
#include "h2o.h"
|
|
@@ -155,10 +172,12 @@ static struct {
|
|
|
|
static void set_cloexec(int fd)
|
|
{
|
|
+#ifndef _WIN32
|
|
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
|
|
perror("failed to set FD_CLOEXEC");
|
|
abort();
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
static int on_openssl_print_errors(const char *str, size_t len, void *fp)
|
|
@@ -682,6 +701,7 @@ Found:
|
|
return conf.server_starter.fds[i];
|
|
}
|
|
|
|
+#ifndef _WIN32
|
|
static int open_unix_listener(h2o_configurator_command_t *cmd, yoml_t *node, struct sockaddr_un *sun)
|
|
{
|
|
struct stat st;
|
|
@@ -708,6 +728,7 @@ static int open_unix_listener(h2o_configurator_command_t *cmd, yoml_t *node, str
|
|
|
|
return fd;
|
|
}
|
|
+#endif
|
|
|
|
static int open_tcp_listener(h2o_configurator_command_t *cmd, yoml_t *node, const char *hostname, const char *servname, int domain,
|
|
int type, int protocol, struct sockaddr *addr, socklen_t addrlen)
|
|
@@ -718,13 +739,21 @@ static int open_tcp_listener(h2o_configurator_command_t *cmd, yoml_t *node, cons
|
|
goto Error;
|
|
set_cloexec(fd);
|
|
{ /* set reuseaddr */
|
|
+#ifdef _WIN32
|
|
+ char flag = 1;
|
|
+#else
|
|
int flag = 1;
|
|
+#endif
|
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) != 0)
|
|
goto Error;
|
|
}
|
|
#ifdef TCP_DEFER_ACCEPT
|
|
{ /* set TCP_DEFER_ACCEPT */
|
|
+#ifdef _WIN32
|
|
+ char flag = 1;
|
|
+#else
|
|
int flag = 1;
|
|
+#endif
|
|
if (setsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &flag, sizeof(flag)) != 0)
|
|
goto Error;
|
|
}
|
|
@@ -732,7 +761,11 @@ static int open_tcp_listener(h2o_configurator_command_t *cmd, yoml_t *node, cons
|
|
#ifdef IPV6_V6ONLY
|
|
/* set IPv6only */
|
|
if (domain == AF_INET6) {
|
|
+#ifdef _WIN32
|
|
+ char flag = 1;
|
|
+#else
|
|
int flag = 1;
|
|
+#endif
|
|
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) != 0)
|
|
goto Error;
|
|
}
|
|
@@ -766,6 +799,12 @@ static int on_config_listen(h2o_configurator_command_t *cmd, h2o_configurator_co
|
|
const char *hostname = NULL, *servname = NULL, *type = "tcp";
|
|
yoml_t *ssl_node = NULL;
|
|
|
|
+#ifdef _WIN32
|
|
+ hostname = "127.0.0.1";
|
|
+ WSADATA wsaData;
|
|
+ WSAStartup(MAKEWORD(2, 0), &wsaData);
|
|
+#endif
|
|
+
|
|
/* fetch servname (and hostname) */
|
|
switch (node->type) {
|
|
case YOML_TYPE_SCALAR:
|
|
@@ -804,6 +843,7 @@ static int on_config_listen(h2o_configurator_command_t *cmd, h2o_configurator_co
|
|
return -1;
|
|
}
|
|
|
|
+#ifndef _WIN32
|
|
if (strcmp(type, "unix") == 0) {
|
|
|
|
/* unix socket */
|
|
@@ -844,7 +884,10 @@ static int on_config_listen(h2o_configurator_command_t *cmd, h2o_configurator_co
|
|
if (listener->hosts != NULL && ctx->hostconf != NULL)
|
|
h2o_append_to_null_terminated_list((void *)&listener->hosts, ctx->hostconf);
|
|
|
|
- } else if (strcmp(type, "tcp") == 0) {
|
|
+ } else
|
|
+#endif
|
|
+
|
|
+ if (strcmp(type, "tcp") == 0) {
|
|
|
|
/* TCP socket */
|
|
struct addrinfo hints, *res, *ai;
|
|
@@ -934,6 +977,7 @@ static int on_config_listen_exit(h2o_configurator_t *_configurator, h2o_configur
|
|
return 0;
|
|
}
|
|
|
|
+#ifndef _WIN32
|
|
static int setup_running_user(const char *login)
|
|
{
|
|
struct passwd *passwdbuf = h2o_mem_alloc(sizeof(*passwdbuf));
|
|
@@ -969,6 +1013,7 @@ static int on_config_user(h2o_configurator_command_t *cmd, h2o_configurator_cont
|
|
|
|
return 0;
|
|
}
|
|
+#endif
|
|
|
|
static int on_config_pid_file(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node)
|
|
{
|
|
@@ -1115,7 +1160,10 @@ static void on_sigfatal(int signo)
|
|
static void setup_signal_handlers(void)
|
|
{
|
|
h2o_set_signal_handler(SIGTERM, on_sigterm);
|
|
+#ifndef _WIN32
|
|
h2o_set_signal_handler(SIGPIPE, SIG_IGN);
|
|
+#endif
|
|
+
|
|
#ifdef __linux__
|
|
if ((backtrace_symbols_to_fd = popen_annotate_backtrace_symbols()) == -1)
|
|
backtrace_symbols_to_fd = 2;
|
|
@@ -1320,11 +1368,13 @@ static char **build_server_starter_argv(const char *h2o_cmd, const char *config_
|
|
sprintf(newarg, "--port=%s:%s", host, serv);
|
|
}
|
|
} break;
|
|
+#ifndef _WIN32
|
|
case AF_UNIX: {
|
|
struct sockaddr_un *sun = (void *)&conf.listeners[i]->addr;
|
|
newarg = h2o_mem_alloc(sizeof("--path=") + strlen(sun->sun_path));
|
|
sprintf(newarg, "--path=%s", sun->sun_path);
|
|
} break;
|
|
+#endif
|
|
}
|
|
h2o_vector_reserve(NULL, (void *)&args, sizeof(args.entries[0]), args.size + 1);
|
|
args.entries[args.size++] = newarg;
|
|
@@ -1343,7 +1393,13 @@ static char **build_server_starter_argv(const char *h2o_cmd, const char *config_
|
|
static int run_using_server_starter(const char *h2o_cmd, const char *config_file)
|
|
{
|
|
char **args = build_server_starter_argv(h2o_cmd, config_file);
|
|
+
|
|
+#ifndef _WIN32
|
|
setenv("H2O_VIA_MASTER", "", 1);
|
|
+#else
|
|
+ putenv("H2O_VIA_MASTER=1");
|
|
+#endif
|
|
+
|
|
execvp(args[0], args);
|
|
fprintf(stderr, "failed to spawn %s:%s\n", args[0], strerror(errno));
|
|
return EX_CONFIG;
|
|
@@ -1362,8 +1418,10 @@ static void setup_configurators(void)
|
|
|
|
{
|
|
h2o_configurator_t *c = h2o_configurator_create(&conf.globalconf, sizeof(*c));
|
|
+#ifndef _WIN32
|
|
h2o_configurator_define_command(c, "user", H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR,
|
|
on_config_user);
|
|
+#endif
|
|
h2o_configurator_define_command(c, "pid-file", H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR,
|
|
on_config_pid_file);
|
|
h2o_configurator_define_command(c, "error-log", H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR,
|
|
@@ -1516,7 +1574,11 @@ int main(int argc, char **argv)
|
|
}
|
|
}
|
|
|
|
+#ifndef _WIN32
|
|
unsetenv("SERVER_STARTER_PORT");
|
|
+#else
|
|
+ putenv("SERVER_STARTER_PORT=");
|
|
+#endif
|
|
|
|
/* handle run_mode == MASTER|TEST */
|
|
switch (conf.run_mode) {
|
|
@@ -1541,6 +1603,7 @@ int main(int argc, char **argv)
|
|
conf.error_log = NULL;
|
|
}
|
|
|
|
+#ifndef _WIN32
|
|
{ /* raise RLIMIT_NOFILE */
|
|
struct rlimit limit;
|
|
if (getrlimit(RLIMIT_NOFILE, &limit) == 0) {
|
|
@@ -1554,6 +1617,7 @@ int main(int argc, char **argv)
|
|
}
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
setup_signal_handlers();
|
|
|
|
@@ -1563,6 +1627,7 @@ int main(int argc, char **argv)
|
|
return EX_CONFIG;
|
|
}
|
|
|
|
+#ifndef _WIN32
|
|
/* setuid */
|
|
if (conf.running_user != NULL) {
|
|
if (h2o_setuidgid(conf.running_user) != 0) {
|
|
@@ -1580,6 +1645,7 @@ int main(int argc, char **argv)
|
|
}
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
/* pid file must be written after setuid, since we need to remove it */
|
|
if (conf.pid_file != NULL) {
|
|
@@ -1594,6 +1660,7 @@ int main(int argc, char **argv)
|
|
|
|
/* all setup should be complete by now */
|
|
|
|
+#ifndef _WIN32
|
|
/* replace STDIN to an closed pipe */
|
|
{
|
|
int fds[2];
|
|
@@ -1605,6 +1672,7 @@ int main(int argc, char **argv)
|
|
dup2(fds[0], 0);
|
|
close(fds[0]);
|
|
}
|
|
+#endif
|
|
|
|
/* redirect STDOUT and STDERR to error_log (if specified) */
|
|
if (error_log_fd != -1) {
|
|
--
|
|
2.4.4
|
|
|