changeset 183:4c698194c56d

nginx-0.0.1-2003-11-13-19:16:33 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 13 Nov 2003 16:16:33 +0000
parents 3c49eaf3f522
children 1bf718ce0dde
files src/core/ngx_core.h src/core/ngx_os_init.h src/http/modules/ngx_http_static_handler.c src/http/ngx_http_core_module.c src/os/unix/ngx_freebsd.h src/os/unix/ngx_freebsd_config.h src/os/unix/ngx_freebsd_init.c src/os/unix/ngx_freebsd_init.h src/os/unix/ngx_freebsd_sendfile_chain.c src/os/unix/ngx_linux_config.h src/os/unix/ngx_linux_init.c src/os/unix/ngx_os.h src/os/unix/ngx_posix_init.c src/os/unix/ngx_solaris_config.h src/os/unix/ngx_solaris_init.c src/os/unix/ngx_time.h src/os/win32/ngx_files.c src/os/win32/ngx_files.h src/os/win32/ngx_os.h src/os/win32/ngx_win32_config.h
diffstat 20 files changed, 348 insertions(+), 138 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -30,7 +30,7 @@ typedef struct ngx_connection_s  ngx_con
 #include <ngx_times.h>
 #include <ngx_inet.h>
 #include <ngx_conf_file.h>
-#include <ngx_os_init.h>
+#include <ngx_os.h>
 #include <ngx_connection.h>
 
 
deleted file mode 100644
--- a/src/core/ngx_os_init.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _NGX_OS_INIT_H_INCLUDED_
-#define _NGX_OS_INIT_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#define NGX_IO_SENDFILE    1
-#define NGX_IO_ZEROCOPY    2
-
-#if (HAVE_SENDFILE)
-#define NGX_HAVE_SENDFILE  NGX_IO_SENDFILE
-#else
-#define NGX_HAVE_SENDFILE  0
-#endif
-
-#if (HAVE_ZEROCOPY)
-#define NGX_HAVE_ZEROCOPY  NGX_IO_ZEROCOPY
-#else
-#define NGX_HAVE_ZEROCOPY  0
-#endif
-
-
-
-typedef struct {
-    ssize_t       (*recv)(ngx_connection_t *c, char *buf, size_t size);
-    ssize_t       (*recv_chain)(ngx_connection_t *c, ngx_chain_t *in);
-    ssize_t       (*send)(ngx_connection_t *c, char *buf, size_t size);
-    ngx_chain_t  *(*send_chain)(ngx_connection_t *c, ngx_chain_t *in);
-    int             flags;
-} ngx_os_io_t;
-
-
-int ngx_os_init(ngx_log_t *log);
-
-#if !(WIN32)
-int ngx_daemon(ngx_log_t *log);
-#endif
-
-
-extern ngx_os_io_t  ngx_os_io;
-extern int          ngx_max_sockets;
-extern int          ngx_inherited_nonblocking;
-
-
-extern int          restart;
-extern int          rotate;
-
-
-#endif /* _NGX_OS_INIT_H_INCLUDED_ */
--- a/src/http/modules/ngx_http_static_handler.c
+++ b/src/http/modules/ngx_http_static_handler.c
@@ -87,30 +87,52 @@ ngx_log_debug(r->connection->log, "HTTP 
 
 #if (WIN9X)
 
-    /*
-     * There is no way to open a file or a directory in Win9X with
-     * one syscall: Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag.
-     * So we need to check its type before the opening
-     */
+    if (ngx_win32_version < NGX_WIN_NT) {
+
+        /*
+         * There is no way to open a file or a directory in Win9X with
+         * one syscall: Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag.
+         * So we need to check its type before the opening.
+         */
+
+        r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
+        if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
+            err = ngx_errno;
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
+                          ngx_file_type_n " \"%s\" failed", r->file.name.data);
+
+            if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
+                return NGX_HTTP_NOT_FOUND;
+
+            } else if (err == NGX_EACCES) {
+                return NGX_HTTP_FORBIDDEN;
 
-    r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
-    if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
-        err = ngx_errno;
-        ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
-                      ngx_file_type_n " \"%s\" failed", r->file.name.data);
+            } else {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+        }
+
+        if (ngx_is_dir(r->file.info)) {
+ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
 
-        if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
-            return NGX_HTTP_NOT_FOUND;
+            if (!(r->headers_out.location =
+                   ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
+            {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
 
-        } else if (err == NGX_EACCES) {
-            return NGX_HTTP_FORBIDDEN;
+            *last++ = '/';
+            *last = '\0';
+            r->headers_out.location->key.len = 8;
+            r->headers_out.location->key.data = "Location" ;
+            r->headers_out.location->value.len = last - location;
+            r->headers_out.location->value.data = location;
 
-        } else {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            return NGX_HTTP_MOVED_PERMANENTLY;
         }
     }
 
-#else
+#endif
 
     if (r->file.fd == NGX_INVALID_FILE) {
         r->file.fd = ngx_open_file(r->file.name.data,
@@ -163,7 +185,6 @@ ngx_log_debug(r->connection->log, "FILE:
     if (ngx_is_dir(r->file.info)) {
 ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
 
-#if !(WIN9X)
         if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
             ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
                           ngx_close_file_n " \"%s\" failed", r->file.name.data);
@@ -171,7 +192,6 @@ ngx_log_debug(r->connection->log, "HTTP 
 
         r->file.fd = NGX_INVALID_FILE;
         r->file.info_valid = 0;
-#endif
 
         if (!(r->headers_out.location =
                    ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
@@ -203,7 +223,6 @@ ngx_log_debug(r->connection->log, "HTTP 
     }
 
 #endif
-#endif
 
     r->content_handler = ngx_http_static_handler;
 
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -4,9 +4,6 @@
 #include <ngx_event.h>
 #include <ngx_http.h>
 #include <nginx.h>
-#if __FreeBSD__
-#include <ngx_freebsd_init.h>
-#endif
 
 
 static void ngx_http_phase_event_handler(ngx_event_t *rev);
new file mode 100644
--- /dev/null
+++ b/src/os/unix/ngx_freebsd.h
@@ -0,0 +1,16 @@
+#ifndef _NGX_FREEBSD_H_INCLUDED_
+#define _NGX_FREEBSD_H_INCLUDED_
+
+
+ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in);
+
+
+extern int ngx_freebsd_kern_osreldate;
+extern int ngx_freebsd_hw_ncpu;
+extern int ngx_freebsd_net_inet_tcp_sendspace;
+extern int ngx_freebsd_sendfile_nbytes_bug;
+extern int ngx_freebsd_kern_ipc_zero_copy_send;
+extern int ngx_freebsd_use_tcp_nopush;
+
+
+#endif /* _NGX_FREEBSD_H_INCLUDED_ */
--- a/src/os/unix/ngx_freebsd_config.h
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -24,23 +24,35 @@
 #include <osreldate.h>
 
 
+/* TODO: autoconf */
+#if __FreeBSD_version < 300007
+typedef u_int64_t  uint64_t;
+typedef u_int32_t  uintptr_t;
+#endif
+
+
+#if __FreeBSD_version < 330002  /* exactly */
+typedef uint32_t   socklen_t;
+#endif
+
+
 #if (i386)
 
 #define OFF_FMT    "%lld"
 #define SIZE_FMT   "%d"
 #define SIZEX_FMT  "%x"
-#define TIME_FMT   "%lu"
 
 #else  /* amd64, alpha, sparc64, ia64 */
 
 #define OFF_FMT    "%ld"
 #define SIZE_FMT   "%ld"
 #define SIZEX_FMT  "%lx"
-#define TIME_FMT   "%lu"
 
 #endif
 
+#define TIME_FMT   "%lu"
 #define PID_FMT    "%d"
+#define RLIM_FMT   "%lld"
 
 
 #ifndef HAVE_SELECT
--- a/src/os/unix/ngx_freebsd_init.c
+++ b/src/os/unix/ngx_freebsd_init.c
@@ -1,5 +1,6 @@
 
-#include <ngx_freebsd_init.h>
+#include <ngx_config.h>
+#include <ngx_core.h>
 
 
 /* FreeBSD 3.4 at least */
deleted file mode 100644
--- a/src/os/unix/ngx_freebsd_init.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _NGX_FREEBSD_INIT_H_INCLUDED_
-#define _NGX_FREEBSD_INIT_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/* STUB */
-int ngx_posix_init(ngx_log_t *log);
-ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
-ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry);
-/* */
-
-ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in);
-
-
-extern int ngx_freebsd_kern_osreldate;
-extern int ngx_freebsd_hw_ncpu;
-extern int ngx_freebsd_net_inet_tcp_sendspace;
-extern int ngx_freebsd_sendfile_nbytes_bug;
-extern int ngx_freebsd_kern_ipc_zero_copy_send;
-extern int ngx_freebsd_use_tcp_nopush;
-
-
-#endif /* _NGX_FREEBSD_INIT_H_INCLUDED_ */
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -2,7 +2,6 @@
 #include <ngx_config.h>
 #include <ngx_core.h>
 #include <ngx_event.h>
-#include <ngx_freebsd_init.h>
 
 
 /*
--- a/src/os/unix/ngx_linux_config.h
+++ b/src/os/unix/ngx_linux_config.h
@@ -34,8 +34,9 @@
 #define OFF_FMT    "%lld"
 #define SIZE_FMT   "%d"
 #define SIZEX_FMT  "%x"
+#define TIME_FMT   "%lu"
 #define PID_FMT    "%d"
-#define TIME_FMT   "%lu"
+#define RLIM_FMT   "%lu"
 
 
 
--- a/src/os/unix/ngx_linux_init.c
+++ b/src/os/unix/ngx_linux_init.c
@@ -3,12 +3,6 @@
 #include <ngx_core.h>
 
 
-/* STUB */
-ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
-ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in);
-int ngx_posix_init(ngx_log_t *log);
-
-
 char ngx_linux_kern_ostype[50];
 char ngx_linux_kern_osrelease[20];
 
new file mode 100644
--- /dev/null
+++ b/src/os/unix/ngx_os.h
@@ -0,0 +1,58 @@
+#ifndef _NGX_OS_H_INCLUDED_
+#define _NGX_OS_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#define NGX_IO_SENDFILE    1
+#define NGX_IO_ZEROCOPY    2
+
+#if (HAVE_SENDFILE)
+#define NGX_HAVE_SENDFILE  NGX_IO_SENDFILE
+#else
+#define NGX_HAVE_SENDFILE  0
+#endif
+
+#if (HAVE_ZEROCOPY)
+#define NGX_HAVE_ZEROCOPY  NGX_IO_ZEROCOPY
+#else
+#define NGX_HAVE_ZEROCOPY  0
+#endif
+
+
+
+typedef struct {
+    ssize_t       (*recv)(ngx_connection_t *c, char *buf, size_t size);
+    ssize_t       (*recv_chain)(ngx_connection_t *c, ngx_chain_t *in);
+    ssize_t       (*send)(ngx_connection_t *c, char *buf, size_t size);
+    ngx_chain_t  *(*send_chain)(ngx_connection_t *c, ngx_chain_t *in);
+    int             flags;
+} ngx_os_io_t;
+
+
+int ngx_os_init(ngx_log_t *log);
+int ngx_daemon(ngx_log_t *log);
+int ngx_posix_init(ngx_log_t *log);
+
+ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
+ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry);
+ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in);
+
+
+extern ngx_os_io_t  ngx_os_io;
+extern int          ngx_max_sockets;
+extern int          ngx_inherited_nonblocking;
+
+
+extern int          restart;
+extern int          rotate;
+
+
+#ifdef __FreeBSD__
+#include <ngx_freebsd.h>
+#endif
+
+
+#endif /* _NGX_OS_H_INCLUDED_ */
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -47,7 +47,7 @@ int ngx_posix_init(ngx_log_t *log)
     }
 
     ngx_log_error(NGX_LOG_INFO, log, 0,
-                  "getrlimit(RLIMIT_NOFILE): %qd:%qd",
+                  "getrlimit(RLIMIT_NOFILE): " RLIM_FMT ":" RLIM_FMT,
                   rlmt.rlim_cur, rlmt.rlim_max);
 
     ngx_max_sockets = rlmt.rlim_cur;
--- a/src/os/unix/ngx_solaris_config.h
+++ b/src/os/unix/ngx_solaris_config.h
@@ -22,6 +22,7 @@
 #include <sys/filio.h>          /* FIONBIO */
 #include <sys/stropts.h>        /* INFTIM */
 #include <sys/socket.h>
+#include <sys/systeminfo.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
@@ -32,8 +33,9 @@ typedef uint32_t  u_int32_t;
 #define OFF_FMT    "%lld"
 #define SIZE_FMT   "%d"
 #define SIZEX_FMT  "%x"
+#define TIME_FMT   "%lu"
 #define PID_FMT    "%ld"
-#define TIME_FMT   "%lu"
+#define RLIM_FMT   "%lu"
 
 
 #ifndef HAVE_SELECT
new file mode 100644
--- /dev/null
+++ b/src/os/unix/ngx_solaris_init.c
@@ -0,0 +1,51 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+char ngx_solaris_sysname[20];
+char ngx_solaris_release[10];
+char ngx_solaris_version[50];
+
+
+ngx_os_io_t ngx_os_io = {
+    ngx_unix_recv,
+    NULL,
+    NULL,
+    ngx_writev_chain,
+    NGX_HAVE_ZEROCOPY
+};
+
+
+int ngx_os_init(ngx_log_t *log)
+{
+    if (sysinfo(SI_SYSNAME, ngx_solaris_sysname, sizeof(ngx_solaris_sysname))
+                                                                         == -1)
+    {
+        ngx_log_error(NGX_LOG_ALERT, log, errno, "sysinfo(SI_SYSNAME) failed");
+        return NGX_ERROR;
+    }
+
+    if (sysinfo(SI_RELEASE, ngx_solaris_release, sizeof(ngx_solaris_release))
+                                                                         == -1)
+    {
+        ngx_log_error(NGX_LOG_ALERT, log, errno, "sysinfo(SI_RELEASE) failed");
+        return NGX_ERROR;
+    }
+
+    if (sysinfo(SI_VERSION, ngx_solaris_version, sizeof(ngx_solaris_version))
+                                                                         == -1)
+    {
+        ngx_log_error(NGX_LOG_ALERT, log, errno, "sysinfo(SI_SYSNAME) failed");
+        return NGX_ERROR;
+    }
+
+    ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %s %s"
+                  ngx_solaris_sysname, ngx_solaris_release);
+
+    ngx_log_error(NGX_LOG_INFO, log, 0, "version: %s",
+                  ngx_solaris_version);
+
+
+    return ngx_posix_init(log);
+}
--- a/src/os/unix/ngx_time.h
+++ b/src/os/unix/ngx_time.h
@@ -20,7 +20,10 @@ typedef struct tm      ngx_tm_t;
 #define ngx_tm_mon     tm_mon
 #define ngx_tm_year    tm_year
 #define ngx_tm_wday    tm_wday
+
+#ifndef SOLARIS
 #define ngx_tm_zone    tm_zone
+#endif
 
 
 void ngx_localtime(ngx_tm_t *tm);
--- a/src/os/win32/ngx_files.c
+++ b/src/os/win32/ngx_files.c
@@ -6,26 +6,49 @@
 ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
 {
     size_t      n;
-    long        high_offset;
-    ngx_err_t   err;
     OVERLAPPED  ovlp, *povlp;
 
+#if (WIN9X)
+
     if (ngx_win32_version < NGX_WIN_NT) {
-        high_offset = (long) (offset >> 32);
-        if (SetFilePointer(file->fd, (long) offset, &high_offset, FILE_BEGIN)
-                                                                 == 0xFFFFFFFF)
-        {
-            err = ngx_errno;
-            if (err != NO_ERROR) {
-                ngx_log_error(NGX_LOG_ERR, file->log, err,
-                              "SeekFilePointer() failed");
-                return NGX_ERROR;
+        long        high_offset;
+        ngx_err_t   err;
+
+        /*
+         * in Win9X the overlapped pointer must be NULL
+         * so we need to use SetFilePointer() to set the offset
+         */
+
+        if (file->offset != offset) {
+
+            /*
+             * the maximum file size on FAT16 is 2G, but on FAT32 it's 4G so we
+             * need to use high_offset because a single offset is signed value
+             */
+
+            high_offset = (long) (offset >> 32);
+            if (SetFilePointer(file->fd, (long) offset, &high_offset,
+                               FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+            {
+                /*
+                 * INVALID_SET_FILE_POINTER is 0xffffffff and it can be valid
+                 * value for large file so we need also to check GetLastError()
+                 */
+
+                err = ngx_errno;
+                if (err != NO_ERROR) {
+                    ngx_log_error(NGX_LOG_ERR, file->log, err,
+                                  "SeekFilePointer() failed");
+                    return NGX_ERROR;
+                }
             }
         }
 
         povlp = NULL;
 
     } else {
+
+#endif
         ovlp.Internal = 0;
         ovlp.InternalHigh = 0;
         ovlp.Offset = (DWORD) offset;
@@ -33,7 +56,10 @@ ssize_t ngx_read_file(ngx_file_t *file, 
         ovlp.hEvent = NULL;
 
         povlp = &ovlp;
+
+#if (WIN9X)
     }
+#endif
 
     if (ReadFile(file->fd, buf, size, &n, povlp) == 0) {
         ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "ReadFile() failed");
@@ -46,13 +72,66 @@ ssize_t ngx_read_file(ngx_file_t *file, 
 }
 
 
-/* TODO: as read file */
-
 ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
 {
-    size_t n;
+    size_t      n;
+    OVERLAPPED  ovlp, *povlp;
+
+#if (WIN9X)
+
+    if (ngx_win32_version < NGX_WIN_NT) {
+        long        high_offset;
+        ngx_err_t   err;
+
+        /*
+         * in Win9X the overlapped pointer must be NULL
+         * so we need to use SetFilePointer() to set the offset
+         */
+
+        if (file->offset != offset) {
+
+            /*
+             * the maximum file size on FAT16 is 2G, but on FAT32 it's 4G so we
+             * need to use high_offset because a single offset is signed value
+             */
 
-    if (WriteFile(file->fd, buf, size, &n, NULL) == 0) {
+            high_offset = (long) (offset >> 32);
+            if (SetFilePointer(file->fd, (long) offset, &high_offset,
+                               FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+            {
+                /*
+                 * INVALID_SET_FILE_POINTER is 0xffffffff and it can be valid
+                 * value for large file so we need also to check GetLastError()
+                 */
+
+                err = ngx_errno;
+                if (err != NO_ERROR) {
+                    ngx_log_error(NGX_LOG_ERR, file->log, err,
+                                  "SeekFilePointer() failed");
+                    return NGX_ERROR;
+                }
+            }
+        }
+
+        povlp = NULL;
+
+    } else {
+
+#endif
+
+        ovlp.Internal = 0;
+        ovlp.InternalHigh = 0;
+        ovlp.Offset = (DWORD) offset;
+        ovlp.OffsetHigh = (DWORD) (offset >> 32);
+        ovlp.hEvent = NULL;
+
+        povlp = &ovlp;
+
+#if (WIN9X)
+    }
+#endif
+
+    if (WriteFile(file->fd, buf, size, &n, povlp) == 0) {
         ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "WriteFile() failed");
         return NGX_ERROR;
     }
@@ -63,12 +142,15 @@ ssize_t ngx_write_file(ngx_file_t *file,
 }
 
 
-/* TODO: log error */
-
 int ngx_file_append_mode(ngx_fd_t fd)
 {
-    if (SetFilePointer(fd, 0, NULL, FILE_END) == 0xFFFFFFFF) {
-        if (GetLastError() != NO_ERROR) {
+    ngx_err_t  err;
+
+    if (SetFilePointer(fd, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) {
+        err = ngx_errno;
+        if (err != NO_ERROR) {
+            ngx_log_error(NGX_LOG_ERR, file->log, err,
+                          "SeekFilePointer() failed");
             return NGX_ERROR;
         }
     }
--- a/src/os/win32/ngx_files.h
+++ b/src/os/win32/ngx_files.h
@@ -6,11 +6,17 @@
 #include <ngx_core.h>
 
 
-/* INVALID_FILE_ATTRIBUTES specified but not defined at least in MSVC6SP2 */
+/* INVALID_FILE_ATTRIBUTES is specified but not defined at least in MSVC6SP2 */
 #ifndef INVALID_FILE_ATTRIBUTES
-#define INVALID_FILE_ATTRIBUTES     0xFFFFFFFF
+#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
 
new file mode 100644
--- /dev/null
+++ b/src/os/win32/ngx_os.h
@@ -0,0 +1,49 @@
+ifndef _NGX_OS_H_INCLUDED_
+#define _NGX_OS_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+#define NGX_IO_SENDFILE    1
+#define NGX_IO_ZEROCOPY    2
+
+#if (HAVE_SENDFILE)
+#define NGX_HAVE_SENDFILE  NGX_IO_SENDFILE
+#else
+#define NGX_HAVE_SENDFILE  0
+#endif
+
+#if (HAVE_ZEROCOPY)
+#define NGX_HAVE_ZEROCOPY  NGX_IO_ZEROCOPY
+#else
+#define NGX_HAVE_ZEROCOPY  0
+#endif
+
+
+
+typedef struct {
+    ssize_t       (*recv)(ngx_connection_t *c, char *buf, size_t size);
+    ssize_t       (*recv_chain)(ngx_connection_t *c, ngx_chain_t *in);
+    ssize_t       (*send)(ngx_connection_t *c, char *buf, size_t size);
+    ngx_chain_t  *(*send_chain)(ngx_connection_t *c, ngx_chain_t *in);
+    int             flags;
+} ngx_os_io_t;
+
+
+int ngx_os_init(ngx_log_t *log);
+
+
+extern ngx_os_io_t  ngx_os_io;
+extern int          ngx_max_sockets;
+extern int          ngx_inherited_nonblocking;
+extern int          ngx_win32_version;
+
+
+extern int          restart;
+extern int          rotate;
+
+
+
+#endif /* _NGX_OS_H_INCLUDED_ */
+
--- a/src/os/win32/ngx_win32_config.h
+++ b/src/os/win32/ngx_win32_config.h
@@ -4,10 +4,7 @@
 
 #define WIN32       1
 
-/* STUB */
 #define NGX_WIN_NT  200000
-extern int  ngx_win32_version;
-/**/