aboutsummaryrefslogtreecommitdiffstats
path: root/app/nginx/src/os/win32
diff options
context:
space:
mode:
Diffstat (limited to 'app/nginx/src/os/win32')
-rw-r--r--app/nginx/src/os/win32/nginx.icobin0 -> 1350 bytes
-rw-r--r--app/nginx/src/os/win32/nginx.rc6
-rw-r--r--app/nginx/src/os/win32/nginx_icon16.xpm24
-rw-r--r--app/nginx/src/os/win32/nginx_icon32.xpm39
-rw-r--r--app/nginx/src/os/win32/nginx_icon48.xpm55
-rw-r--r--app/nginx/src/os/win32/ngx_alloc.c44
-rw-r--r--app/nginx/src/os/win32/ngx_alloc.h27
-rw-r--r--app/nginx/src/os/win32/ngx_atomic.h69
-rw-r--r--app/nginx/src/os/win32/ngx_dlopen.c22
-rw-r--r--app/nginx/src/os/win32/ngx_dlopen.h32
-rw-r--r--app/nginx/src/os/win32/ngx_errno.c60
-rw-r--r--app/nginx/src/os/win32/ngx_errno.h71
-rw-r--r--app/nginx/src/os/win32/ngx_event_log.c99
-rw-r--r--app/nginx/src/os/win32/ngx_files.c883
-rw-r--r--app/nginx/src/os/win32/ngx_files.h273
-rw-r--r--app/nginx/src/os/win32/ngx_os.h68
-rw-r--r--app/nginx/src/os/win32/ngx_process.c238
-rw-r--r--app/nginx/src/os/win32/ngx_process.h78
-rw-r--r--app/nginx/src/os/win32/ngx_process_cycle.c1042
-rw-r--r--app/nginx/src/os/win32/ngx_process_cycle.h44
-rw-r--r--app/nginx/src/os/win32/ngx_service.c134
-rw-r--r--app/nginx/src/os/win32/ngx_shmem.c161
-rw-r--r--app/nginx/src/os/win32/ngx_shmem.h33
-rw-r--r--app/nginx/src/os/win32/ngx_socket.c34
-rw-r--r--app/nginx/src/os/win32/ngx_socket.h207
-rw-r--r--app/nginx/src/os/win32/ngx_stat.c34
-rw-r--r--app/nginx/src/os/win32/ngx_thread.c30
-rw-r--r--app/nginx/src/os/win32/ngx_thread.h27
-rw-r--r--app/nginx/src/os/win32/ngx_time.c83
-rw-r--r--app/nginx/src/os/win32/ngx_time.h51
-rw-r--r--app/nginx/src/os/win32/ngx_udp_wsarecv.c149
-rw-r--r--app/nginx/src/os/win32/ngx_user.c23
-rw-r--r--app/nginx/src/os/win32/ngx_user.h25
-rw-r--r--app/nginx/src/os/win32/ngx_win32_config.h282
-rw-r--r--app/nginx/src/os/win32/ngx_win32_init.c297
-rw-r--r--app/nginx/src/os/win32/ngx_wsarecv.c174
-rw-r--r--app/nginx/src/os/win32/ngx_wsarecv_chain.c106
-rw-r--r--app/nginx/src/os/win32/ngx_wsasend.c185
-rw-r--r--app/nginx/src/os/win32/ngx_wsasend_chain.c292
39 files changed, 5501 insertions, 0 deletions
diff --git a/app/nginx/src/os/win32/nginx.ico b/app/nginx/src/os/win32/nginx.ico
new file mode 100644
index 0000000..70f79db
--- /dev/null
+++ b/app/nginx/src/os/win32/nginx.ico
Binary files differ
diff --git a/app/nginx/src/os/win32/nginx.rc b/app/nginx/src/os/win32/nginx.rc
new file mode 100644
index 0000000..dc8b7ab
--- /dev/null
+++ b/app/nginx/src/os/win32/nginx.rc
@@ -0,0 +1,6 @@
+
+// Copyright (C) Igor Sysoev
+// Copyright (C) Nginx, Inc.
+
+
+nginx icon discardable "src\\os\\win32\\nginx.ico"
diff --git a/app/nginx/src/os/win32/nginx_icon16.xpm b/app/nginx/src/os/win32/nginx_icon16.xpm
new file mode 100644
index 0000000..45e4bad
--- /dev/null
+++ b/app/nginx/src/os/win32/nginx_icon16.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static char * nginx_xpm[] = {
+"16 16 2 2",
+/* colors */
+" c none",
+"GG c #009900",
+/* pixels */
+" ",
+" GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGG ",
+" GGGGGG GGGGGG ",
+" GGGGGG GGGGGG ",
+" GGGGGG ",
+" GGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGG GGGGGGGGGGGGGGGGGG ",
+" GGGGGG GGGGGGGGGGGGGG ",
+" GGGGGG GGGGGG ",
+" GGGGGG GGGGGG ",
+" GGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG ",
+" "
+};
diff --git a/app/nginx/src/os/win32/nginx_icon32.xpm b/app/nginx/src/os/win32/nginx_icon32.xpm
new file mode 100644
index 0000000..eb26638
--- /dev/null
+++ b/app/nginx/src/os/win32/nginx_icon32.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char * nginx_xpm[] = {
+"32 32 2 2",
+/* colors */
+" c none",
+"GG c #009900",
+/* pixels */
+" ",
+" ",
+" ",
+" ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGG ",
+" GGGGGGGGGG ",
+" GGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGG ",
+" GGGGGGGGGG GGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" ",
+" ",
+" ",
+" "
diff --git a/app/nginx/src/os/win32/nginx_icon48.xpm b/app/nginx/src/os/win32/nginx_icon48.xpm
new file mode 100644
index 0000000..c25ba0f
--- /dev/null
+++ b/app/nginx/src/os/win32/nginx_icon48.xpm
@@ -0,0 +1,55 @@
+/* XPM */
+static char * nginx_xpm[] = {
+"48 48 2 2",
+/* colors */
+" c none",
+"GG c #009900",
+/* pixels */
+" ",
+" ",
+" ",
+" ",
+" ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG ",
+" ",
+" ",
+" ",
+" ",
+" ",
diff --git a/app/nginx/src/os/win32/ngx_alloc.c b/app/nginx/src/os/win32/ngx_alloc.c
new file mode 100644
index 0000000..0c0ef30
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_alloc.c
@@ -0,0 +1,44 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+ngx_uint_t ngx_pagesize;
+ngx_uint_t ngx_pagesize_shift;
+ngx_uint_t ngx_cacheline_size;
+
+
+void *ngx_alloc(size_t size, ngx_log_t *log)
+{
+ void *p;
+
+ p = malloc(size);
+ if (p == NULL) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ "malloc(%uz) failed", size);
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, "malloc: %p:%uz", p, size);
+
+ return p;
+}
+
+
+void *ngx_calloc(size_t size, ngx_log_t *log)
+{
+ void *p;
+
+ p = ngx_alloc(size, log);
+
+ if (p) {
+ ngx_memzero(p, size);
+ }
+
+ return p;
+}
diff --git a/app/nginx/src/os/win32/ngx_alloc.h b/app/nginx/src/os/win32/ngx_alloc.h
new file mode 100644
index 0000000..5a0fa3f
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_alloc.h
@@ -0,0 +1,27 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_ALLOC_H_INCLUDED_
+#define _NGX_ALLOC_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+void *ngx_alloc(size_t size, ngx_log_t *log);
+void *ngx_calloc(size_t size, ngx_log_t *log);
+
+#define ngx_free free
+#define ngx_memalign(alignment, size, log) ngx_alloc(size, log)
+
+extern ngx_uint_t ngx_pagesize;
+extern ngx_uint_t ngx_pagesize_shift;
+extern ngx_uint_t ngx_cacheline_size;
+
+
+#endif /* _NGX_ALLOC_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_atomic.h b/app/nginx/src/os/win32/ngx_atomic.h
new file mode 100644
index 0000000..113f561
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_atomic.h
@@ -0,0 +1,69 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_ATOMIC_H_INCLUDED_
+#define _NGX_ATOMIC_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#define NGX_HAVE_ATOMIC_OPS 1
+
+typedef int32_t ngx_atomic_int_t;
+typedef uint32_t ngx_atomic_uint_t;
+typedef volatile ngx_atomic_uint_t ngx_atomic_t;
+#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
+
+
+#if defined( __WATCOMC__ ) || defined( __BORLANDC__ ) || defined(__GNUC__) \
+ || ( _MSC_VER >= 1300 )
+
+/* the new SDK headers */
+
+#define ngx_atomic_cmp_set(lock, old, set) \
+ ((ngx_atomic_uint_t) InterlockedCompareExchange((long *) lock, set, old) \
+ == old)
+
+#else
+
+/* the old MS VC6.0SP2 SDK headers */
+
+#define ngx_atomic_cmp_set(lock, old, set) \
+ (InterlockedCompareExchange((void **) lock, (void *) set, (void *) old) \
+ == (void *) old)
+
+#endif
+
+
+#define ngx_atomic_fetch_add(p, add) InterlockedExchangeAdd((long *) p, add)
+
+
+#define ngx_memory_barrier()
+
+
+#if defined( __BORLANDC__ ) || ( __WATCOMC__ < 1230 )
+
+/*
+ * Borland C++ 5.5 (tasm32) and Open Watcom C prior to 1.3
+ * do not understand the "pause" instruction
+ */
+
+#define ngx_cpu_pause()
+#else
+#define ngx_cpu_pause() __asm { pause }
+#endif
+
+
+void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);
+
+#define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
+#define ngx_unlock(lock) *(lock) = 0
+
+
+#endif /* _NGX_ATOMIC_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_dlopen.c b/app/nginx/src/os/win32/ngx_dlopen.c
new file mode 100644
index 0000000..804f49d
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_dlopen.c
@@ -0,0 +1,22 @@
+
+/*
+ * Copyright (C) Maxim Dounin
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+char *
+ngx_dlerror(void)
+{
+ u_char *p;
+ static u_char errstr[NGX_MAX_ERROR_STR];
+
+ p = ngx_strerror(ngx_errno, errstr, NGX_MAX_ERROR_STR);
+ *p = '\0';
+
+ return (char *) errstr;
+}
diff --git a/app/nginx/src/os/win32/ngx_dlopen.h b/app/nginx/src/os/win32/ngx_dlopen.h
new file mode 100644
index 0000000..0d6b405
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_dlopen.h
@@ -0,0 +1,32 @@
+
+/*
+ * Copyright (C) Maxim Dounin
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_DLOPEN_H_INCLUDED_
+#define _NGX_DLOPEN_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#define NGX_HAVE_DLOPEN 1
+
+
+#define ngx_dlopen(path) LoadLibrary((char *) path)
+#define ngx_dlopen_n "LoadLibrary()"
+
+#define ngx_dlsym(handle, symbol) (void *) GetProcAddress(handle, symbol)
+#define ngx_dlsym_n "GetProcAddress()"
+
+#define ngx_dlclose(handle) (FreeLibrary(handle) ? 0 : -1)
+#define ngx_dlclose_n "FreeLibrary()"
+
+
+char *ngx_dlerror(void);
+
+
+#endif /* _NGX_DLOPEN_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_errno.c b/app/nginx/src/os/win32/ngx_errno.c
new file mode 100644
index 0000000..b732bf4
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_errno.c
@@ -0,0 +1,60 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+u_char *
+ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
+{
+ u_int len;
+ static u_long lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
+
+ if (size == 0) {
+ return errstr;
+ }
+
+ len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, lang, (char *) errstr, size, NULL);
+
+ if (len == 0 && lang && GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND) {
+
+ /*
+ * Try to use English messages first and fallback to a language,
+ * based on locale: non-English Windows have no English messages
+ * at all. This way allows to use English messages at least on
+ * Windows with MUI.
+ */
+
+ lang = 0;
+
+ len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, err, lang, (char *) errstr, size, NULL);
+ }
+
+ if (len == 0) {
+ return ngx_snprintf(errstr, size,
+ "FormatMessage() error:(%d)", GetLastError());
+ }
+
+ /* remove ".\r\n\0" */
+ while (errstr[len] == '\0' || errstr[len] == CR
+ || errstr[len] == LF || errstr[len] == '.')
+ {
+ --len;
+ }
+
+ return &errstr[++len];
+}
+
+
+ngx_int_t
+ngx_strerror_init(void)
+{
+ return NGX_OK;
+}
diff --git a/app/nginx/src/os/win32/ngx_errno.h b/app/nginx/src/os/win32/ngx_errno.h
new file mode 100644
index 0000000..255a39d
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_errno.h
@@ -0,0 +1,71 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_ERRNO_H_INCLUDED_
+#define _NGX_ERRNO_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+typedef DWORD ngx_err_t;
+
+#define ngx_errno GetLastError()
+#define ngx_set_errno(err) SetLastError(err)
+#define ngx_socket_errno WSAGetLastError()
+#define ngx_set_socket_errno(err) WSASetLastError(err)
+
+#define NGX_EPERM ERROR_ACCESS_DENIED
+#define NGX_ENOENT ERROR_FILE_NOT_FOUND
+#define NGX_ENOPATH ERROR_PATH_NOT_FOUND
+#define NGX_ENOMEM ERROR_NOT_ENOUGH_MEMORY
+#define NGX_EACCES ERROR_ACCESS_DENIED
+/*
+ * there are two EEXIST error codes:
+ * ERROR_FILE_EXISTS used by CreateFile(CREATE_NEW),
+ * and ERROR_ALREADY_EXISTS used by CreateDirectory();
+ * MoveFile() uses both
+ */
+#define NGX_EEXIST ERROR_ALREADY_EXISTS
+#define NGX_EEXIST_FILE ERROR_FILE_EXISTS
+#define NGX_EXDEV ERROR_NOT_SAME_DEVICE
+#define NGX_ENOTDIR ERROR_PATH_NOT_FOUND
+#define NGX_EISDIR ERROR_CANNOT_MAKE
+#define NGX_ENOSPC ERROR_DISK_FULL
+#define NGX_EPIPE EPIPE
+#define NGX_EAGAIN WSAEWOULDBLOCK
+#define NGX_EINPROGRESS WSAEINPROGRESS
+#define NGX_ENOPROTOOPT WSAENOPROTOOPT
+#define NGX_EOPNOTSUPP WSAEOPNOTSUPP
+#define NGX_EADDRINUSE WSAEADDRINUSE
+#define NGX_ECONNABORTED WSAECONNABORTED
+#define NGX_ECONNRESET WSAECONNRESET
+#define NGX_ENOTCONN WSAENOTCONN
+#define NGX_ETIMEDOUT WSAETIMEDOUT
+#define NGX_ECONNREFUSED WSAECONNREFUSED
+#define NGX_ENAMETOOLONG ERROR_BAD_PATHNAME
+#define NGX_ENETDOWN WSAENETDOWN
+#define NGX_ENETUNREACH WSAENETUNREACH
+#define NGX_EHOSTDOWN WSAEHOSTDOWN
+#define NGX_EHOSTUNREACH WSAEHOSTUNREACH
+#define NGX_ENOMOREFILES ERROR_NO_MORE_FILES
+#define NGX_EILSEQ ERROR_NO_UNICODE_TRANSLATION
+#define NGX_ELOOP 0
+#define NGX_EBADF WSAEBADF
+
+#define NGX_EALREADY WSAEALREADY
+#define NGX_EINVAL WSAEINVAL
+#define NGX_EMFILE WSAEMFILE
+#define NGX_ENFILE WSAEMFILE
+
+
+u_char *ngx_strerror(ngx_err_t err, u_char *errstr, size_t size);
+ngx_int_t ngx_strerror_init(void);
+
+
+#endif /* _NGX_ERRNO_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_event_log.c b/app/nginx/src/os/win32/ngx_event_log.c
new file mode 100644
index 0000000..e11ed1e
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_event_log.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#define NGX_MAX_ERROR_STR 2048
+
+
+void ngx_cdecl
+ngx_event_log(ngx_err_t err, const char *fmt, ...)
+{
+ u_char *p, *last;
+ long types;
+ HKEY key;
+ HANDLE ev;
+ va_list args;
+ u_char text[NGX_MAX_ERROR_STR];
+ const char *msgarg[9];
+ static u_char netmsg[] = "%SystemRoot%\\System32\\netmsg.dll";
+
+ last = text + NGX_MAX_ERROR_STR;
+ p = text + GetModuleFileName(NULL, (char *) text, NGX_MAX_ERROR_STR - 50);
+
+ *p++ = ':';
+ ngx_linefeed(p);
+
+ va_start(args, fmt);
+ p = ngx_vslprintf(p, last, fmt, args);
+ va_end(args);
+
+ if (err) {
+ p = ngx_log_errno(p, last, err);
+ }
+
+ if (p > last - NGX_LINEFEED_SIZE - 1) {
+ p = last - NGX_LINEFEED_SIZE - 1;
+ }
+
+ ngx_linefeed(p);
+
+ *p = '\0';
+
+ /*
+ * we do not log errors here since we use
+ * Event Log only to log our own logs open errors
+ */
+
+ if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\nginx",
+ 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &key, NULL)
+ != 0)
+ {
+ return;
+ }
+
+ if (RegSetValueEx(key, "EventMessageFile", 0, REG_EXPAND_SZ,
+ netmsg, sizeof(netmsg) - 1)
+ != 0)
+ {
+ return;
+ }
+
+ types = EVENTLOG_ERROR_TYPE;
+
+ if (RegSetValueEx(key, "TypesSupported", 0, REG_DWORD,
+ (u_char *) &types, sizeof(long))
+ != 0)
+ {
+ return;
+ }
+
+ RegCloseKey(key);
+
+ ev = RegisterEventSource(NULL, "nginx");
+
+ msgarg[0] = (char *) text;
+ msgarg[1] = NULL;
+ msgarg[2] = NULL;
+ msgarg[3] = NULL;
+ msgarg[4] = NULL;
+ msgarg[5] = NULL;
+ msgarg[6] = NULL;
+ msgarg[7] = NULL;
+ msgarg[8] = NULL;
+
+ /*
+ * the 3299 event id in netmsg.dll has the generic message format:
+ * "%1 %2 %3 %4 %5 %6 %7 %8 %9"
+ */
+
+ ReportEvent(ev, EVENTLOG_ERROR_TYPE, 0, 3299, NULL, 9, 0, msgarg, NULL);
+
+ DeregisterEventSource(ev);
+}
diff --git a/app/nginx/src/os/win32/ngx_files.c b/app/nginx/src/os/win32/ngx_files.c
new file mode 100644
index 0000000..9ef22a5
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_files.c
@@ -0,0 +1,883 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#define NGX_UTF16_BUFLEN 256
+
+static ngx_int_t ngx_win32_check_filename(u_char *name, u_short *u,
+ size_t len);
+static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len);
+
+
+/* FILE_FLAG_BACKUP_SEMANTICS allows to obtain a handle to a directory */
+
+ngx_fd_t
+ngx_open_file(u_char *name, u_long mode, u_long create, u_long access)
+{
+ size_t len;
+ u_short *u;
+ ngx_fd_t fd;
+ ngx_err_t err;
+ u_short utf16[NGX_UTF16_BUFLEN];
+
+ len = NGX_UTF16_BUFLEN;
+ u = ngx_utf8_to_utf16(utf16, name, &len);
+
+ if (u == NULL) {
+ return INVALID_HANDLE_VALUE;
+ }
+
+ fd = INVALID_HANDLE_VALUE;
+
+ if (create == NGX_FILE_OPEN
+ && ngx_win32_check_filename(name, u, len) != NGX_OK)
+ {
+ goto failed;
+ }
+
+ fd = CreateFileW(u, mode,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+ NULL, create, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+failed:
+
+ if (u != utf16) {
+ err = ngx_errno;
+ ngx_free(u);
+ ngx_set_errno(err);
+ }
+
+ return fd;
+}
+
+
+ssize_t
+ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
+{
+ u_long n;
+ ngx_err_t err;
+ OVERLAPPED ovlp, *povlp;
+
+ ovlp.Internal = 0;
+ ovlp.InternalHigh = 0;
+ ovlp.Offset = (u_long) offset;
+ ovlp.OffsetHigh = (u_long) (offset >> 32);
+ ovlp.hEvent = NULL;
+
+ povlp = &ovlp;
+
+ if (ReadFile(file->fd, buf, size, &n, povlp) == 0) {
+ err = ngx_errno;
+
+ if (err == ERROR_HANDLE_EOF) {
+ return 0;
+ }
+
+ ngx_log_error(NGX_LOG_ERR, file->log, err,
+ "ReadFile() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ file->offset += n;
+
+ return n;
+}
+
+
+ssize_t
+ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
+{
+ u_long n;
+ OVERLAPPED ovlp, *povlp;
+
+ ovlp.Internal = 0;
+ ovlp.InternalHigh = 0;
+ ovlp.Offset = (u_long) offset;
+ ovlp.OffsetHigh = (u_long) (offset >> 32);
+ ovlp.hEvent = NULL;
+
+ povlp = &ovlp;
+
+ if (WriteFile(file->fd, buf, size, &n, povlp) == 0) {
+ ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno,
+ "WriteFile() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ if (n != size) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, 0,
+ "WriteFile() \"%s\" has written only %ul of %uz",
+ file->name.data, n, size);
+ return NGX_ERROR;
+ }
+
+ file->offset += n;
+
+ return n;
+}
+
+
+ssize_t
+ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
+ ngx_pool_t *pool)
+{
+ u_char *buf, *prev;
+ size_t size;
+ ssize_t total, n;
+
+ total = 0;
+
+ while (cl) {
+ buf = cl->buf->pos;
+ prev = buf;
+ size = 0;
+
+ /* coalesce the neighbouring bufs */
+
+ while (cl && prev == cl->buf->pos) {
+ size += cl->buf->last - cl->buf->pos;
+ prev = cl->buf->last;
+ cl = cl->next;
+ }
+
+ n = ngx_write_file(file, buf, size, offset);
+
+ if (n == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ total += n;
+ offset += n;
+ }
+
+ return total;
+}
+
+
+ssize_t
+ngx_read_fd(ngx_fd_t fd, void *buf, size_t size)
+{
+ u_long n;
+
+ if (ReadFile(fd, buf, size, &n, NULL) != 0) {
+ return (size_t) n;
+ }
+
+ return -1;
+}
+
+
+ssize_t
+ngx_write_fd(ngx_fd_t fd, void *buf, size_t size)
+{
+ u_long n;
+
+ if (WriteFile(fd, buf, size, &n, NULL) != 0) {
+ return (size_t) n;
+ }
+
+ return -1;
+}
+
+
+ssize_t
+ngx_write_console(ngx_fd_t fd, void *buf, size_t size)
+{
+ u_long n;
+
+ (void) CharToOemBuff(buf, buf, size);
+
+ if (WriteFile(fd, buf, size, &n, NULL) != 0) {
+ return (size_t) n;
+ }
+
+ return -1;
+}
+
+
+ngx_err_t
+ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log)
+{
+ u_char *name;
+ ngx_err_t err;
+ ngx_uint_t collision;
+ ngx_atomic_uint_t num;
+
+ name = ngx_alloc(to->len + 1 + NGX_ATOMIC_T_LEN + 1 + sizeof("DELETE"),
+ log);
+ if (name == NULL) {
+ return NGX_ENOMEM;
+ }
+
+ ngx_memcpy(name, to->data, to->len);
+
+ collision = 0;
+
+ /* mutex_lock() (per cache or single ?) */
+
+ for ( ;; ) {
+ num = ngx_next_temp_number(collision);
+
+ ngx_sprintf(name + to->len, ".%0muA.DELETE%Z", num);
+
+ if (MoveFile((const char *) to->data, (const char *) name) != 0) {
+ break;
+ }
+
+ collision = 1;
+
+ ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
+ "MoveFile() \"%s\" to \"%s\" failed", to->data, name);
+ }
+
+ if (MoveFile((const char *) from->data, (const char *) to->data) == 0) {
+ err = ngx_errno;
+
+ } else {
+ err = 0;
+ }
+
+ if (DeleteFile((const char *) name) == 0) {
+ ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
+ "DeleteFile() \"%s\" failed", name);
+ }
+
+ /* mutex_unlock() */
+
+ ngx_free(name);
+
+ return err;
+}
+
+
+ngx_int_t
+ngx_file_info(u_char *file, ngx_file_info_t *sb)
+{
+ size_t len;
+ long rc;
+ u_short *u;
+ ngx_err_t err;
+ WIN32_FILE_ATTRIBUTE_DATA fa;
+ u_short utf16[NGX_UTF16_BUFLEN];
+
+ len = NGX_UTF16_BUFLEN;
+
+ u = ngx_utf8_to_utf16(utf16, file, &len);
+
+ if (u == NULL) {
+ return NGX_FILE_ERROR;
+ }
+
+ rc = NGX_FILE_ERROR;
+
+ if (ngx_win32_check_filename(file, u, len) != NGX_OK) {
+ goto failed;
+ }
+
+ rc = GetFileAttributesExW(u, GetFileExInfoStandard, &fa);
+
+ sb->dwFileAttributes = fa.dwFileAttributes;
+ sb->ftCreationTime = fa.ftCreationTime;
+ sb->ftLastAccessTime = fa.ftLastAccessTime;
+ sb->ftLastWriteTime = fa.ftLastWriteTime;
+ sb->nFileSizeHigh = fa.nFileSizeHigh;
+ sb->nFileSizeLow = fa.nFileSizeLow;
+
+failed:
+
+ if (u != utf16) {
+ err = ngx_errno;
+ ngx_free(u);
+ ngx_set_errno(err);
+ }
+
+ return rc;
+}
+
+
+ngx_int_t
+ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
+{
+ uint64_t intervals;
+ FILETIME ft;
+
+ /* 116444736000000000 is commented in src/os/win32/ngx_time.c */
+
+ intervals = s * 10000000 + 116444736000000000;
+
+ ft.dwLowDateTime = (DWORD) intervals;
+ ft.dwHighDateTime = (DWORD) (intervals >> 32);
+
+ if (SetFileTime(fd, NULL, NULL, &ft) != 0) {
+ return NGX_OK;
+ }
+
+ return NGX_ERROR;
+}
+
+
+ngx_int_t
+ngx_create_file_mapping(ngx_file_mapping_t *fm)
+{
+ LARGE_INTEGER size;
+
+ fm->fd = ngx_open_file(fm->name, NGX_FILE_RDWR, NGX_FILE_TRUNCATE,
+ NGX_FILE_DEFAULT_ACCESS);
+ if (fm->fd == NGX_INVALID_FILE) {
+ ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed", fm->name);
+ return NGX_ERROR;
+ }
+
+ fm->handle = NULL;
+
+ size.QuadPart = fm->size;
+
+ if (SetFilePointerEx(fm->fd, size, NULL, FILE_BEGIN) == 0) {
+ ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+ "SetFilePointerEx(\"%s\", %uz) failed",
+ fm->name, fm->size);
+ goto failed;
+ }
+
+ if (SetEndOfFile(fm->fd) == 0) {
+ ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+ "SetEndOfFile() \"%s\" failed", fm->name);
+ goto failed;
+ }
+
+ fm->handle = CreateFileMapping(fm->fd, NULL, PAGE_READWRITE,
+ (u_long) ((off_t) fm->size >> 32),
+ (u_long) ((off_t) fm->size & 0xffffffff),
+ NULL);
+ if (fm->handle == NULL) {
+ ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+ "CreateFileMapping(%s, %uz) failed",
+ fm->name, fm->size);
+ goto failed;
+ }
+
+ fm->addr = MapViewOfFile(fm->handle, FILE_MAP_WRITE, 0, 0, 0);
+
+ if (fm->addr != NULL) {
+ return NGX_OK;
+ }
+
+ ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+ "MapViewOfFile(%uz) of file mapping \"%s\" failed",
+ fm->size, fm->name);
+
+failed:
+
+ if (fm->handle) {
+ if (CloseHandle(fm->handle) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+ "CloseHandle() of file mapping \"%s\" failed",
+ fm->name);
+ }
+ }
+
+ if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", fm->name);
+ }
+
+ return NGX_ERROR;
+}
+
+
+void
+ngx_close_file_mapping(ngx_file_mapping_t *fm)
+{
+ if (UnmapViewOfFile(fm->addr) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+ "UnmapViewOfFile(%p) of file mapping \"%s\" failed",
+ fm->addr, &fm->name);
+ }
+
+ if (CloseHandle(fm->handle) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+ "CloseHandle() of file mapping \"%s\" failed",
+ &fm->name);
+ }
+
+ if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", fm->name);
+ }
+}
+
+
+u_char *
+ngx_realpath(u_char *path, u_char *resolved)
+{
+ /* STUB */
+ return path;
+}
+
+
+ngx_int_t
+ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
+{
+ ngx_cpystrn(name->data + name->len, NGX_DIR_MASK, NGX_DIR_MASK_LEN + 1);
+
+ dir->dir = FindFirstFile((const char *) name->data, &dir->finddata);
+
+ name->data[name->len] = '\0';
+
+ if (dir->dir == INVALID_HANDLE_VALUE) {
+ return NGX_ERROR;
+ }
+
+ dir->valid_info = 1;
+ dir->ready = 1;
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_read_dir(ngx_dir_t *dir)
+{
+ if (dir->ready) {
+ dir->ready = 0;
+ return NGX_OK;
+ }
+
+ if (FindNextFile(dir->dir, &dir->finddata) != 0) {
+ dir->type = 1;
+ return NGX_OK;
+ }
+
+ return NGX_ERROR;
+}
+
+
+ngx_int_t
+ngx_close_dir(ngx_dir_t *dir)
+{
+ if (FindClose(dir->dir) == 0) {
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_open_glob(ngx_glob_t *gl)
+{
+ u_char *p;
+ size_t len;
+ ngx_err_t err;
+
+ gl->dir = FindFirstFile((const char *) gl->pattern, &gl->finddata);
+
+ if (gl->dir == INVALID_HANDLE_VALUE) {
+
+ err = ngx_errno;
+
+ if ((err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
+ && gl->test)
+ {
+ gl->no_match = 1;
+ return NGX_OK;
+ }
+
+ return NGX_ERROR;
+ }
+
+ for (p = gl->pattern; *p; p++) {
+ if (*p == '/') {
+ gl->last = p + 1 - gl->pattern;
+ }
+ }
+
+ len = ngx_strlen(gl->finddata.cFileName);
+ gl->name.len = gl->last + len;
+
+ gl->name.data = ngx_alloc(gl->name.len + 1, gl->log);
+ if (gl->name.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(gl->name.data, gl->pattern, gl->last);
+ ngx_cpystrn(gl->name.data + gl->last, (u_char *) gl->finddata.cFileName,
+ len + 1);
+
+ gl->ready = 1;
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
+{
+ size_t len;
+ ngx_err_t err;
+
+ if (gl->no_match) {
+ return NGX_DONE;
+ }
+
+ if (gl->ready) {
+ *name = gl->name;
+
+ gl->ready = 0;
+ return NGX_OK;
+ }
+
+ ngx_free(gl->name.data);
+ gl->name.data = NULL;
+
+ if (FindNextFile(gl->dir, &gl->finddata) != 0) {
+
+ len = ngx_strlen(gl->finddata.cFileName);
+ gl->name.len = gl->last + len;
+
+ gl->name.data = ngx_alloc(gl->name.len + 1, gl->log);
+ if (gl->name.data == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(gl->name.data, gl->pattern, gl->last);
+ ngx_cpystrn(gl->name.data + gl->last, (u_char *) gl->finddata.cFileName,
+ len + 1);
+
+ *name = gl->name;
+
+ return NGX_OK;
+ }
+
+ err = ngx_errno;
+
+ if (err == NGX_ENOMOREFILES) {
+ return NGX_DONE;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, gl->log, err,
+ "FindNextFile(%s) failed", gl->pattern);
+
+ return NGX_ERROR;
+}
+
+
+void
+ngx_close_glob(ngx_glob_t *gl)
+{
+ if (gl->name.data) {
+ ngx_free(gl->name.data);
+ }
+
+ if (gl->dir == INVALID_HANDLE_VALUE) {
+ return;
+ }
+
+ if (FindClose(gl->dir) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, gl->log, ngx_errno,
+ "FindClose(%s) failed", gl->pattern);
+ }
+}
+
+
+ngx_int_t
+ngx_de_info(u_char *name, ngx_dir_t *dir)
+{
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_de_link_info(u_char *name, ngx_dir_t *dir)
+{
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_read_ahead(ngx_fd_t fd, size_t n)
+{
+ return ~NGX_FILE_ERROR;
+}
+
+
+ngx_int_t
+ngx_directio_on(ngx_fd_t fd)
+{
+ return ~NGX_FILE_ERROR;
+}
+
+
+ngx_int_t
+ngx_directio_off(ngx_fd_t fd)
+{
+ return ~NGX_FILE_ERROR;
+}
+
+
+size_t
+ngx_fs_bsize(u_char *name)
+{
+ u_char root[4];
+ u_long sc, bs, nfree, ncl;
+
+ if (name[2] == ':') {
+ ngx_cpystrn(root, name, 4);
+ name = root;
+ }
+
+ if (GetDiskFreeSpace((const char *) name, &sc, &bs, &nfree, &ncl) == 0) {
+ return 512;
+ }
+
+ return sc * bs;
+}
+
+
+static ngx_int_t
+ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
+{
+ u_char *p, ch;
+ u_long n;
+ u_short *lu;
+ ngx_err_t err;
+ enum {
+ sw_start = 0,
+ sw_normal,
+ sw_after_slash,
+ sw_after_colon,
+ sw_after_dot
+ } state;
+
+ /* check for NTFS streams (":"), trailing dots and spaces */
+
+ lu = NULL;
+ state = sw_start;
+
+ for (p = name; *p; p++) {
+ ch = *p;
+
+ switch (state) {
+
+ case sw_start:
+
+ /*
+ * skip till first "/" to allow paths starting with drive and
+ * relative path, like "c:html/"
+ */
+
+ if (ch == '/' || ch == '\\') {
+ state = sw_after_slash;
+ }
+
+ break;
+
+ case sw_normal:
+
+ if (ch == ':') {
+ state = sw_after_colon;
+ break;
+ }
+
+ if (ch == '.' || ch == ' ') {
+ state = sw_after_dot;
+ break;
+ }
+
+ if (ch == '/' || ch == '\\') {
+ state = sw_after_slash;
+ break;
+ }
+
+ break;
+
+ case sw_after_slash:
+
+ if (ch == '/' || ch == '\\') {
+ break;
+ }
+
+ if (ch == '.') {
+ break;
+ }
+
+ if (ch == ':') {
+ state = sw_after_colon;
+ break;
+ }
+
+ state = sw_normal;
+ break;
+
+ case sw_after_colon:
+
+ if (ch == '/' || ch == '\\') {
+ state = sw_after_slash;
+ break;
+ }
+
+ goto invalid;
+
+ case sw_after_dot:
+
+ if (ch == '/' || ch == '\\') {
+ goto invalid;
+ }
+
+ if (ch == ':') {
+ goto invalid;
+ }
+
+ if (ch == '.' || ch == ' ') {
+ break;
+ }
+
+ state = sw_normal;
+ break;
+ }
+ }
+
+ if (state == sw_after_dot) {
+ goto invalid;
+ }
+
+ /* check if long name match */
+
+ lu = malloc(len * 2);
+ if (lu == NULL) {
+ return NGX_ERROR;
+ }
+
+ n = GetLongPathNameW(u, lu, len);
+
+ if (n == 0) {
+ goto failed;
+ }
+
+ if (n != len - 1 || _wcsicmp(u, lu) != 0) {
+ goto invalid;
+ }
+
+ ngx_free(lu);
+
+ return NGX_OK;
+
+invalid:
+
+ ngx_set_errno(NGX_ENOENT);
+
+failed:
+
+ if (lu) {
+ err = ngx_errno;
+ ngx_free(lu);
+ ngx_set_errno(err);
+ }
+
+ return NGX_ERROR;
+}
+
+
+static u_short *
+ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t *len)
+{
+ u_char *p;
+ u_short *u, *last;
+ uint32_t n;
+
+ p = utf8;
+ u = utf16;
+ last = utf16 + *len;
+
+ while (u < last) {
+
+ if (*p < 0x80) {
+ *u++ = (u_short) *p;
+
+ if (*p == 0) {
+ *len = u - utf16;
+ return utf16;
+ }
+
+ p++;
+
+ continue;
+ }
+
+ if (u + 1 == last) {
+ *len = u - utf16;
+ break;
+ }
+
+ n = ngx_utf8_decode(&p, 4);
+
+ if (n > 0x10ffff) {
+ ngx_set_errno(NGX_EILSEQ);
+ return NULL;
+ }
+
+ if (n > 0xffff) {
+ n -= 0x10000;
+ *u++ = (u_short) (0xd800 + (n >> 10));
+ *u++ = (u_short) (0xdc00 + (n & 0x03ff));
+ continue;
+ }
+
+ *u++ = (u_short) n;
+ }
+
+ /* the given buffer is not enough, allocate a new one */
+
+ u = malloc(((p - utf8) + ngx_strlen(p) + 1) * sizeof(u_short));
+ if (u == NULL) {
+ return NULL;
+ }
+
+ ngx_memcpy(u, utf16, *len * 2);
+
+ utf16 = u;
+ u += *len;
+
+ for ( ;; ) {
+
+ if (*p < 0x80) {
+ *u++ = (u_short) *p;
+
+ if (*p == 0) {
+ *len = u - utf16;
+ return utf16;
+ }
+
+ p++;
+
+ continue;
+ }
+
+ n = ngx_utf8_decode(&p, 4);
+
+ if (n > 0x10ffff) {
+ ngx_free(utf16);
+ ngx_set_errno(NGX_EILSEQ);
+ return NULL;
+ }
+
+ if (n > 0xffff) {
+ n -= 0x10000;
+ *u++ = (u_short) (0xd800 + (n >> 10));
+ *u++ = (u_short) (0xdc00 + (n & 0x03ff));
+ continue;
+ }
+
+ *u++ = (u_short) n;
+ }
+
+ /* unreachable */
+}
diff --git a/app/nginx/src/os/win32/ngx_files.h b/app/nginx/src/os/win32/ngx_files.h
new file mode 100644
index 0000000..895daea
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_files.h
@@ -0,0 +1,273 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_FILES_H_INCLUDED_
+#define _NGX_FILES_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+typedef HANDLE ngx_fd_t;
+typedef BY_HANDLE_FILE_INFORMATION ngx_file_info_t;
+typedef uint64_t ngx_file_uniq_t;
+
+
+typedef struct {
+ u_char *name;
+ size_t size;
+ void *addr;
+ ngx_fd_t fd;
+ HANDLE handle;
+ ngx_log_t *log;
+} ngx_file_mapping_t;
+
+
+typedef struct {
+ HANDLE dir;
+ WIN32_FIND_DATA finddata;
+
+ unsigned valid_info:1;
+ unsigned type:1;
+ unsigned ready:1;
+} ngx_dir_t;
+
+
+typedef struct {
+ HANDLE dir;
+ WIN32_FIND_DATA finddata;
+
+ unsigned ready:1;
+ unsigned test:1;
+ unsigned no_match:1;
+
+ u_char *pattern;
+ ngx_str_t name;
+ size_t last;
+ ngx_log_t *log;
+} ngx_glob_t;
+
+
+
+/* INVALID_FILE_ATTRIBUTES is specified but not defined at least in MSVC6SP2 */
+#ifndef INVALID_FILE_ATTRIBUTES
+#define INVALID_FILE_ATTRIBUTES 0xffffffff
+#endif
+
+/* INVALID_SET_FILE_POINTER is not defined at least in MSVC6SP2 */
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER 0xffffffff
+#endif
+
+
+#define NGX_INVALID_FILE INVALID_HANDLE_VALUE
+#define NGX_FILE_ERROR 0
+
+
+ngx_fd_t ngx_open_file(u_char *name, u_long mode, u_long create, u_long access);
+#define ngx_open_file_n "CreateFile()"
+
+#define NGX_FILE_RDONLY GENERIC_READ
+#define NGX_FILE_WRONLY GENERIC_WRITE
+#define NGX_FILE_RDWR GENERIC_READ|GENERIC_WRITE
+#define NGX_FILE_APPEND FILE_APPEND_DATA|SYNCHRONIZE
+#define NGX_FILE_NONBLOCK 0
+
+#define NGX_FILE_CREATE_OR_OPEN OPEN_ALWAYS
+#define NGX_FILE_OPEN OPEN_EXISTING
+#define NGX_FILE_TRUNCATE CREATE_ALWAYS
+
+#define NGX_FILE_DEFAULT_ACCESS 0
+#define NGX_FILE_OWNER_ACCESS 0
+
+
+#define ngx_open_tempfile(name, persistent, access) \
+ CreateFile((const char *) name, \
+ GENERIC_READ|GENERIC_WRITE, \
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, \
+ NULL, \
+ CREATE_NEW, \
+ persistent ? 0: \
+ FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, \
+ NULL);
+
+#define ngx_open_tempfile_n "CreateFile()"
+
+
+#define ngx_close_file CloseHandle
+#define ngx_close_file_n "CloseHandle()"
+
+
+ssize_t ngx_read_fd(ngx_fd_t fd, void *buf, size_t size);
+#define ngx_read_fd_n "ReadFile()"
+
+
+ssize_t ngx_write_fd(ngx_fd_t fd, void *buf, size_t size);
+#define ngx_write_fd_n "WriteFile()"
+
+
+ssize_t ngx_write_console(ngx_fd_t fd, void *buf, size_t size);
+
+
+#define ngx_linefeed(p) *p++ = CR; *p++ = LF;
+#define NGX_LINEFEED_SIZE 2
+#define NGX_LINEFEED CRLF
+
+
+#define ngx_delete_file(name) DeleteFile((const char *) name)
+#define ngx_delete_file_n "DeleteFile()"
+
+
+#define ngx_rename_file(o, n) MoveFile((const char *) o, (const char *) n)
+#define ngx_rename_file_n "MoveFile()"
+ngx_err_t ngx_win32_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_log_t *log);
+
+
+
+ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s);
+#define ngx_set_file_time_n "SetFileTime()"
+
+
+ngx_int_t ngx_file_info(u_char *filename, ngx_file_info_t *fi);
+#define ngx_file_info_n "GetFileAttributesEx()"
+
+
+#define ngx_fd_info(fd, fi) GetFileInformationByHandle(fd, fi)
+#define ngx_fd_info_n "GetFileInformationByHandle()"
+
+
+#define ngx_link_info(name, fi) ngx_file_info(name, fi)
+#define ngx_link_info_n "GetFileAttributesEx()"
+
+
+#define ngx_is_dir(fi) \
+ (((fi)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+#define ngx_is_file(fi) \
+ (((fi)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+#define ngx_is_link(fi) 0
+#define ngx_is_exec(fi) 0
+
+#define ngx_file_access(fi) 0
+
+#define ngx_file_size(fi) \
+ (((off_t) (fi)->nFileSizeHigh << 32) | (fi)->nFileSizeLow)
+#define ngx_file_fs_size(fi) ngx_file_size(fi)
+
+#define ngx_file_uniq(fi) (*(ngx_file_uniq_t *) &(fi)->nFileIndexHigh)
+
+
+/* 116444736000000000 is commented in src/os/win32/ngx_time.c */
+
+#define ngx_file_mtime(fi) \
+ (time_t) (((((unsigned __int64) (fi)->ftLastWriteTime.dwHighDateTime << 32) \
+ | (fi)->ftLastWriteTime.dwLowDateTime) \
+ - 116444736000000000) / 10000000)
+
+ngx_int_t ngx_create_file_mapping(ngx_file_mapping_t *fm);
+void ngx_close_file_mapping(ngx_file_mapping_t *fm);
+
+
+u_char *ngx_realpath(u_char *path, u_char *resolved);
+#define ngx_realpath_n ""
+#define ngx_getcwd(buf, size) GetCurrentDirectory(size, (char *) buf)
+#define ngx_getcwd_n "GetCurrentDirectory()"
+#define ngx_path_separator(c) ((c) == '/' || (c) == '\\')
+
+#define NGX_HAVE_MAX_PATH 1
+#define NGX_MAX_PATH MAX_PATH
+
+#define NGX_DIR_MASK (u_char *) "/*"
+#define NGX_DIR_MASK_LEN 2
+
+
+ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir);
+#define ngx_open_dir_n "FindFirstFile()"
+
+
+ngx_int_t ngx_read_dir(ngx_dir_t *dir);
+#define ngx_read_dir_n "FindNextFile()"
+
+
+ngx_int_t ngx_close_dir(ngx_dir_t *dir);
+#define ngx_close_dir_n "FindClose()"
+
+
+#define ngx_create_dir(name, access) CreateDirectory((const char *) name, NULL)
+#define ngx_create_dir_n "CreateDirectory()"
+
+
+#define ngx_delete_dir(name) RemoveDirectory((const char *) name)
+#define ngx_delete_dir_n "RemoveDirectory()"
+
+
+#define ngx_dir_access(a) (a)
+
+
+#define ngx_de_name(dir) ((u_char *) (dir)->finddata.cFileName)
+#define ngx_de_namelen(dir) ngx_strlen((dir)->finddata.cFileName)
+
+ngx_int_t ngx_de_info(u_char *name, ngx_dir_t *dir);
+#define ngx_de_info_n "dummy()"
+
+ngx_int_t ngx_de_link_info(u_char *name, ngx_dir_t *dir);
+#define ngx_de_link_info_n "dummy()"
+
+#define ngx_de_is_dir(dir) \
+ (((dir)->finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+#define ngx_de_is_file(dir) \
+ (((dir)->finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+#define ngx_de_is_link(dir) 0
+#define ngx_de_access(dir) 0
+#define ngx_de_size(dir) \
+ (((off_t) (dir)->finddata.nFileSizeHigh << 32) | (dir)->finddata.nFileSizeLow)
+#define ngx_de_fs_size(dir) ngx_de_size(dir)
+
+/* 116444736000000000 is commented in src/os/win32/ngx_time.c */
+
+#define ngx_de_mtime(dir) \
+ (time_t) (((((unsigned __int64) \
+ (dir)->finddata.ftLastWriteTime.dwHighDateTime << 32) \
+ | (dir)->finddata.ftLastWriteTime.dwLowDateTime) \
+ - 116444736000000000) / 10000000)
+
+
+ngx_int_t ngx_open_glob(ngx_glob_t *gl);
+#define ngx_open_glob_n "FindFirstFile()"
+
+ngx_int_t ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name);
+void ngx_close_glob(ngx_glob_t *gl);
+
+
+ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset);
+#define ngx_read_file_n "ReadFile()"
+
+ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size,
+ off_t offset);
+
+ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
+ off_t offset, ngx_pool_t *pool);
+
+ngx_int_t ngx_read_ahead(ngx_fd_t fd, size_t n);
+#define ngx_read_ahead_n "ngx_read_ahead_n"
+
+ngx_int_t ngx_directio_on(ngx_fd_t fd);
+#define ngx_directio_on_n "ngx_directio_on_n"
+
+ngx_int_t ngx_directio_off(ngx_fd_t fd);
+#define ngx_directio_off_n "ngx_directio_off_n"
+
+size_t ngx_fs_bsize(u_char *name);
+
+
+#define ngx_stdout GetStdHandle(STD_OUTPUT_HANDLE)
+#define ngx_stderr GetStdHandle(STD_ERROR_HANDLE)
+#define ngx_set_stderr(fd) SetStdHandle(STD_ERROR_HANDLE, fd)
+#define ngx_set_stderr_n "SetStdHandle(STD_ERROR_HANDLE)"
+
+
+#endif /* _NGX_FILES_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_os.h b/app/nginx/src/os/win32/ngx_os.h
new file mode 100644
index 0000000..15f5aa0
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_os.h
@@ -0,0 +1,68 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_OS_H_INCLUDED_
+#define _NGX_OS_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#define NGX_IO_SENDFILE 1
+
+
+typedef ssize_t (*ngx_recv_pt)(ngx_connection_t *c, u_char *buf, size_t size);
+typedef ssize_t (*ngx_recv_chain_pt)(ngx_connection_t *c, ngx_chain_t *in,
+ off_t limit);
+typedef ssize_t (*ngx_send_pt)(ngx_connection_t *c, u_char *buf, size_t size);
+typedef ngx_chain_t *(*ngx_send_chain_pt)(ngx_connection_t *c, ngx_chain_t *in,
+ off_t limit);
+
+typedef struct {
+ ngx_recv_pt recv;
+ ngx_recv_chain_pt recv_chain;
+ ngx_recv_pt udp_recv;
+ ngx_send_pt send;
+ ngx_send_pt udp_send;
+ ngx_send_chain_pt udp_send_chain;
+ ngx_send_chain_pt send_chain;
+ ngx_uint_t flags;
+} ngx_os_io_t;
+
+
+ngx_int_t ngx_os_init(ngx_log_t *log);
+void ngx_os_status(ngx_log_t *log);
+ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_pid_t pid);
+
+ssize_t ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
+ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
+ssize_t ngx_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
+ssize_t ngx_udp_overlapped_wsarecv(ngx_connection_t *c, u_char *buf,
+ size_t size);
+ssize_t ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit);
+ssize_t ngx_wsasend(ngx_connection_t *c, u_char *buf, size_t size);
+ssize_t ngx_overlapped_wsasend(ngx_connection_t *c, u_char *buf, size_t size);
+ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
+ off_t limit);
+ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
+ off_t limit);
+
+void ngx_cdecl ngx_event_log(ngx_err_t err, const char *fmt, ...);
+
+
+extern ngx_os_io_t ngx_os_io;
+extern ngx_uint_t ngx_ncpu;
+extern ngx_uint_t ngx_max_wsabufs;
+extern ngx_int_t ngx_max_sockets;
+extern ngx_uint_t ngx_inherited_nonblocking;
+extern ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
+extern ngx_uint_t ngx_win32_version;
+extern char ngx_unique[];
+
+
+#endif /* _NGX_OS_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_process.c b/app/nginx/src/os/win32/ngx_process.c
new file mode 100644
index 0000000..57b1ae9
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_process.c
@@ -0,0 +1,238 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+int ngx_argc;
+char **ngx_argv;
+char **ngx_os_argv;
+
+ngx_int_t ngx_last_process;
+ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
+
+
+ngx_pid_t
+ngx_spawn_process(ngx_cycle_t *cycle, char *name, ngx_int_t respawn)
+{
+ u_long rc, n, code;
+ ngx_int_t s;
+ ngx_pid_t pid;
+ ngx_exec_ctx_t ctx;
+ HANDLE events[2];
+ char file[MAX_PATH + 1];
+
+ if (respawn >= 0) {
+ s = respawn;
+
+ } else {
+ for (s = 0; s < ngx_last_process; s++) {
+ if (ngx_processes[s].handle == NULL) {
+ break;
+ }
+ }
+
+ if (s == NGX_MAX_PROCESSES) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "no more than %d processes can be spawned",
+ NGX_MAX_PROCESSES);
+ return NGX_INVALID_PID;
+ }
+ }
+
+ n = GetModuleFileName(NULL, file, MAX_PATH);
+
+ if (n == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "GetModuleFileName() failed");
+ return NGX_INVALID_PID;
+ }
+
+ file[n] = '\0';
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "GetModuleFileName: \"%s\"", file);
+
+ ctx.path = file;
+ ctx.name = name;
+ ctx.args = GetCommandLine();
+ ctx.argv = NULL;
+ ctx.envp = NULL;
+
+ pid = ngx_execute(cycle, &ctx);
+
+ if (pid == NGX_INVALID_PID) {
+ return pid;
+ }
+
+ ngx_memzero(&ngx_processes[s], sizeof(ngx_process_t));
+
+ ngx_processes[s].handle = ctx.child;
+ ngx_processes[s].pid = pid;
+ ngx_processes[s].name = name;
+
+ ngx_sprintf(ngx_processes[s].term_event, "ngx_%s_term_%P%Z", name, pid);
+ ngx_sprintf(ngx_processes[s].quit_event, "ngx_%s_quit_%P%Z", name, pid);
+ ngx_sprintf(ngx_processes[s].reopen_event, "ngx_%s_reopen_%P%Z",
+ name, pid);
+
+ events[0] = ngx_master_process_event;
+ events[1] = ctx.child;
+
+ rc = WaitForMultipleObjects(2, events, 0, 5000);
+
+ ngx_time_update();
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "WaitForMultipleObjects: %ul", rc);
+
+ switch (rc) {
+
+ case WAIT_OBJECT_0:
+
+ ngx_processes[s].term = OpenEvent(EVENT_MODIFY_STATE, 0,
+ (char *) ngx_processes[s].term_event);
+ if (ngx_processes[s].term == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "OpenEvent(\"%s\") failed",
+ ngx_processes[s].term_event);
+ goto failed;
+ }
+
+ ngx_processes[s].quit = OpenEvent(EVENT_MODIFY_STATE, 0,
+ (char *) ngx_processes[s].quit_event);
+ if (ngx_processes[s].quit == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "OpenEvent(\"%s\") failed",
+ ngx_processes[s].quit_event);
+ goto failed;
+ }
+
+ ngx_processes[s].reopen = OpenEvent(EVENT_MODIFY_STATE, 0,
+ (char *) ngx_processes[s].reopen_event);
+ if (ngx_processes[s].reopen == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "OpenEvent(\"%s\") failed",
+ ngx_processes[s].reopen_event);
+ goto failed;
+ }
+
+ if (ResetEvent(ngx_master_process_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed",
+ ngx_master_process_event_name);
+ goto failed;
+ }
+
+ break;
+
+ case WAIT_OBJECT_0 + 1:
+ if (GetExitCodeProcess(ctx.child, &code) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "GetExitCodeProcess(%P) failed", pid);
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "%s process %P exited with code %Xl",
+ name, pid, code);
+
+ goto failed;
+
+ case WAIT_TIMEOUT:
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "the event \"%s\" was not signaled for 5s",
+ ngx_master_process_event_name);
+ goto failed;
+
+ case WAIT_FAILED:
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "WaitForSingleObject(\"%s\") failed",
+ ngx_master_process_event_name);
+
+ goto failed;
+ }
+
+ if (respawn >= 0) {
+ return pid;
+ }
+
+ switch (respawn) {
+
+ case NGX_PROCESS_RESPAWN:
+ ngx_processes[s].just_spawn = 0;
+ break;
+
+ case NGX_PROCESS_JUST_RESPAWN:
+ ngx_processes[s].just_spawn = 1;
+ break;
+ }
+
+ if (s == ngx_last_process) {
+ ngx_last_process++;
+ }
+
+ return pid;
+
+failed:
+
+ if (ngx_processes[s].reopen) {
+ ngx_close_handle(ngx_processes[s].reopen);
+ }
+
+ if (ngx_processes[s].quit) {
+ ngx_close_handle(ngx_processes[s].quit);
+ }
+
+ if (ngx_processes[s].term) {
+ ngx_close_handle(ngx_processes[s].term);
+ }
+
+ TerminateProcess(ngx_processes[s].handle, 2);
+
+ if (ngx_processes[s].handle) {
+ ngx_close_handle(ngx_processes[s].handle);
+ ngx_processes[s].handle = NULL;
+ }
+
+ return NGX_INVALID_PID;
+}
+
+
+ngx_pid_t
+ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
+{
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ngx_memzero(&si, sizeof(STARTUPINFO));
+ si.cb = sizeof(STARTUPINFO);
+
+ ngx_memzero(&pi, sizeof(PROCESS_INFORMATION));
+
+ if (CreateProcess(ctx->path, ctx->args,
+ NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)
+ == 0)
+ {
+ ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
+ "CreateProcess(\"%s\") failed", ngx_argv[0]);
+
+ return 0;
+ }
+
+ ctx->child = pi.hProcess;
+
+ if (CloseHandle(pi.hThread) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CloseHandle(pi.hThread) failed");
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
+ "start %s process %P", ctx->name, pi.dwProcessId);
+
+ return pi.dwProcessId;
+}
diff --git a/app/nginx/src/os/win32/ngx_process.h b/app/nginx/src/os/win32/ngx_process.h
new file mode 100644
index 0000000..a6a5aa2
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_process.h
@@ -0,0 +1,78 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_PROCESS_H_INCLUDED_
+#define _NGX_PROCESS_H_INCLUDED_
+
+
+typedef DWORD ngx_pid_t;
+#define NGX_INVALID_PID 0
+
+
+#define ngx_getpid GetCurrentProcessId
+#define ngx_log_pid ngx_pid
+
+
+#define NGX_PROCESS_SYNC_NAME \
+ (sizeof("ngx_cache_manager_mutex_") + NGX_INT32_LEN)
+
+
+typedef uint64_t ngx_cpuset_t;
+
+
+typedef struct {
+ HANDLE handle;
+ ngx_pid_t pid;
+ char *name;
+
+ HANDLE term;
+ HANDLE quit;
+ HANDLE reopen;
+
+ u_char term_event[NGX_PROCESS_SYNC_NAME];
+ u_char quit_event[NGX_PROCESS_SYNC_NAME];
+ u_char reopen_event[NGX_PROCESS_SYNC_NAME];
+
+ unsigned just_spawn:1;
+ unsigned exiting:1;
+} ngx_process_t;
+
+
+typedef struct {
+ char *path;
+ char *name;
+ char *args;
+ char *const *argv;
+ char *const *envp;
+ HANDLE child;
+} ngx_exec_ctx_t;
+
+
+ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, char *name, ngx_int_t respawn);
+ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx);
+
+#define ngx_debug_point()
+#define ngx_sched_yield() SwitchToThread()
+
+
+#define NGX_MAX_PROCESSES (MAXIMUM_WAIT_OBJECTS - 4)
+
+#define NGX_PROCESS_RESPAWN -2
+#define NGX_PROCESS_JUST_RESPAWN -3
+
+
+extern int ngx_argc;
+extern char **ngx_argv;
+extern char **ngx_os_argv;
+
+extern ngx_int_t ngx_last_process;
+extern ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
+
+extern ngx_pid_t ngx_pid;
+
+
+#endif /* _NGX_PROCESS_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_process_cycle.c b/app/nginx/src/os/win32/ngx_process_cycle.c
new file mode 100644
index 0000000..293b967
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_process_cycle.c
@@ -0,0 +1,1042 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+#include <nginx.h>
+
+
+static void ngx_console_init(ngx_cycle_t *cycle);
+static int __stdcall ngx_console_handler(u_long type);
+static ngx_int_t ngx_create_signal_events(ngx_cycle_t *cycle);
+static ngx_int_t ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type);
+static void ngx_reopen_worker_processes(ngx_cycle_t *cycle);
+static void ngx_quit_worker_processes(ngx_cycle_t *cycle, ngx_uint_t old);
+static void ngx_terminate_worker_processes(ngx_cycle_t *cycle);
+static ngx_uint_t ngx_reap_worker(ngx_cycle_t *cycle, HANDLE h);
+static void ngx_master_process_exit(ngx_cycle_t *cycle);
+static void ngx_worker_process_cycle(ngx_cycle_t *cycle, char *mevn);
+static void ngx_worker_process_exit(ngx_cycle_t *cycle);
+static ngx_thread_value_t __stdcall ngx_worker_thread(void *data);
+static ngx_thread_value_t __stdcall ngx_cache_manager_thread(void *data);
+static void ngx_cache_manager_process_handler(void);
+static ngx_thread_value_t __stdcall ngx_cache_loader_thread(void *data);
+
+
+ngx_uint_t ngx_process;
+ngx_uint_t ngx_worker;
+ngx_pid_t ngx_pid;
+
+ngx_uint_t ngx_inherited;
+ngx_pid_t ngx_new_binary;
+
+sig_atomic_t ngx_terminate;
+sig_atomic_t ngx_quit;
+sig_atomic_t ngx_reopen;
+sig_atomic_t ngx_reconfigure;
+ngx_uint_t ngx_exiting;
+
+
+HANDLE ngx_master_process_event;
+char ngx_master_process_event_name[NGX_PROCESS_SYNC_NAME];
+
+static HANDLE ngx_stop_event;
+static char ngx_stop_event_name[NGX_PROCESS_SYNC_NAME];
+static HANDLE ngx_quit_event;
+static char ngx_quit_event_name[NGX_PROCESS_SYNC_NAME];
+static HANDLE ngx_reopen_event;
+static char ngx_reopen_event_name[NGX_PROCESS_SYNC_NAME];
+static HANDLE ngx_reload_event;
+static char ngx_reload_event_name[NGX_PROCESS_SYNC_NAME];
+
+HANDLE ngx_cache_manager_mutex;
+char ngx_cache_manager_mutex_name[NGX_PROCESS_SYNC_NAME];
+HANDLE ngx_cache_manager_event;
+
+
+void
+ngx_master_process_cycle(ngx_cycle_t *cycle)
+{
+ u_long nev, ev, timeout;
+ ngx_err_t err;
+ ngx_int_t n;
+ ngx_msec_t timer;
+ ngx_uint_t live;
+ HANDLE events[MAXIMUM_WAIT_OBJECTS];
+
+ ngx_sprintf((u_char *) ngx_master_process_event_name,
+ "ngx_master_%s%Z", ngx_unique);
+
+ if (ngx_process == NGX_PROCESS_WORKER) {
+ ngx_worker_process_cycle(cycle, ngx_master_process_event_name);
+ return;
+ }
+
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "master started");
+
+ ngx_console_init(cycle);
+
+ SetEnvironmentVariable("ngx_unique", ngx_unique);
+
+ ngx_master_process_event = CreateEvent(NULL, 1, 0,
+ ngx_master_process_event_name);
+ if (ngx_master_process_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed",
+ ngx_master_process_event_name);
+ exit(2);
+ }
+
+ if (ngx_create_signal_events(cycle) != NGX_OK) {
+ exit(2);
+ }
+
+ ngx_sprintf((u_char *) ngx_cache_manager_mutex_name,
+ "ngx_cache_manager_mutex_%s%Z", ngx_unique);
+
+ ngx_cache_manager_mutex = CreateMutex(NULL, 0,
+ ngx_cache_manager_mutex_name);
+ if (ngx_cache_manager_mutex == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateMutex(\"%s\") failed", ngx_cache_manager_mutex_name);
+ exit(2);
+ }
+
+
+ events[0] = ngx_stop_event;
+ events[1] = ngx_quit_event;
+ events[2] = ngx_reopen_event;
+ events[3] = ngx_reload_event;
+
+ ngx_close_listening_sockets(cycle);
+
+ if (ngx_start_worker_processes(cycle, NGX_PROCESS_RESPAWN) == 0) {
+ exit(2);
+ }
+
+ timer = 0;
+ timeout = INFINITE;
+
+ for ( ;; ) {
+
+ nev = 4;
+ for (n = 0; n < ngx_last_process; n++) {
+ if (ngx_processes[n].handle) {
+ events[nev++] = ngx_processes[n].handle;
+ }
+ }
+
+ if (timer) {
+ timeout = timer > ngx_current_msec ? timer - ngx_current_msec : 0;
+ }
+
+ ev = WaitForMultipleObjects(nev, events, 0, timeout);
+
+ err = ngx_errno;
+ ngx_time_update();
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "master WaitForMultipleObjects: %ul", ev);
+
+ if (ev == WAIT_OBJECT_0) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
+
+ if (ResetEvent(ngx_stop_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed", ngx_stop_event_name);
+ }
+
+ if (timer == 0) {
+ timer = ngx_current_msec + 5000;
+ }
+
+ ngx_terminate = 1;
+ ngx_quit_worker_processes(cycle, 0);
+
+ continue;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 1) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "shutting down");
+
+ if (ResetEvent(ngx_quit_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed", ngx_quit_event_name);
+ }
+
+ ngx_quit = 1;
+ ngx_quit_worker_processes(cycle, 0);
+
+ continue;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 2) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
+
+ if (ResetEvent(ngx_reopen_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed",
+ ngx_reopen_event_name);
+ }
+
+ ngx_reopen_files(cycle, -1);
+ ngx_reopen_worker_processes(cycle);
+
+ continue;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 3) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
+
+ if (ResetEvent(ngx_reload_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "ResetEvent(\"%s\") failed",
+ ngx_reload_event_name);
+ }
+
+ cycle = ngx_init_cycle(cycle);
+ if (cycle == NULL) {
+ cycle = (ngx_cycle_t *) ngx_cycle;
+ continue;
+ }
+
+ ngx_cycle = cycle;
+
+ ngx_close_listening_sockets(cycle);
+
+ if (ngx_start_worker_processes(cycle, NGX_PROCESS_JUST_RESPAWN)) {
+ ngx_quit_worker_processes(cycle, 1);
+ }
+
+ continue;
+ }
+
+ if (ev > WAIT_OBJECT_0 + 3 && ev < WAIT_OBJECT_0 + nev) {
+
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "reap worker");
+
+ live = ngx_reap_worker(cycle, events[ev]);
+
+ if (!live && (ngx_terminate || ngx_quit)) {
+ ngx_master_process_exit(cycle);
+ }
+
+ continue;
+ }
+
+ if (ev == WAIT_TIMEOUT) {
+ ngx_terminate_worker_processes(cycle);
+
+ ngx_master_process_exit(cycle);
+ }
+
+ if (ev == WAIT_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
+ "WaitForMultipleObjects() failed");
+
+ continue;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "WaitForMultipleObjects() returned unexpected value %ul", ev);
+ }
+}
+
+
+static void
+ngx_console_init(ngx_cycle_t *cycle)
+{
+ ngx_core_conf_t *ccf;
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+ if (ccf->daemon) {
+ if (FreeConsole() == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "FreeConsole() failed");
+ }
+
+ return;
+ }
+
+ if (SetConsoleCtrlHandler(ngx_console_handler, 1) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "SetConsoleCtrlHandler() failed");
+ }
+}
+
+
+static int __stdcall
+ngx_console_handler(u_long type)
+{
+ char *msg;
+
+ switch (type) {
+
+ case CTRL_C_EVENT:
+ msg = "Ctrl-C pressed, exiting";
+ break;
+
+ case CTRL_BREAK_EVENT:
+ msg = "Ctrl-Break pressed, exiting";
+ break;
+
+ case CTRL_CLOSE_EVENT:
+ msg = "console closing, exiting";
+ break;
+
+ case CTRL_LOGOFF_EVENT:
+ msg = "user logs off, exiting";
+ break;
+
+ default:
+ return 0;
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, msg);
+
+ if (ngx_stop_event == NULL) {
+ return 1;
+ }
+
+ if (SetEvent(ngx_stop_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
+ "SetEvent(\"%s\") failed", ngx_stop_event_name);
+ }
+
+ return 1;
+}
+
+
+static ngx_int_t
+ngx_create_signal_events(ngx_cycle_t *cycle)
+{
+ ngx_sprintf((u_char *) ngx_stop_event_name,
+ "Global\\ngx_stop_%s%Z", ngx_unique);
+
+ ngx_stop_event = CreateEvent(NULL, 1, 0, ngx_stop_event_name);
+ if (ngx_stop_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed", ngx_stop_event_name);
+ return NGX_ERROR;
+ }
+
+
+ ngx_sprintf((u_char *) ngx_quit_event_name,
+ "Global\\ngx_quit_%s%Z", ngx_unique);
+
+ ngx_quit_event = CreateEvent(NULL, 1, 0, ngx_quit_event_name);
+ if (ngx_quit_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed", ngx_quit_event_name);
+ return NGX_ERROR;
+ }
+
+
+ ngx_sprintf((u_char *) ngx_reopen_event_name,
+ "Global\\ngx_reopen_%s%Z", ngx_unique);
+
+ ngx_reopen_event = CreateEvent(NULL, 1, 0, ngx_reopen_event_name);
+ if (ngx_reopen_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed", ngx_reopen_event_name);
+ return NGX_ERROR;
+ }
+
+
+ ngx_sprintf((u_char *) ngx_reload_event_name,
+ "Global\\ngx_reload_%s%Z", ngx_unique);
+
+ ngx_reload_event = CreateEvent(NULL, 1, 0, ngx_reload_event_name);
+ if (ngx_reload_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"%s\") failed", ngx_reload_event_name);
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type)
+{
+ ngx_int_t n;
+ ngx_core_conf_t *ccf;
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+ for (n = 0; n < ccf->worker_processes; n++) {
+ if (ngx_spawn_process(cycle, "worker", type) == NGX_INVALID_PID) {
+ break;
+ }
+ }
+
+ return n;
+}
+
+
+static void
+ngx_reopen_worker_processes(ngx_cycle_t *cycle)
+{
+ ngx_int_t n;
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ if (ngx_processes[n].handle == NULL) {
+ continue;
+ }
+
+ if (SetEvent(ngx_processes[n].reopen) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "SetEvent(\"%s\") failed",
+ ngx_processes[n].reopen_event);
+ }
+ }
+}
+
+
+static void
+ngx_quit_worker_processes(ngx_cycle_t *cycle, ngx_uint_t old)
+{
+ ngx_int_t n;
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "process: %d %P %p e:%d j:%d",
+ n,
+ ngx_processes[n].pid,
+ ngx_processes[n].handle,
+ ngx_processes[n].exiting,
+ ngx_processes[n].just_spawn);
+
+ if (old && ngx_processes[n].just_spawn) {
+ ngx_processes[n].just_spawn = 0;
+ continue;
+ }
+
+ if (ngx_processes[n].handle == NULL) {
+ continue;
+ }
+
+ if (SetEvent(ngx_processes[n].quit) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "SetEvent(\"%s\") failed",
+ ngx_processes[n].quit_event);
+ }
+
+ ngx_processes[n].exiting = 1;
+ }
+}
+
+
+static void
+ngx_terminate_worker_processes(ngx_cycle_t *cycle)
+{
+ ngx_int_t n;
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ if (ngx_processes[n].handle == NULL) {
+ continue;
+ }
+
+ if (TerminateProcess(ngx_processes[n].handle, 0) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "TerminateProcess(\"%p\") failed",
+ ngx_processes[n].handle);
+ }
+
+ ngx_processes[n].exiting = 1;
+
+ ngx_close_handle(ngx_processes[n].reopen);
+ ngx_close_handle(ngx_processes[n].quit);
+ ngx_close_handle(ngx_processes[n].term);
+ ngx_close_handle(ngx_processes[n].handle);
+ }
+}
+
+
+static ngx_uint_t
+ngx_reap_worker(ngx_cycle_t *cycle, HANDLE h)
+{
+ u_long code;
+ ngx_int_t n;
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ if (ngx_processes[n].handle != h) {
+ continue;
+ }
+
+ if (GetExitCodeProcess(h, &code) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "GetExitCodeProcess(%P) failed",
+ ngx_processes[n].pid);
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
+ "%s process %P exited with code %Xl",
+ ngx_processes[n].name, ngx_processes[n].pid, code);
+
+ ngx_close_handle(ngx_processes[n].reopen);
+ ngx_close_handle(ngx_processes[n].quit);
+ ngx_close_handle(ngx_processes[n].term);
+ ngx_close_handle(h);
+
+ ngx_processes[n].handle = NULL;
+ ngx_processes[n].term = NULL;
+ ngx_processes[n].quit = NULL;
+ ngx_processes[n].reopen = NULL;
+
+ if (!ngx_processes[n].exiting && !ngx_terminate && !ngx_quit) {
+
+ if (ngx_spawn_process(cycle, ngx_processes[n].name, n)
+ == NGX_INVALID_PID)
+ {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "could not respawn %s", ngx_processes[n].name);
+
+ if (n == ngx_last_process - 1) {
+ ngx_last_process--;
+ }
+ }
+ }
+
+ goto found;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unknown process handle %p", h);
+
+found:
+
+ for (n = 0; n < ngx_last_process; n++) {
+
+ ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "process: %d %P %p e:%d j:%d",
+ n,
+ ngx_processes[n].pid,
+ ngx_processes[n].handle,
+ ngx_processes[n].exiting,
+ ngx_processes[n].just_spawn);
+
+ if (ngx_processes[n].handle) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+static void
+ngx_master_process_exit(ngx_cycle_t *cycle)
+{
+ ngx_uint_t i;
+
+ ngx_delete_pidfile(cycle);
+
+ ngx_close_handle(ngx_cache_manager_mutex);
+ ngx_close_handle(ngx_stop_event);
+ ngx_close_handle(ngx_quit_event);
+ ngx_close_handle(ngx_reopen_event);
+ ngx_close_handle(ngx_reload_event);
+ ngx_close_handle(ngx_master_process_event);
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit");
+
+ for (i = 0; cycle->modules[i]; i++) {
+ if (cycle->modules[i]->exit_master) {
+ cycle->modules[i]->exit_master(cycle);
+ }
+ }
+
+ ngx_destroy_pool(cycle->pool);
+
+ exit(0);
+}
+
+
+static void
+ngx_worker_process_cycle(ngx_cycle_t *cycle, char *mevn)
+{
+ char wtevn[NGX_PROCESS_SYNC_NAME];
+ char wqevn[NGX_PROCESS_SYNC_NAME];
+ char wroevn[NGX_PROCESS_SYNC_NAME];
+ HANDLE mev, events[3];
+ u_long nev, ev;
+ ngx_err_t err;
+ ngx_tid_t wtid, cmtid, cltid;
+ ngx_log_t *log;
+
+ log = cycle->log;
+
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "worker started");
+
+ ngx_sprintf((u_char *) wtevn, "ngx_worker_term_%P%Z", ngx_pid);
+ events[0] = CreateEvent(NULL, 1, 0, wtevn);
+ if (events[0] == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "CreateEvent(\"%s\") failed", wtevn);
+ goto failed;
+ }
+
+ ngx_sprintf((u_char *) wqevn, "ngx_worker_quit_%P%Z", ngx_pid);
+ events[1] = CreateEvent(NULL, 1, 0, wqevn);
+ if (events[1] == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "CreateEvent(\"%s\") failed", wqevn);
+ goto failed;
+ }
+
+ ngx_sprintf((u_char *) wroevn, "ngx_worker_reopen_%P%Z", ngx_pid);
+ events[2] = CreateEvent(NULL, 1, 0, wroevn);
+ if (events[2] == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "CreateEvent(\"%s\") failed", wroevn);
+ goto failed;
+ }
+
+ mev = OpenEvent(EVENT_MODIFY_STATE, 0, mevn);
+ if (mev == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "OpenEvent(\"%s\") failed", mevn);
+ goto failed;
+ }
+
+ if (SetEvent(mev) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "SetEvent(\"%s\") failed", mevn);
+ goto failed;
+ }
+
+
+ ngx_sprintf((u_char *) ngx_cache_manager_mutex_name,
+ "ngx_cache_manager_mutex_%s%Z", ngx_unique);
+
+ ngx_cache_manager_mutex = OpenMutex(SYNCHRONIZE, 0,
+ ngx_cache_manager_mutex_name);
+ if (ngx_cache_manager_mutex == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "OpenMutex(\"%s\") failed", ngx_cache_manager_mutex_name);
+ goto failed;
+ }
+
+ ngx_cache_manager_event = CreateEvent(NULL, 1, 0, NULL);
+ if (ngx_cache_manager_event == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "CreateEvent(\"ngx_cache_manager_event\") failed");
+ goto failed;
+ }
+
+
+ if (ngx_create_thread(&wtid, ngx_worker_thread, NULL, log) != 0) {
+ goto failed;
+ }
+
+ if (ngx_create_thread(&cmtid, ngx_cache_manager_thread, NULL, log) != 0) {
+ goto failed;
+ }
+
+ if (ngx_create_thread(&cltid, ngx_cache_loader_thread, NULL, log) != 0) {
+ goto failed;
+ }
+
+ for ( ;; ) {
+ ev = WaitForMultipleObjects(3, events, 0, INFINITE);
+
+ err = ngx_errno;
+ ngx_time_update();
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
+ "worker WaitForMultipleObjects: %ul", ev);
+
+ if (ev == WAIT_OBJECT_0) {
+ ngx_terminate = 1;
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "exiting");
+
+ if (ResetEvent(events[0]) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
+ "ResetEvent(\"%s\") failed", wtevn);
+ }
+
+ break;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 1) {
+ ngx_quit = 1;
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "gracefully shutting down");
+ break;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 2) {
+ ngx_reopen = 1;
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, "reopening logs");
+
+ if (ResetEvent(events[2]) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, log, 0,
+ "ResetEvent(\"%s\") failed", wroevn);
+ }
+
+ continue;
+ }
+
+ if (ev == WAIT_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, log, err,
+ "WaitForMultipleObjects() failed");
+
+ goto failed;
+ }
+ }
+
+ /* wait threads */
+
+ if (SetEvent(ngx_cache_manager_event) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "SetEvent(\"ngx_cache_manager_event\") failed");
+ }
+
+ events[1] = wtid;
+ events[2] = cmtid;
+
+ nev = 3;
+
+ for ( ;; ) {
+ ev = WaitForMultipleObjects(nev, events, 0, INFINITE);
+
+ err = ngx_errno;
+ ngx_time_update();
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
+ "worker exit WaitForMultipleObjects: %ul", ev);
+
+ if (ev == WAIT_OBJECT_0) {
+ break;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 1) {
+ if (nev == 2) {
+ break;
+ }
+
+ events[1] = events[2];
+ nev = 2;
+ continue;
+ }
+
+ if (ev == WAIT_OBJECT_0 + 2) {
+ nev = 2;
+ continue;
+ }
+
+ if (ev == WAIT_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, log, err,
+ "WaitForMultipleObjects() failed");
+ break;
+ }
+ }
+
+ ngx_close_handle(ngx_cache_manager_event);
+ ngx_close_handle(events[0]);
+ ngx_close_handle(events[1]);
+ ngx_close_handle(events[2]);
+ ngx_close_handle(mev);
+
+ ngx_worker_process_exit(cycle);
+
+failed:
+
+ exit(2);
+}
+
+
+static ngx_thread_value_t __stdcall
+ngx_worker_thread(void *data)
+{
+ ngx_int_t n;
+ ngx_time_t *tp;
+ ngx_cycle_t *cycle;
+
+ tp = ngx_timeofday();
+ srand((ngx_pid << 16) ^ (unsigned) tp->sec ^ tp->msec);
+
+ cycle = (ngx_cycle_t *) ngx_cycle;
+
+ for (n = 0; cycle->modules[n]; n++) {
+ if (cycle->modules[n]->init_process) {
+ if (cycle->modules[n]->init_process(cycle) == NGX_ERROR) {
+ /* fatal */
+ exit(2);
+ }
+ }
+ }
+
+ while (!ngx_quit) {
+
+ if (ngx_exiting) {
+ if (ngx_event_no_timers_left() == NGX_OK) {
+ break;
+ }
+ }
+
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "worker cycle");
+
+ ngx_process_events_and_timers(cycle);
+
+ if (ngx_terminate) {
+ return 0;
+ }
+
+ if (ngx_quit) {
+ ngx_quit = 0;
+
+ if (!ngx_exiting) {
+ ngx_exiting = 1;
+ ngx_set_shutdown_timer(cycle);
+ ngx_close_listening_sockets(cycle);
+ ngx_close_idle_connections(cycle);
+ }
+ }
+
+ if (ngx_reopen) {
+ ngx_reopen = 0;
+ ngx_reopen_files(cycle, -1);
+ }
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
+
+ return 0;
+}
+
+
+static void
+ngx_worker_process_exit(ngx_cycle_t *cycle)
+{
+ ngx_uint_t i;
+ ngx_connection_t *c;
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit");
+
+ for (i = 0; cycle->modules[i]; i++) {
+ if (cycle->modules[i]->exit_process) {
+ cycle->modules[i]->exit_process(cycle);
+ }
+ }
+
+ if (ngx_exiting) {
+ c = cycle->connections;
+ for (i = 0; i < cycle->connection_n; i++) {
+ if (c[i].fd != (ngx_socket_t) -1
+ && c[i].read
+ && !c[i].read->accept
+ && !c[i].read->channel
+ && !c[i].read->resolver)
+ {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+ "*%uA open socket #%d left in connection %ui",
+ c[i].number, c[i].fd, i);
+ }
+ }
+ }
+
+ ngx_destroy_pool(cycle->pool);
+
+ exit(0);
+}
+
+
+static ngx_thread_value_t __stdcall
+ngx_cache_manager_thread(void *data)
+{
+ u_long ev;
+ HANDLE events[2];
+ ngx_err_t err;
+ ngx_cycle_t *cycle;
+
+ cycle = (ngx_cycle_t *) ngx_cycle;
+
+ events[0] = ngx_cache_manager_event;
+ events[1] = ngx_cache_manager_mutex;
+
+ for ( ;; ) {
+ ev = WaitForMultipleObjects(2, events, 0, INFINITE);
+
+ err = ngx_errno;
+ ngx_time_update();
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+ "cache manager WaitForMultipleObjects: %ul", ev);
+
+ if (ev == WAIT_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
+ "WaitForMultipleObjects() failed");
+ }
+
+ /*
+ * ev == WAIT_OBJECT_0
+ * ev == WAIT_OBJECT_0 + 1
+ * ev == WAIT_ABANDONED_0 + 1
+ */
+
+ if (ngx_terminate || ngx_quit || ngx_exiting) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
+ return 0;
+ }
+
+ break;
+ }
+
+ for ( ;; ) {
+
+ if (ngx_terminate || ngx_quit || ngx_exiting) {
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
+ break;
+ }
+
+ ngx_cache_manager_process_handler();
+ }
+
+ if (ReleaseMutex(ngx_cache_manager_mutex) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "ReleaseMutex() failed");
+ }
+
+ return 0;
+}
+
+
+static void
+ngx_cache_manager_process_handler(void)
+{
+ u_long ev;
+ ngx_uint_t i;
+ ngx_msec_t next, n;
+ ngx_path_t **path;
+
+ next = 60 * 60 * 1000;
+
+ path = ngx_cycle->paths.elts;
+ for (i = 0; i < ngx_cycle->paths.nelts; i++) {
+
+ if (path[i]->manager) {
+ n = path[i]->manager(path[i]->data);
+
+ next = (n <= next) ? n : next;
+
+ ngx_time_update();
+ }
+ }
+
+ if (next == 0) {
+ next = 1;
+ }
+
+ ev = WaitForSingleObject(ngx_cache_manager_event, (u_long) next);
+
+ if (ev != WAIT_TIMEOUT) {
+
+ ngx_time_update();
+
+ ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
+ "cache manager WaitForSingleObject: %ul", ev);
+ }
+}
+
+
+static ngx_thread_value_t __stdcall
+ngx_cache_loader_thread(void *data)
+{
+ ngx_uint_t i;
+ ngx_path_t **path;
+ ngx_cycle_t *cycle;
+
+ ngx_msleep(60000);
+
+ cycle = (ngx_cycle_t *) ngx_cycle;
+
+ path = cycle->paths.elts;
+ for (i = 0; i < cycle->paths.nelts; i++) {
+
+ if (ngx_terminate || ngx_quit || ngx_exiting) {
+ break;
+ }
+
+ if (path[i]->loader) {
+ path[i]->loader(path[i]->data);
+ ngx_time_update();
+ }
+ }
+
+ return 0;
+}
+
+
+void
+ngx_single_process_cycle(ngx_cycle_t *cycle)
+{
+ ngx_tid_t tid;
+
+ ngx_console_init(cycle);
+
+ if (ngx_create_signal_events(cycle) != NGX_OK) {
+ exit(2);
+ }
+
+ if (ngx_create_thread(&tid, ngx_worker_thread, NULL, cycle->log) != 0) {
+ /* fatal */
+ exit(2);
+ }
+
+ /* STUB */
+ WaitForSingleObject(ngx_stop_event, INFINITE);
+}
+
+
+ngx_int_t
+ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_pid_t pid)
+{
+ HANDLE ev;
+ ngx_int_t rc;
+ char evn[NGX_PROCESS_SYNC_NAME];
+
+ ngx_sprintf((u_char *) evn, "Global\\ngx_%s_%P%Z", sig, pid);
+
+ ev = OpenEvent(EVENT_MODIFY_STATE, 0, evn);
+ if (ev == NULL) {
+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
+ "OpenEvent(\"%s\") failed", evn);
+ return 1;
+ }
+
+ if (SetEvent(ev) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "SetEvent(\"%s\") failed", evn);
+ rc = 1;
+
+ } else {
+ rc = 0;
+ }
+
+ ngx_close_handle(ev);
+
+ return rc;
+}
+
+
+void
+ngx_close_handle(HANDLE h)
+{
+ if (CloseHandle(h) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
+ "CloseHandle(%p) failed", h);
+ }
+}
diff --git a/app/nginx/src/os/win32/ngx_process_cycle.h b/app/nginx/src/os/win32/ngx_process_cycle.h
new file mode 100644
index 0000000..95d2743
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_process_cycle.h
@@ -0,0 +1,44 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_PROCESS_CYCLE_H_INCLUDED_
+#define _NGX_PROCESS_CYCLE_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#define NGX_PROCESS_SINGLE 0
+#define NGX_PROCESS_MASTER 1
+#define NGX_PROCESS_SIGNALLER 2
+#define NGX_PROCESS_WORKER 3
+
+
+void ngx_master_process_cycle(ngx_cycle_t *cycle);
+void ngx_single_process_cycle(ngx_cycle_t *cycle);
+void ngx_close_handle(HANDLE h);
+
+
+extern ngx_uint_t ngx_process;
+extern ngx_uint_t ngx_worker;
+extern ngx_pid_t ngx_pid;
+extern ngx_uint_t ngx_exiting;
+
+extern sig_atomic_t ngx_quit;
+extern sig_atomic_t ngx_terminate;
+extern sig_atomic_t ngx_reopen;
+
+extern ngx_uint_t ngx_inherited;
+extern ngx_pid_t ngx_new_binary;
+
+
+extern HANDLE ngx_master_process_event;
+extern char ngx_master_process_event_name[];
+
+
+#endif /* _NGX_PROCESS_CYCLE_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_service.c b/app/nginx/src/os/win32/ngx_service.c
new file mode 100644
index 0000000..835d9cf
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_service.c
@@ -0,0 +1,134 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+
+#define NGX_SERVICE_CONTROL_SHUTDOWN 128
+#define NGX_SERVICE_CONTROL_REOPEN 129
+
+
+SERVICE_TABLE_ENTRY st[] = {
+ { "nginx", service_main },
+ { NULL, NULL }
+};
+
+
+ngx_int_t
+ngx_service(ngx_log_t *log)
+{
+ /* primary thread */
+
+ /* StartServiceCtrlDispatcher() should be called within 30 seconds */
+
+ if (StartServiceCtrlDispatcher(st) == 0) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ "StartServiceCtrlDispatcher() failed");
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
+void
+service_main(u_int argc, char **argv)
+{
+ SERVICE_STATUS status;
+ SERVICE_STATUS_HANDLE service;
+
+ /* thread spawned by SCM */
+
+ service = RegisterServiceCtrlHandlerEx("nginx", service_handler, ctx);
+ if (service == INVALID_HANDLE_VALUE) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ "RegisterServiceCtrlHandlerEx() failed");
+ return;
+ }
+
+ status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ status.dwCurrentState = SERVICE_START_PENDING;
+ status.dwControlsAccepted = SERVICE_ACCEPT_STOP
+ |SERVICE_ACCEPT_PARAMCHANGE;
+ status.dwWin32ExitCode = NO_ERROR;
+ status.dwServiceSpecificExitCode = 0;
+ status.dwCheckPoint = 1;
+ status.dwWaitHint = 2000;
+
+ /* SetServiceStatus() should be called within 80 seconds */
+
+ if (SetServiceStatus(service, &status) == 0) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ "SetServiceStatus() failed");
+ return;
+ }
+
+ /* init */
+
+ status.dwCurrentState = SERVICE_RUNNING;
+ status.dwCheckPoint = 0;
+ status.dwWaitHint = 0;
+
+ if (SetServiceStatus(service, &status) == 0) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ "SetServiceStatus() failed");
+ return;
+ }
+
+ /* call master or worker loop */
+
+ /*
+ * master should use event notification and look status
+ * single should use iocp to get notifications from service handler
+ */
+
+}
+
+
+u_int
+service_handler(u_int control, u_int type, void *data, void *ctx)
+{
+ /* primary thread */
+
+ switch (control) {
+
+ case SERVICE_CONTROL_INTERROGATE:
+ status = NGX_IOCP_INTERROGATE;
+ break;
+
+ case SERVICE_CONTROL_STOP:
+ status = NGX_IOCP_STOP;
+ break;
+
+ case SERVICE_CONTROL_PARAMCHANGE:
+ status = NGX_IOCP_RECONFIGURE;
+ break;
+
+ case NGX_SERVICE_CONTROL_SHUTDOWN:
+ status = NGX_IOCP_REOPEN;
+ break;
+
+ case NGX_SERVICE_CONTROL_REOPEN:
+ status = NGX_IOCP_REOPEN;
+ break;
+
+ default:
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+ if (ngx_single) {
+ if (PostQueuedCompletionStatus(iocp, ... status, ...) == 0) {
+ err = ngx_errno;
+ ngx_log_error(NGX_LOG_ALERT, log, err,
+ "PostQueuedCompletionStatus() failed");
+ return err;
+ }
+
+ } else {
+ Event
+ }
+
+ return NO_ERROR;
+}
diff --git a/app/nginx/src/os/win32/ngx_shmem.c b/app/nginx/src/os/win32/ngx_shmem.c
new file mode 100644
index 0000000..c3ed699
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_shmem.c
@@ -0,0 +1,161 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+/*
+ * Base addresses selected by system for shared memory mappings are likely
+ * to be different on Windows Vista and later versions due to address space
+ * layout randomization. This is however incompatible with storing absolute
+ * addresses within the shared memory.
+ *
+ * To make it possible to store absolute addresses we create mappings
+ * at the same address in all processes by starting mappings at predefined
+ * addresses. The addresses were selected somewhat randomly in order to
+ * minimize the probability that some other library doing something similar
+ * conflicts with us. The addresses are from the following typically free
+ * blocks:
+ *
+ * - 0x10000000 .. 0x70000000 (about 1.5 GB in total) on 32-bit platforms
+ * - 0x000000007fff0000 .. 0x000007f68e8b0000 (about 8 TB) on 64-bit platforms
+ *
+ * Additionally, we allow to change the mapping address once it was detected
+ * to be different from one originally used. This is needed to support
+ * reconfiguration.
+ */
+
+
+#ifdef _WIN64
+#define NGX_SHMEM_BASE 0x0000047047e00000
+#else
+#define NGX_SHMEM_BASE 0x2efe0000
+#endif
+
+
+ngx_uint_t ngx_allocation_granularity;
+
+
+ngx_int_t
+ngx_shm_alloc(ngx_shm_t *shm)
+{
+ u_char *name;
+ uint64_t size;
+ static u_char *base = (u_char *) NGX_SHMEM_BASE;
+
+ name = ngx_alloc(shm->name.len + 2 + NGX_INT32_LEN, shm->log);
+ if (name == NULL) {
+ return NGX_ERROR;
+ }
+
+ (void) ngx_sprintf(name, "%V_%s%Z", &shm->name, ngx_unique);
+
+ ngx_set_errno(0);
+
+ size = shm->size;
+
+ shm->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
+ (u_long) (size >> 32),
+ (u_long) (size & 0xffffffff),
+ (char *) name);
+
+ if (shm->handle == NULL) {
+ ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
+ "CreateFileMapping(%uz, %s) failed",
+ shm->size, name);
+ ngx_free(name);
+
+ return NGX_ERROR;
+ }
+
+ ngx_free(name);
+
+ if (ngx_errno == ERROR_ALREADY_EXISTS) {
+ shm->exists = 1;
+ }
+
+ shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, base);
+
+ if (shm->addr != NULL) {
+ base += ngx_align(size, ngx_allocation_granularity);
+ return NGX_OK;
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, shm->log, ngx_errno,
+ "MapViewOfFileEx(%uz, %p) of file mapping \"%V\" failed, "
+ "retry without a base address",
+ shm->size, base, &shm->name);
+
+ /*
+ * Order of shared memory zones may be different in the master process
+ * and worker processes after reconfiguration. As a result, the above
+ * may fail due to a conflict with a previously created mapping remapped
+ * to a different address. Additionally, there may be a conflict with
+ * some other uses of the memory. In this case we retry without a base
+ * address to let the system assign the address itself.
+ */
+
+ shm->addr = MapViewOfFile(shm->handle, FILE_MAP_WRITE, 0, 0, 0);
+
+ if (shm->addr != NULL) {
+ return NGX_OK;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
+ "MapViewOfFile(%uz) of file mapping \"%V\" failed",
+ shm->size, &shm->name);
+
+ if (CloseHandle(shm->handle) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
+ "CloseHandle() of file mapping \"%V\" failed",
+ &shm->name);
+ }
+
+ return NGX_ERROR;
+}
+
+
+ngx_int_t
+ngx_shm_remap(ngx_shm_t *shm, u_char *addr)
+{
+ if (UnmapViewOfFile(shm->addr) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
+ "UnmapViewOfFile(%p) of file mapping \"%V\" failed",
+ shm->addr, &shm->name);
+ return NGX_ERROR;
+ }
+
+ shm->addr = MapViewOfFileEx(shm->handle, FILE_MAP_WRITE, 0, 0, 0, addr);
+
+ if (shm->addr != NULL) {
+ return NGX_OK;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
+ "MapViewOfFileEx(%uz, %p) of file mapping \"%V\" failed",
+ shm->size, addr, &shm->name);
+
+ return NGX_ERROR;
+}
+
+
+void
+ngx_shm_free(ngx_shm_t *shm)
+{
+ if (UnmapViewOfFile(shm->addr) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
+ "UnmapViewOfFile(%p) of file mapping \"%V\" failed",
+ shm->addr, &shm->name);
+ }
+
+ if (CloseHandle(shm->handle) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
+ "CloseHandle() of file mapping \"%V\" failed",
+ &shm->name);
+ }
+}
diff --git a/app/nginx/src/os/win32/ngx_shmem.h b/app/nginx/src/os/win32/ngx_shmem.h
new file mode 100644
index 0000000..ee47429
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_shmem.h
@@ -0,0 +1,33 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_SHMEM_H_INCLUDED_
+#define _NGX_SHMEM_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+typedef struct {
+ u_char *addr;
+ size_t size;
+ ngx_str_t name;
+ HANDLE handle;
+ ngx_log_t *log;
+ ngx_uint_t exists; /* unsigned exists:1; */
+} ngx_shm_t;
+
+
+ngx_int_t ngx_shm_alloc(ngx_shm_t *shm);
+ngx_int_t ngx_shm_remap(ngx_shm_t *shm, u_char *addr);
+void ngx_shm_free(ngx_shm_t *shm);
+
+extern ngx_uint_t ngx_allocation_granularity;
+
+
+#endif /* _NGX_SHMEM_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_socket.c b/app/nginx/src/os/win32/ngx_socket.c
new file mode 100644
index 0000000..05a39f4
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_socket.c
@@ -0,0 +1,34 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+int
+ngx_nonblocking(ngx_socket_t s)
+{
+ unsigned long nb = 1;
+
+ return ioctlsocket(s, FIONBIO, &nb);
+}
+
+
+int
+ngx_blocking(ngx_socket_t s)
+{
+ unsigned long nb = 0;
+
+ return ioctlsocket(s, FIONBIO, &nb);
+}
+
+
+int
+ngx_tcp_push(ngx_socket_t s)
+{
+ return 0;
+}
diff --git a/app/nginx/src/os/win32/ngx_socket.h b/app/nginx/src/os/win32/ngx_socket.h
new file mode 100644
index 0000000..a9e26c2
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_socket.h
@@ -0,0 +1,207 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_SOCKET_H_INCLUDED_
+#define _NGX_SOCKET_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#define NGX_WRITE_SHUTDOWN SD_SEND
+
+
+typedef SOCKET ngx_socket_t;
+typedef int socklen_t;
+
+
+#define ngx_socket(af, type, proto) \
+ WSASocketW(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED)
+
+#define ngx_socket_n "WSASocketW()"
+
+int ngx_nonblocking(ngx_socket_t s);
+int ngx_blocking(ngx_socket_t s);
+
+#define ngx_nonblocking_n "ioctlsocket(FIONBIO)"
+#define ngx_blocking_n "ioctlsocket(!FIONBIO)"
+
+#define ngx_shutdown_socket shutdown
+#define ngx_shutdown_socket_n "shutdown()"
+
+#define ngx_close_socket closesocket
+#define ngx_close_socket_n "closesocket()"
+
+
+#ifndef WSAID_ACCEPTEX
+
+typedef BOOL (PASCAL FAR * LPFN_ACCEPTEX)(
+ IN SOCKET sListenSocket,
+ IN SOCKET sAcceptSocket,
+ IN PVOID lpOutputBuffer,
+ IN DWORD dwReceiveDataLength,
+ IN DWORD dwLocalAddressLength,
+ IN DWORD dwRemoteAddressLength,
+ OUT LPDWORD lpdwBytesReceived,
+ IN LPOVERLAPPED lpOverlapped
+ );
+
+#define WSAID_ACCEPTEX \
+ {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
+
+#endif
+
+
+#ifndef WSAID_GETACCEPTEXSOCKADDRS
+
+typedef VOID (PASCAL FAR * LPFN_GETACCEPTEXSOCKADDRS)(
+ IN PVOID lpOutputBuffer,
+ IN DWORD dwReceiveDataLength,
+ IN DWORD dwLocalAddressLength,
+ IN DWORD dwRemoteAddressLength,
+ OUT struct sockaddr **LocalSockaddr,
+ OUT LPINT LocalSockaddrLength,
+ OUT struct sockaddr **RemoteSockaddr,
+ OUT LPINT RemoteSockaddrLength
+ );
+
+#define WSAID_GETACCEPTEXSOCKADDRS \
+ {0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
+
+#endif
+
+
+#ifndef WSAID_TRANSMITFILE
+
+#ifndef TF_DISCONNECT
+
+#define TF_DISCONNECT 1
+#define TF_REUSE_SOCKET 2
+#define TF_WRITE_BEHIND 4
+#define TF_USE_DEFAULT_WORKER 0
+#define TF_USE_SYSTEM_THREAD 16
+#define TF_USE_KERNEL_APC 32
+
+typedef struct _TRANSMIT_FILE_BUFFERS {
+ LPVOID Head;
+ DWORD HeadLength;
+ LPVOID Tail;
+ DWORD TailLength;
+} TRANSMIT_FILE_BUFFERS, *PTRANSMIT_FILE_BUFFERS, FAR *LPTRANSMIT_FILE_BUFFERS;
+
+#endif
+
+typedef BOOL (PASCAL FAR * LPFN_TRANSMITFILE)(
+ IN SOCKET hSocket,
+ IN HANDLE hFile,
+ IN DWORD nNumberOfBytesToWrite,
+ IN DWORD nNumberOfBytesPerSend,
+ IN LPOVERLAPPED lpOverlapped,
+ IN LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
+ IN DWORD dwReserved
+ );
+
+#define WSAID_TRANSMITFILE \
+ {0xb5367df0,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
+
+#endif
+
+
+#ifndef WSAID_TRANSMITPACKETS
+
+/* OpenWatcom has a swapped TP_ELEMENT_FILE and TP_ELEMENT_MEMORY definition */
+
+#ifndef TP_ELEMENT_FILE
+
+#ifdef _MSC_VER
+#pragma warning(disable:4201) /* Nonstandard extension, nameless struct/union */
+#endif
+
+typedef struct _TRANSMIT_PACKETS_ELEMENT {
+ ULONG dwElFlags;
+#define TP_ELEMENT_MEMORY 1
+#define TP_ELEMENT_FILE 2
+#define TP_ELEMENT_EOP 4
+ ULONG cLength;
+ union {
+ struct {
+ LARGE_INTEGER nFileOffset;
+ HANDLE hFile;
+ };
+ PVOID pBuffer;
+ };
+} TRANSMIT_PACKETS_ELEMENT, *PTRANSMIT_PACKETS_ELEMENT,
+ FAR *LPTRANSMIT_PACKETS_ELEMENT;
+
+#ifdef _MSC_VER
+#pragma warning(default:4201)
+#endif
+
+#endif
+
+typedef BOOL (PASCAL FAR * LPFN_TRANSMITPACKETS) (
+ SOCKET hSocket,
+ TRANSMIT_PACKETS_ELEMENT *lpPacketArray,
+ DWORD nElementCount,
+ DWORD nSendSize,
+ LPOVERLAPPED lpOverlapped,
+ DWORD dwFlags
+ );
+
+#define WSAID_TRANSMITPACKETS \
+ {0xd9689da0,0x1f90,0x11d3,{0x99,0x71,0x00,0xc0,0x4f,0x68,0xc8,0x76}}
+
+#endif
+
+
+#ifndef WSAID_CONNECTEX
+
+typedef BOOL (PASCAL FAR * LPFN_CONNECTEX) (
+ IN SOCKET s,
+ IN const struct sockaddr FAR *name,
+ IN int namelen,
+ IN PVOID lpSendBuffer OPTIONAL,
+ IN DWORD dwSendDataLength,
+ OUT LPDWORD lpdwBytesSent,
+ IN LPOVERLAPPED lpOverlapped
+ );
+
+#define WSAID_CONNECTEX \
+ {0x25a207b9,0xddf3,0x4660,{0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e}}
+
+#endif
+
+
+#ifndef WSAID_DISCONNECTEX
+
+typedef BOOL (PASCAL FAR * LPFN_DISCONNECTEX) (
+ IN SOCKET s,
+ IN LPOVERLAPPED lpOverlapped,
+ IN DWORD dwFlags,
+ IN DWORD dwReserved
+ );
+
+#define WSAID_DISCONNECTEX \
+ {0x7fda2e11,0x8630,0x436f,{0xa0,0x31,0xf5,0x36,0xa6,0xee,0xc1,0x57}}
+
+#endif
+
+
+extern LPFN_ACCEPTEX ngx_acceptex;
+extern LPFN_GETACCEPTEXSOCKADDRS ngx_getacceptexsockaddrs;
+extern LPFN_TRANSMITFILE ngx_transmitfile;
+extern LPFN_TRANSMITPACKETS ngx_transmitpackets;
+extern LPFN_CONNECTEX ngx_connectex;
+extern LPFN_DISCONNECTEX ngx_disconnectex;
+
+
+int ngx_tcp_push(ngx_socket_t s);
+#define ngx_tcp_push_n "tcp_push()"
+
+
+#endif /* _NGX_SOCKET_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_stat.c b/app/nginx/src/os/win32/ngx_stat.c
new file mode 100644
index 0000000..51bcd96
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_stat.c
@@ -0,0 +1,34 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+int ngx_file_type(char *file, ngx_file_info_t *sb)
+{
+ sb->dwFileAttributes = GetFileAttributes(file);
+
+ if (sb->dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+int ngx_stat(char *file, ngx_stat_t *sb)
+{
+ *sb = GetFileAttributes(file);
+
+ if (*sb == INVALID_FILE_ATTRIBUTES) {
+ return -1;
+ }
+
+ return 0;
+}
+*/
diff --git a/app/nginx/src/os/win32/ngx_thread.c b/app/nginx/src/os/win32/ngx_thread.c
new file mode 100644
index 0000000..a13de2d
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_thread.c
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+ngx_err_t
+ngx_create_thread(ngx_tid_t *tid,
+ ngx_thread_value_t (__stdcall *func)(void *arg), void *arg, ngx_log_t *log)
+{
+ u_long id;
+ ngx_err_t err;
+
+ *tid = CreateThread(NULL, 0, func, arg, 0, &id);
+
+ if (*tid != NULL) {
+ ngx_log_error(NGX_LOG_NOTICE, log, 0,
+ "create thread " NGX_TID_T_FMT, id);
+ return 0;
+ }
+
+ err = ngx_errno;
+ ngx_log_error(NGX_LOG_ALERT, log, err, "CreateThread() failed");
+ return err;
+}
diff --git a/app/nginx/src/os/win32/ngx_thread.h b/app/nginx/src/os/win32/ngx_thread.h
new file mode 100644
index 0000000..4012276
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_thread.h
@@ -0,0 +1,27 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_THREAD_H_INCLUDED_
+#define _NGX_THREAD_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+typedef HANDLE ngx_tid_t;
+typedef DWORD ngx_thread_value_t;
+
+
+ngx_err_t ngx_create_thread(ngx_tid_t *tid,
+ ngx_thread_value_t (__stdcall *func)(void *arg), void *arg, ngx_log_t *log);
+
+#define ngx_log_tid GetCurrentThreadId()
+#define NGX_TID_T_FMT "%ud"
+
+
+#endif /* _NGX_THREAD_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_time.c b/app/nginx/src/os/win32/ngx_time.c
new file mode 100644
index 0000000..bd6d287
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_time.c
@@ -0,0 +1,83 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+void
+ngx_gettimeofday(struct timeval *tp)
+{
+ uint64_t intervals;
+ FILETIME ft;
+
+ GetSystemTimeAsFileTime(&ft);
+
+ /*
+ * A file time is a 64-bit value that represents the number
+ * of 100-nanosecond intervals that have elapsed since
+ * January 1, 1601 12:00 A.M. UTC.
+ *
+ * Between January 1, 1970 (Epoch) and January 1, 1601 there were
+ * 134744 days,
+ * 11644473600 seconds or
+ * 11644473600,000,000,0 100-nanosecond intervals.
+ *
+ * See also MSKB Q167296.
+ */
+
+ intervals = ((uint64_t) ft.dwHighDateTime << 32) | ft.dwLowDateTime;
+ intervals -= 116444736000000000;
+
+ tp->tv_sec = (long) (intervals / 10000000);
+ tp->tv_usec = (long) ((intervals % 10000000) / 10);
+}
+
+
+void
+ngx_libc_localtime(time_t s, struct tm *tm)
+{
+ struct tm *t;
+
+ t = localtime(&s);
+ *tm = *t;
+}
+
+
+void
+ngx_libc_gmtime(time_t s, struct tm *tm)
+{
+ struct tm *t;
+
+ t = gmtime(&s);
+ *tm = *t;
+}
+
+
+ngx_int_t
+ngx_gettimezone(void)
+{
+ u_long n;
+ TIME_ZONE_INFORMATION tz;
+
+ n = GetTimeZoneInformation(&tz);
+
+ switch (n) {
+
+ case TIME_ZONE_ID_UNKNOWN:
+ return -tz.Bias;
+
+ case TIME_ZONE_ID_STANDARD:
+ return -(tz.Bias + tz.StandardBias);
+
+ case TIME_ZONE_ID_DAYLIGHT:
+ return -(tz.Bias + tz.DaylightBias);
+
+ default: /* TIME_ZONE_ID_INVALID */
+ return 0;
+ }
+}
diff --git a/app/nginx/src/os/win32/ngx_time.h b/app/nginx/src/os/win32/ngx_time.h
new file mode 100644
index 0000000..6c2f806
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_time.h
@@ -0,0 +1,51 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_TIME_H_INCLUDED_
+#define _NGX_TIME_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+typedef ngx_rbtree_key_t ngx_msec_t;
+typedef ngx_rbtree_key_int_t ngx_msec_int_t;
+
+typedef SYSTEMTIME ngx_tm_t;
+typedef FILETIME ngx_mtime_t;
+
+#define ngx_tm_sec wSecond
+#define ngx_tm_min wMinute
+#define ngx_tm_hour wHour
+#define ngx_tm_mday wDay
+#define ngx_tm_mon wMonth
+#define ngx_tm_year wYear
+#define ngx_tm_wday wDayOfWeek
+
+#define ngx_tm_sec_t u_short
+#define ngx_tm_min_t u_short
+#define ngx_tm_hour_t u_short
+#define ngx_tm_mday_t u_short
+#define ngx_tm_mon_t u_short
+#define ngx_tm_year_t u_short
+#define ngx_tm_wday_t u_short
+
+
+#define ngx_msleep Sleep
+
+#define NGX_HAVE_GETTIMEZONE 1
+
+#define ngx_timezone_update()
+
+ngx_int_t ngx_gettimezone(void);
+void ngx_libc_localtime(time_t s, struct tm *tm);
+void ngx_libc_gmtime(time_t s, struct tm *tm);
+void ngx_gettimeofday(struct timeval *tp);
+
+
+#endif /* _NGX_TIME_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_udp_wsarecv.c b/app/nginx/src/os/win32/ngx_udp_wsarecv.c
new file mode 100644
index 0000000..5424375
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_udp_wsarecv.c
@@ -0,0 +1,149 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ssize_t
+ngx_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ int rc;
+ u_long bytes, flags;
+ WSABUF wsabuf[1];
+ ngx_err_t err;
+ ngx_event_t *rev;
+
+ wsabuf[0].buf = (char *) buf;
+ wsabuf[0].len = size;
+ flags = 0;
+ bytes = 0;
+
+ rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, NULL, NULL);
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSARecv: fd:%d rc:%d %ul of %z", c->fd, rc, bytes, size);
+
+ rev = c->read;
+
+ if (rc == -1) {
+ rev->ready = 0;
+ err = ngx_socket_errno;
+
+ if (err == WSAEWOULDBLOCK) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "WSARecv() not ready");
+ return NGX_AGAIN;
+ }
+
+ rev->error = 1;
+ ngx_connection_error(c, err, "WSARecv() failed");
+
+ return NGX_ERROR;
+ }
+
+ return bytes;
+}
+
+
+ssize_t
+ngx_udp_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ int rc;
+ u_long bytes, flags;
+ WSABUF wsabuf[1];
+ ngx_err_t err;
+ ngx_event_t *rev;
+ LPWSAOVERLAPPED ovlp;
+
+ rev = c->read;
+
+ if (!rev->ready) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0, "second wsa post");
+ return NGX_AGAIN;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "rev->complete: %d", rev->complete);
+
+ if (rev->complete) {
+ rev->complete = 0;
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+ if (rev->ovlp.error) {
+ ngx_connection_error(c, rev->ovlp.error, "WSARecv() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSARecv ovlp: fd:%d %ul of %z",
+ c->fd, rev->available, size);
+
+ return rev->available;
+ }
+
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp,
+ &bytes, 0, NULL)
+ == 0)
+ {
+ ngx_connection_error(c, ngx_socket_errno,
+ "WSARecv() or WSAGetOverlappedResult() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSARecv: fd:%d %ul of %z", c->fd, bytes, size);
+
+ return bytes;
+ }
+
+ ovlp = (LPWSAOVERLAPPED) &rev->ovlp;
+ ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
+ wsabuf[0].buf = (char *) buf;
+ wsabuf[0].len = size;
+ flags = 0;
+ bytes = 0;
+
+ rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);
+
+ rev->complete = 0;
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSARecv ovlp: fd:%d rc:%d %ul of %z",
+ c->fd, rc, bytes, size);
+
+ if (rc == -1) {
+ err = ngx_socket_errno;
+ if (err == WSA_IO_PENDING) {
+ rev->active = 1;
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "WSARecv() posted");
+ return NGX_AGAIN;
+ }
+
+ rev->error = 1;
+ ngx_connection_error(c, err, "WSARecv() failed");
+ return NGX_ERROR;
+ }
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+
+ /*
+ * if a socket was bound with I/O completion port
+ * then GetQueuedCompletionStatus() would anyway return its status
+ * despite that WSARecv() was already complete
+ */
+
+ rev->active = 1;
+ return NGX_AGAIN;
+ }
+
+ rev->active = 0;
+
+ return bytes;
+}
diff --git a/app/nginx/src/os/win32/ngx_user.c b/app/nginx/src/os/win32/ngx_user.c
new file mode 100644
index 0000000..ea6da5a
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_user.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#if (NGX_CRYPT)
+
+ngx_int_t
+ngx_libc_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
+{
+ /* STUB: a plain text password */
+
+ *encrypted = key;
+
+ return NGX_OK;
+}
+
+#endif /* NGX_CRYPT */
diff --git a/app/nginx/src/os/win32/ngx_user.h b/app/nginx/src/os/win32/ngx_user.h
new file mode 100644
index 0000000..61408e4
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_user.h
@@ -0,0 +1,25 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_USER_H_INCLUDED_
+#define _NGX_USER_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+/* STUB */
+#define ngx_uid_t ngx_int_t
+#define ngx_gid_t ngx_int_t
+
+
+ngx_int_t ngx_libc_crypt(ngx_pool_t *pool, u_char *key, u_char *salt,
+ u_char **encrypted);
+
+
+#endif /* _NGX_USER_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_win32_config.h b/app/nginx/src/os/win32/ngx_win32_config.h
new file mode 100644
index 0000000..4824d05
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_win32_config.h
@@ -0,0 +1,282 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_WIN32_CONFIG_H_INCLUDED_
+#define _NGX_WIN32_CONFIG_H_INCLUDED_
+
+
+#undef WIN32
+#define WIN32 0x0400
+#define _WIN32_WINNT 0x0501
+
+
+#define STRICT
+#define WIN32_LEAN_AND_MEAN
+
+/* enable getenv() and gmtime() in msvc8 */
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_DEPRECATE
+
+/* enable gethostbyname() in msvc2015 */
+#if !(NGX_HAVE_INET6)
+#define _WINSOCK_DEPRECATED_NO_WARNINGS
+#endif
+
+/*
+ * we need to include <windows.h> explicitly before <winsock2.h> because
+ * the warning 4201 is enabled in <windows.h>
+ */
+#include <windows.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable:4201)
+#endif
+
+#include <winsock2.h>
+#include <ws2tcpip.h> /* ipv6 */
+#include <mswsock.h>
+#include <shellapi.h>
+#include <stddef.h> /* offsetof() */
+
+#ifdef __MINGW64_VERSION_MAJOR
+
+/* GCC MinGW-w64 supports _FILE_OFFSET_BITS */
+#define _FILE_OFFSET_BITS 64
+
+#elif defined __GNUC__
+
+/* GCC MinGW's stdio.h includes sys/types.h */
+#define _OFF_T_
+#define __have_typedef_off_t
+
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#ifdef __GNUC__
+#include <stdint.h>
+#endif
+#include <ctype.h>
+#include <locale.h>
+
+#ifdef __WATCOMC__
+#define _TIME_T_DEFINED
+typedef long time_t;
+/* OpenWatcom defines time_t as "unsigned long" */
+#endif
+
+#include <time.h> /* localtime(), strftime() */
+
+
+#ifdef _MSC_VER
+
+/* the end of the precompiled headers */
+#pragma hdrstop
+
+#pragma warning(default:4201)
+
+/* disable some "-W4" level warnings */
+
+/* 'type cast': from function pointer to data pointer */
+#pragma warning(disable:4054)
+
+/* 'type cast': from data pointer to function pointer */
+#pragma warning(disable:4055)
+
+/* 'function' : different 'const' qualifiers */
+#pragma warning(disable:4090)
+
+/* unreferenced formal parameter */
+#pragma warning(disable:4100)
+
+/* FD_SET() and FD_CLR(): conditional expression is constant */
+#pragma warning(disable:4127)
+
+/* conversion from 'type1' to 'type2', possible loss of data */
+#pragma warning(disable:4244)
+
+/* conversion from 'size_t' to 'type', possible loss of data */
+#pragma warning(disable:4267)
+
+/* array is too small to include a terminating null character */
+#pragma warning(disable:4295)
+
+#endif
+
+
+#ifdef __WATCOMC__
+
+/* symbol 'ngx_rbtree_min' has been defined, but not referenced */
+#pragma disable_message(202)
+
+#endif
+
+
+#ifdef __BORLANDC__
+
+/* the end of the precompiled headers */
+#pragma hdrstop
+
+/* functions containing (for|while|some if) are not expanded inline */
+#pragma warn -8027
+
+/* unreferenced formal parameter */
+#pragma warn -8057
+
+/* suspicious pointer arithmetic */
+#pragma warn -8072
+
+#endif
+
+
+#include <ngx_auto_config.h>
+
+
+#define ngx_inline __inline
+#define ngx_cdecl __cdecl
+
+
+#ifdef _MSC_VER
+typedef unsigned __int32 uint32_t;
+typedef __int32 int32_t;
+typedef unsigned __int16 uint16_t;
+#define ngx_libc_cdecl __cdecl
+
+#elif defined __BORLANDC__
+typedef unsigned __int32 uint32_t;
+typedef __int32 int32_t;
+typedef unsigned __int16 uint16_t;
+#define ngx_libc_cdecl __cdecl
+
+#else /* __WATCOMC__ */
+typedef unsigned int uint32_t;
+typedef int int32_t;
+typedef unsigned short int uint16_t;
+#define ngx_libc_cdecl
+
+#endif
+
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#if __BORLANDC__
+typedef int intptr_t;
+typedef u_int uintptr_t;
+#endif
+
+
+#ifndef __MINGW64_VERSION_MAJOR
+
+/* Windows defines off_t as long, which is 32-bit */
+typedef __int64 off_t;
+#define _OFF_T_DEFINED
+
+#endif
+
+
+#ifdef __WATCOMC__
+
+/* off_t is redefined by sys/types.h used by zlib.h */
+#define __TYPES_H_INCLUDED
+typedef int dev_t;
+typedef unsigned int ino_t;
+
+#elif __BORLANDC__
+
+/* off_t is redefined by sys/types.h used by zlib.h */
+#define __TYPES_H
+
+typedef int dev_t;
+typedef unsigned int ino_t;
+
+#endif
+
+
+#ifndef __GNUC__
+#ifdef _WIN64
+typedef __int64 ssize_t;
+#else
+typedef int ssize_t;
+#endif
+#endif
+
+
+typedef uint32_t in_addr_t;
+typedef u_short in_port_t;
+typedef int sig_atomic_t;
+
+
+#ifdef _WIN64
+
+#define NGX_PTR_SIZE 8
+#define NGX_SIZE_T_LEN (sizeof("-9223372036854775808") - 1)
+#define NGX_MAX_SIZE_T_VALUE 9223372036854775807
+#define NGX_TIME_T_LEN (sizeof("-9223372036854775808") - 1)
+#define NGX_TIME_T_SIZE 8
+#define NGX_MAX_TIME_T_VALUE 9223372036854775807
+
+#else
+
+#define NGX_PTR_SIZE 4
+#define NGX_SIZE_T_LEN (sizeof("-2147483648") - 1)
+#define NGX_MAX_SIZE_T_VALUE 2147483647
+#define NGX_TIME_T_LEN (sizeof("-2147483648") - 1)
+#define NGX_TIME_T_SIZE 4
+#define NGX_MAX_TIME_T_VALUE 2147483647
+
+#endif
+
+
+#define NGX_OFF_T_LEN (sizeof("-9223372036854775807") - 1)
+#define NGX_MAX_OFF_T_VALUE 9223372036854775807
+#define NGX_SIG_ATOMIC_T_SIZE 4
+
+
+#define NGX_HAVE_LITTLE_ENDIAN 1
+#define NGX_HAVE_NONALIGNED 1
+
+
+#define NGX_WIN_NT 200000
+
+
+#define NGX_LISTEN_BACKLOG 511
+
+
+#ifndef NGX_HAVE_INHERITED_NONBLOCK
+#define NGX_HAVE_INHERITED_NONBLOCK 1
+#endif
+
+#ifndef NGX_HAVE_CASELESS_FILESYSTEM
+#define NGX_HAVE_CASELESS_FILESYSTEM 1
+#endif
+
+#ifndef NGX_HAVE_WIN32_TRANSMITPACKETS
+#define NGX_HAVE_WIN32_TRANSMITPACKETS 1
+#define NGX_HAVE_WIN32_TRANSMITFILE 0
+#endif
+
+#ifndef NGX_HAVE_WIN32_TRANSMITFILE
+#define NGX_HAVE_WIN32_TRANSMITFILE 1
+#endif
+
+#if (NGX_HAVE_WIN32_TRANSMITPACKETS) || (NGX_HAVE_WIN32_TRANSMITFILE)
+#define NGX_HAVE_SENDFILE 1
+#endif
+
+#ifndef NGX_HAVE_SO_SNDLOWAT
+/* setsockopt(SO_SNDLOWAT) returns error WSAENOPROTOOPT */
+#define NGX_HAVE_SO_SNDLOWAT 0
+#endif
+
+#define NGX_HAVE_GETADDRINFO 1
+
+#define ngx_random rand
+#define ngx_debug_init()
+
+
+#endif /* _NGX_WIN32_CONFIG_H_INCLUDED_ */
diff --git a/app/nginx/src/os/win32/ngx_win32_init.c b/app/nginx/src/os/win32/ngx_win32_init.c
new file mode 100644
index 0000000..ec9b51e
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_win32_init.c
@@ -0,0 +1,297 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <nginx.h>
+
+
+ngx_uint_t ngx_win32_version;
+ngx_uint_t ngx_ncpu;
+ngx_uint_t ngx_max_wsabufs;
+ngx_int_t ngx_max_sockets;
+ngx_uint_t ngx_inherited_nonblocking = 1;
+ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
+
+char ngx_unique[NGX_INT32_LEN + 1];
+
+
+ngx_os_io_t ngx_os_io = {
+ ngx_wsarecv,
+ ngx_wsarecv_chain,
+ ngx_udp_wsarecv,
+ ngx_wsasend,
+ NULL,
+ NULL,
+ ngx_wsasend_chain,
+ 0
+};
+
+
+typedef struct {
+ WORD wServicePackMinor;
+ WORD wSuiteMask;
+ BYTE wProductType;
+} ngx_osviex_stub_t;
+
+
+static u_int osviex;
+static OSVERSIONINFOEX osvi;
+
+/* Should these pointers be per protocol ? */
+LPFN_ACCEPTEX ngx_acceptex;
+LPFN_GETACCEPTEXSOCKADDRS ngx_getacceptexsockaddrs;
+LPFN_TRANSMITFILE ngx_transmitfile;
+LPFN_TRANSMITPACKETS ngx_transmitpackets;
+LPFN_CONNECTEX ngx_connectex;
+LPFN_DISCONNECTEX ngx_disconnectex;
+
+static GUID ax_guid = WSAID_ACCEPTEX;
+static GUID as_guid = WSAID_GETACCEPTEXSOCKADDRS;
+static GUID tf_guid = WSAID_TRANSMITFILE;
+static GUID tp_guid = WSAID_TRANSMITPACKETS;
+static GUID cx_guid = WSAID_CONNECTEX;
+static GUID dx_guid = WSAID_DISCONNECTEX;
+
+
+ngx_int_t
+ngx_os_init(ngx_log_t *log)
+{
+ DWORD bytes;
+ SOCKET s;
+ WSADATA wsd;
+ ngx_err_t err;
+ ngx_time_t *tp;
+ ngx_uint_t n;
+ SYSTEM_INFO si;
+
+ /* get Windows version */
+
+ ngx_memzero(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+#ifdef _MSC_VER
+#pragma warning(disable:4996)
+#endif
+
+ osviex = GetVersionEx((OSVERSIONINFO *) &osvi);
+
+ if (osviex == 0) {
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ if (GetVersionEx((OSVERSIONINFO *) &osvi) == 0) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ "GetVersionEx() failed");
+ return NGX_ERROR;
+ }
+ }
+
+#ifdef _MSC_VER
+#pragma warning(default:4996)
+#endif
+
+ /*
+ * Windows 3.1 Win32s 0xxxxx
+ *
+ * Windows 95 140000
+ * Windows 98 141000
+ * Windows ME 149000
+ * Windows NT 3.51 235100
+ * Windows NT 4.0 240000
+ * Windows NT 4.0 SP5 240050
+ * Windows 2000 250000
+ * Windows XP 250100
+ * Windows 2003 250200
+ * Windows Vista/2008 260000
+ *
+ * Windows CE x.x 3xxxxx
+ */
+
+ ngx_win32_version = osvi.dwPlatformId * 100000
+ + osvi.dwMajorVersion * 10000
+ + osvi.dwMinorVersion * 100;
+
+ if (osviex) {
+ ngx_win32_version += osvi.wServicePackMajor * 10
+ + osvi.wServicePackMinor;
+ }
+
+ GetSystemInfo(&si);
+ ngx_pagesize = si.dwPageSize;
+ ngx_allocation_granularity = si.dwAllocationGranularity;
+ ngx_ncpu = si.dwNumberOfProcessors;
+ ngx_cacheline_size = NGX_CPU_CACHE_LINE;
+
+ for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }
+
+ /* delete default "C" locale for _wcsicmp() */
+ setlocale(LC_ALL, "");
+
+
+ /* init Winsock */
+
+ if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
+ "WSAStartup() failed");
+ return NGX_ERROR;
+ }
+
+ if (ngx_win32_version < NGX_WIN_NT) {
+ ngx_max_wsabufs = 16;
+ return NGX_OK;
+ }
+
+ /* STUB: ngx_uint_t max */
+ ngx_max_wsabufs = 1024 * 1024;
+
+ /*
+ * get AcceptEx(), GetAcceptExSockAddrs(), TransmitFile(),
+ * TransmitPackets(), ConnectEx(), and DisconnectEx() addresses
+ */
+
+ s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+ if (s == (ngx_socket_t) -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
+ ngx_socket_n " failed");
+ return NGX_ERROR;
+ }
+
+ if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ax_guid, sizeof(GUID),
+ &ngx_acceptex, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL)
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
+ "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
+ "WSAID_ACCEPTEX) failed");
+ }
+
+ if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &as_guid, sizeof(GUID),
+ &ngx_getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
+ &bytes, NULL, NULL)
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
+ "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
+ "WSAID_GETACCEPTEXSOCKADDRS) failed");
+ }
+
+ if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tf_guid, sizeof(GUID),
+ &ngx_transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes,
+ NULL, NULL)
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
+ "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
+ "WSAID_TRANSMITFILE) failed");
+ }
+
+ if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tp_guid, sizeof(GUID),
+ &ngx_transmitpackets, sizeof(LPFN_TRANSMITPACKETS), &bytes,
+ NULL, NULL)
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
+ "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
+ "WSAID_TRANSMITPACKETS) failed");
+ }
+
+ if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &cx_guid, sizeof(GUID),
+ &ngx_connectex, sizeof(LPFN_CONNECTEX), &bytes,
+ NULL, NULL)
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
+ "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
+ "WSAID_CONNECTEX) failed");
+ }
+
+ if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &dx_guid, sizeof(GUID),
+ &ngx_disconnectex, sizeof(LPFN_DISCONNECTEX), &bytes,
+ NULL, NULL)
+ == -1)
+ {
+ ngx_log_error(NGX_LOG_NOTICE, log, ngx_socket_errno,
+ "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
+ "WSAID_DISCONNECTEX) failed");
+ }
+
+ if (ngx_close_socket(s) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
+ ngx_close_socket_n " failed");
+ }
+
+ if (GetEnvironmentVariable("ngx_unique", ngx_unique, NGX_INT32_LEN + 1)
+ != 0)
+ {
+ ngx_process = NGX_PROCESS_WORKER;
+
+ } else {
+ err = ngx_errno;
+
+ if (err != ERROR_ENVVAR_NOT_FOUND) {
+ ngx_log_error(NGX_LOG_EMERG, log, err,
+ "GetEnvironmentVariable(\"ngx_unique\") failed");
+ return NGX_ERROR;
+ }
+
+ ngx_sprintf((u_char *) ngx_unique, "%P%Z", ngx_pid);
+ }
+
+ tp = ngx_timeofday();
+ srand((ngx_pid << 16) ^ (unsigned) tp->sec ^ tp->msec);
+
+ return NGX_OK;
+}
+
+
+void
+ngx_os_status(ngx_log_t *log)
+{
+ ngx_osviex_stub_t *osviex_stub;
+
+ ngx_log_error(NGX_LOG_NOTICE, log, 0, NGINX_VER_BUILD);
+
+ if (osviex) {
+
+ /*
+ * the MSVC 6.0 SP2 defines wSuiteMask and wProductType
+ * as WORD wReserved[2]
+ */
+ osviex_stub = (ngx_osviex_stub_t *) &osvi.wServicePackMinor;
+
+ ngx_log_error(NGX_LOG_INFO, log, 0,
+ "OS: %ud build:%ud, \"%s\", suite:%Xd, type:%ud",
+ ngx_win32_version, osvi.dwBuildNumber, osvi.szCSDVersion,
+ osviex_stub->wSuiteMask, osviex_stub->wProductType);
+
+ } else {
+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
+
+ /* Win9x build */
+
+ ngx_log_error(NGX_LOG_INFO, log, 0,
+ "OS: %u build:%ud.%ud.%ud, \"%s\"",
+ ngx_win32_version,
+ osvi.dwBuildNumber >> 24,
+ (osvi.dwBuildNumber >> 16) & 0xff,
+ osvi.dwBuildNumber & 0xffff,
+ osvi.szCSDVersion);
+
+ } else {
+
+ /*
+ * VER_PLATFORM_WIN32_NT
+ *
+ * we do not currently support VER_PLATFORM_WIN32_CE
+ * and we do not support VER_PLATFORM_WIN32s at all
+ */
+
+ ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %ud build:%ud, \"%s\"",
+ ngx_win32_version, osvi.dwBuildNumber,
+ osvi.szCSDVersion);
+ }
+ }
+}
diff --git a/app/nginx/src/os/win32/ngx_wsarecv.c b/app/nginx/src/os/win32/ngx_wsarecv.c
new file mode 100644
index 0000000..1925f0b
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_wsarecv.c
@@ -0,0 +1,174 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ssize_t
+ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ int rc;
+ u_long bytes, flags;
+ WSABUF wsabuf[1];
+ ngx_err_t err;
+ ngx_int_t n;
+ ngx_event_t *rev;
+
+ wsabuf[0].buf = (char *) buf;
+ wsabuf[0].len = size;
+ flags = 0;
+ bytes = 0;
+
+ rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, NULL, NULL);
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSARecv: fd:%d rc:%d %ul of %z", c->fd, rc, bytes, size);
+
+ rev = c->read;
+
+ if (rc == -1) {
+ rev->ready = 0;
+ err = ngx_socket_errno;
+
+ if (err == WSAEWOULDBLOCK) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "WSARecv() not ready");
+ return NGX_AGAIN;
+ }
+
+ n = ngx_connection_error(c, err, "WSARecv() failed");
+
+ if (n == NGX_ERROR) {
+ rev->error = 1;
+ }
+
+ return n;
+ }
+
+ if (bytes < size) {
+ rev->ready = 0;
+ }
+
+ if (bytes == 0) {
+ rev->eof = 1;
+ }
+
+ return bytes;
+}
+
+
+ssize_t
+ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ int rc;
+ u_long bytes, flags;
+ WSABUF wsabuf[1];
+ ngx_err_t err;
+ ngx_int_t n;
+ ngx_event_t *rev;
+ LPWSAOVERLAPPED ovlp;
+
+ rev = c->read;
+
+ if (!rev->ready) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0, "second wsa post");
+ return NGX_AGAIN;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "rev->complete: %d", rev->complete);
+
+ if (rev->complete) {
+ rev->complete = 0;
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+ if (rev->ovlp.error) {
+ ngx_connection_error(c, rev->ovlp.error, "WSARecv() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSARecv ovlp: fd:%d %ul of %z",
+ c->fd, rev->available, size);
+
+ return rev->available;
+ }
+
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp,
+ &bytes, 0, NULL)
+ == 0)
+ {
+ ngx_connection_error(c, ngx_socket_errno,
+ "WSARecv() or WSAGetOverlappedResult() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSARecv: fd:%d %ul of %z", c->fd, bytes, size);
+
+ return bytes;
+ }
+
+ ovlp = (LPWSAOVERLAPPED) &rev->ovlp;
+ ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
+ wsabuf[0].buf = (char *) buf;
+ wsabuf[0].len = size;
+ flags = 0;
+ bytes = 0;
+
+ rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);
+
+ rev->complete = 0;
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSARecv ovlp: fd:%d rc:%d %ul of %z",
+ c->fd, rc, bytes, size);
+
+ if (rc == -1) {
+ err = ngx_socket_errno;
+ if (err == WSA_IO_PENDING) {
+ rev->active = 1;
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "WSARecv() posted");
+ return NGX_AGAIN;
+ }
+
+ n = ngx_connection_error(c, err, "WSARecv() failed");
+
+ if (n == NGX_ERROR) {
+ rev->error = 1;
+ }
+
+ return n;
+ }
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+
+ /*
+ * if a socket was bound with I/O completion port
+ * then GetQueuedCompletionStatus() would anyway return its status
+ * despite that WSARecv() was already complete
+ */
+
+ rev->active = 1;
+ return NGX_AGAIN;
+ }
+
+ if (bytes == 0) {
+ rev->eof = 1;
+ rev->ready = 0;
+
+ } else {
+ rev->ready = 1;
+ }
+
+ rev->active = 0;
+
+ return bytes;
+}
diff --git a/app/nginx/src/os/win32/ngx_wsarecv_chain.c b/app/nginx/src/os/win32/ngx_wsarecv_chain.c
new file mode 100644
index 0000000..2598e09
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_wsarecv_chain.c
@@ -0,0 +1,106 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+#define NGX_WSABUFS 8
+
+
+ssize_t
+ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit)
+{
+ int rc;
+ u_char *prev;
+ u_long bytes, flags;
+ size_t n, size;
+ ngx_err_t err;
+ ngx_array_t vec;
+ ngx_event_t *rev;
+ LPWSABUF wsabuf;
+ WSABUF wsabufs[NGX_WSABUFS];
+
+ prev = NULL;
+ wsabuf = NULL;
+ flags = 0;
+ size = 0;
+ bytes = 0;
+
+ vec.elts = wsabufs;
+ vec.nelts = 0;
+ vec.size = sizeof(WSABUF);
+ vec.nalloc = NGX_WSABUFS;
+ vec.pool = c->pool;
+
+ /* coalesce the neighbouring bufs */
+
+ while (chain) {
+ n = chain->buf->end - chain->buf->last;
+
+ if (limit) {
+ if (size >= (size_t) limit) {
+ break;
+ }
+
+ if (size + n > (size_t) limit) {
+ n = (size_t) limit - size;
+ }
+ }
+
+ if (prev == chain->buf->last) {
+ wsabuf->len += n;
+
+ } else {
+ wsabuf = ngx_array_push(&vec);
+ if (wsabuf == NULL) {
+ return NGX_ERROR;
+ }
+
+ wsabuf->buf = (char *) chain->buf->last;
+ wsabuf->len = n;
+ }
+
+ size += n;
+ prev = chain->buf->end;
+ chain = chain->next;
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSARecv: %d:%d", vec.nelts, wsabuf->len);
+
+
+ rc = WSARecv(c->fd, vec.elts, vec.nelts, &bytes, &flags, NULL, NULL);
+
+ rev = c->read;
+
+ if (rc == -1) {
+ rev->ready = 0;
+ err = ngx_socket_errno;
+
+ if (err == WSAEWOULDBLOCK) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "WSARecv() not ready");
+ return NGX_AGAIN;
+ }
+
+ rev->error = 1;
+ ngx_connection_error(c, err, "WSARecv() failed");
+ return NGX_ERROR;
+ }
+
+ if (bytes < size) {
+ rev->ready = 0;
+ }
+
+ if (bytes == 0) {
+ rev->eof = 1;
+ }
+
+ return bytes;
+}
diff --git a/app/nginx/src/os/win32/ngx_wsasend.c b/app/nginx/src/os/win32/ngx_wsasend.c
new file mode 100644
index 0000000..d6a23d1
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_wsasend.c
@@ -0,0 +1,185 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ssize_t
+ngx_wsasend(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ int n;
+ u_long sent;
+ ngx_err_t err;
+ ngx_event_t *wev;
+ WSABUF wsabuf;
+
+ wev = c->write;
+
+ if (!wev->ready) {
+ return NGX_AGAIN;
+ }
+
+ /*
+ * WSABUF must be 4-byte aligned otherwise
+ * WSASend() will return undocumented WSAEINVAL error.
+ */
+
+ wsabuf.buf = (char *) buf;
+ wsabuf.len = size;
+
+ sent = 0;
+
+ n = WSASend(c->fd, &wsabuf, 1, &sent, 0, NULL, NULL);
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSASend: fd:%d, %d, %ul of %uz", c->fd, n, sent, size);
+
+ if (n == 0) {
+ if (sent < size) {
+ wev->ready = 0;
+ }
+
+ c->sent += sent;
+
+ return sent;
+ }
+
+ err = ngx_socket_errno;
+
+ if (err == WSAEWOULDBLOCK) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, "WSASend() not ready");
+ wev->ready = 0;
+ return NGX_AGAIN;
+ }
+
+ wev->error = 1;
+ ngx_connection_error(c, err, "WSASend() failed");
+
+ return NGX_ERROR;
+}
+
+
+ssize_t
+ngx_overlapped_wsasend(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ int n;
+ u_long sent;
+ ngx_err_t err;
+ ngx_event_t *wev;
+ LPWSAOVERLAPPED ovlp;
+ WSABUF wsabuf;
+
+ wev = c->write;
+
+ if (!wev->ready) {
+ return NGX_AGAIN;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "wev->complete: %d", wev->complete);
+
+ if (!wev->complete) {
+
+ /* post the overlapped WSASend() */
+
+ /*
+ * WSABUFs must be 4-byte aligned otherwise
+ * WSASend() will return undocumented WSAEINVAL error.
+ */
+
+ wsabuf.buf = (char *) buf;
+ wsabuf.len = size;
+
+ sent = 0;
+
+ ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
+ ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
+
+ n = WSASend(c->fd, &wsabuf, 1, &sent, 0, ovlp, NULL);
+
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSASend: fd:%d, %d, %ul of %uz", c->fd, n, sent, size);
+
+ wev->complete = 0;
+
+ if (n == 0) {
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+
+ /*
+ * if a socket was bound with I/O completion port then
+ * GetQueuedCompletionStatus() would anyway return its status
+ * despite that WSASend() was already complete
+ */
+
+ wev->active = 1;
+ return NGX_AGAIN;
+ }
+
+ if (sent < size) {
+ wev->ready = 0;
+ }
+
+ c->sent += sent;
+
+ return sent;
+ }
+
+ err = ngx_socket_errno;
+
+ if (err == WSA_IO_PENDING) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "WSASend() posted");
+ wev->active = 1;
+ return NGX_AGAIN;
+ }
+
+ wev->error = 1;
+ ngx_connection_error(c, err, "WSASend() failed");
+
+ return NGX_ERROR;
+ }
+
+ /* the overlapped WSASend() complete */
+
+ wev->complete = 0;
+ wev->active = 0;
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+
+ if (wev->ovlp.error) {
+ ngx_connection_error(c, wev->ovlp.error, "WSASend() failed");
+ return NGX_ERROR;
+ }
+
+ sent = wev->available;
+
+ } else {
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &wev->ovlp,
+ &sent, 0, NULL)
+ == 0)
+ {
+ ngx_connection_error(c, ngx_socket_errno,
+ "WSASend() or WSAGetOverlappedResult() failed");
+
+ return NGX_ERROR;
+ }
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSAGetOverlappedResult: fd:%d, %ul of %uz",
+ c->fd, sent, size);
+
+ if (sent < size) {
+ wev->ready = 0;
+ }
+
+ c->sent += sent;
+
+ return sent;
+}
diff --git a/app/nginx/src/os/win32/ngx_wsasend_chain.c b/app/nginx/src/os/win32/ngx_wsasend_chain.c
new file mode 100644
index 0000000..e2dde22
--- /dev/null
+++ b/app/nginx/src/os/win32/ngx_wsasend_chain.c
@@ -0,0 +1,292 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+#define NGX_WSABUFS 8
+
+
+ngx_chain_t *
+ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
+{
+ int rc;
+ u_char *prev;
+ u_long size, sent, send, prev_send;
+ ngx_err_t err;
+ ngx_event_t *wev;
+ ngx_array_t vec;
+ ngx_chain_t *cl;
+ LPWSABUF wsabuf;
+ WSABUF wsabufs[NGX_WSABUFS];
+
+ wev = c->write;
+
+ if (!wev->ready) {
+ return in;
+ }
+
+ /* the maximum limit size is the maximum u_long value - the page size */
+
+ if (limit == 0 || limit > (off_t) (NGX_MAX_UINT32_VALUE - ngx_pagesize)) {
+ limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
+ }
+
+ send = 0;
+
+ /*
+ * WSABUFs must be 4-byte aligned otherwise
+ * WSASend() will return undocumented WSAEINVAL error.
+ */
+
+ vec.elts = wsabufs;
+ vec.size = sizeof(WSABUF);
+ vec.nalloc = NGX_WSABUFS;
+ vec.pool = c->pool;
+
+ for ( ;; ) {
+ prev = NULL;
+ wsabuf = NULL;
+ prev_send = send;
+
+ vec.nelts = 0;
+
+ /* create the WSABUF and coalesce the neighbouring bufs */
+
+ for (cl = in;
+ cl && vec.nelts < ngx_max_wsabufs && send < limit;
+ cl = cl->next)
+ {
+ if (ngx_buf_special(cl->buf)) {
+ continue;
+ }
+
+ size = cl->buf->last - cl->buf->pos;
+
+ if (send + size > limit) {
+ size = (u_long) (limit - send);
+ }
+
+ if (prev == cl->buf->pos) {
+ wsabuf->len += cl->buf->last - cl->buf->pos;
+
+ } else {
+ wsabuf = ngx_array_push(&vec);
+ if (wsabuf == NULL) {
+ return NGX_CHAIN_ERROR;
+ }
+
+ wsabuf->buf = (char *) cl->buf->pos;
+ wsabuf->len = cl->buf->last - cl->buf->pos;
+ }
+
+ prev = cl->buf->last;
+ send += size;
+ }
+
+ sent = 0;
+
+ rc = WSASend(c->fd, vec.elts, vec.nelts, &sent, 0, NULL, NULL);
+
+ if (rc == -1) {
+ err = ngx_errno;
+
+ if (err == WSAEWOULDBLOCK) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "WSASend() not ready");
+
+ } else {
+ wev->error = 1;
+ ngx_connection_error(c, err, "WSASend() failed");
+ return NGX_CHAIN_ERROR;
+ }
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSASend: fd:%d, s:%ul", c->fd, sent);
+
+ c->sent += sent;
+
+ in = ngx_chain_update_sent(in, sent);
+
+ if (send - prev_send != sent) {
+ wev->ready = 0;
+ return in;
+ }
+
+ if (send >= limit || in == NULL) {
+ return in;
+ }
+ }
+}
+
+
+ngx_chain_t *
+ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
+{
+ int rc;
+ u_char *prev;
+ u_long size, send, sent;
+ ngx_err_t err;
+ ngx_event_t *wev;
+ ngx_array_t vec;
+ ngx_chain_t *cl;
+ LPWSAOVERLAPPED ovlp;
+ LPWSABUF wsabuf;
+ WSABUF wsabufs[NGX_WSABUFS];
+
+ wev = c->write;
+
+ if (!wev->ready) {
+ return in;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "wev->complete: %d", wev->complete);
+
+ if (!wev->complete) {
+
+ /* post the overlapped WSASend() */
+
+ /* the maximum limit size is the maximum u_long value - the page size */
+
+ if (limit == 0 || limit > (off_t) (NGX_MAX_UINT32_VALUE - ngx_pagesize))
+ {
+ limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
+ }
+
+ /*
+ * WSABUFs must be 4-byte aligned otherwise
+ * WSASend() will return undocumented WSAEINVAL error.
+ */
+
+ vec.elts = wsabufs;
+ vec.nelts = 0;
+ vec.size = sizeof(WSABUF);
+ vec.nalloc = NGX_WSABUFS;
+ vec.pool = c->pool;
+
+ send = 0;
+ prev = NULL;
+ wsabuf = NULL;
+
+ /* create the WSABUF and coalesce the neighbouring bufs */
+
+ for (cl = in;
+ cl && vec.nelts < ngx_max_wsabufs && send < limit;
+ cl = cl->next)
+ {
+ if (ngx_buf_special(cl->buf)) {
+ continue;
+ }
+
+ size = cl->buf->last - cl->buf->pos;
+
+ if (send + size > limit) {
+ size = (u_long) (limit - send);
+ }
+
+ if (prev == cl->buf->pos) {
+ wsabuf->len += cl->buf->last - cl->buf->pos;
+
+ } else {
+ wsabuf = ngx_array_push(&vec);
+ if (wsabuf == NULL) {
+ return NGX_CHAIN_ERROR;
+ }
+
+ wsabuf->buf = (char *) cl->buf->pos;
+ wsabuf->len = cl->buf->last - cl->buf->pos;
+ }
+
+ prev = cl->buf->last;
+ send += size;
+ }
+
+ ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
+ ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
+
+ rc = WSASend(c->fd, vec.elts, vec.nelts, &sent, 0, ovlp, NULL);
+
+ wev->complete = 0;
+
+ if (rc == -1) {
+ err = ngx_errno;
+
+ if (err == WSA_IO_PENDING) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
+ "WSASend() posted");
+ wev->active = 1;
+ return in;
+
+ } else {
+ wev->error = 1;
+ ngx_connection_error(c, err, "WSASend() failed");
+ return NGX_CHAIN_ERROR;
+ }
+
+ } else if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+
+ /*
+ * if a socket was bound with I/O completion port then
+ * GetQueuedCompletionStatus() would anyway return its status
+ * despite that WSASend() was already complete
+ */
+
+ wev->active = 1;
+ return in;
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSASend: fd:%d, s:%ul", c->fd, sent);
+
+ } else {
+
+ /* the overlapped WSASend() complete */
+
+ wev->complete = 0;
+ wev->active = 0;
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+ if (wev->ovlp.error) {
+ ngx_connection_error(c, wev->ovlp.error, "WSASend() failed");
+ return NGX_CHAIN_ERROR;
+ }
+
+ sent = wev->available;
+
+ } else {
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &wev->ovlp,
+ &sent, 0, NULL)
+ == 0)
+ {
+ ngx_connection_error(c, ngx_socket_errno,
+ "WSASend() or WSAGetOverlappedResult() failed");
+
+ return NGX_CHAIN_ERROR;
+ }
+ }
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "WSASend ovlp: fd:%d, s:%ul", c->fd, sent);
+
+ c->sent += sent;
+
+ in = ngx_chain_update_sent(in, sent);
+
+ if (in) {
+ wev->ready = 0;
+
+ } else {
+ wev->ready = 1;
+ }
+
+ return in;
+}