nginx-0.0.1-2002-08-06-20:39:45 import

The first code that uses "ngx_" prefix, the previous one used "gx_" prefix.
At that point the code is not yet usable.  The first draft ideas are dated
back to 23.10.2001.
diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h
new file mode 100644
index 0000000..c14a977
--- /dev/null
+++ b/src/os/unix/ngx_errno.h
@@ -0,0 +1,21 @@
+#ifndef _NGX_ERRNO_H_INCLUDED_
+#define _NGX_ERRNO_H_INCLUDED_
+
+
+#include <errno.h>
+#include <string.h>
+
+typedef int               ngx_err_t;
+
+#define NGX_ENOENT        ENOENT
+#define NGX_EINTR         EINTR
+#define NGX_EAGAIN        EWOULDBLOCK
+
+#define ngx_errno         errno
+#define ngx_socket_errno  errno
+
+#define ngx_strerror_r(err, errstr, size)  \
+             ngx_cpystrn(errstr, strerror(err), size) - (errstr)
+
+
+#endif /* _NGX_ERRNO_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_sendfile.c b/src/os/unix/ngx_sendfile.c
new file mode 100644
index 0000000..2bc1573
--- /dev/null
+++ b/src/os/unix/ngx_sendfile.c
@@ -0,0 +1,65 @@
+
+#include <ngx_config.h>
+#include <ngx_types.h>
+#include <ngx_errno.h>
+#include <ngx_log.h>
+#include <ngx_sendv.h>
+#include <ngx_sendfile.h>
+
+/*
+  TODO:
+    FreeBSD:
+       check sent if errno == EINTR then should return right sent.
+*/
+
+/*
+  returns
+      0 done
+     -1 error
+*/
+
+#if (HAVE_FREEBSD_SENDFILE)
+
+int ngx_sendfile(ngx_socket_t s,
+                 ngx_iovec_t *headers, int hdr_cnt,
+                 ngx_file_t fd, off_t offset, size_t nbytes,
+                 ngx_iovec_t *trailers, int trl_cnt,
+                 off_t *sent,
+                 ngx_log_t *log)
+{
+    int             rc, i;
+    ngx_err_t       err;
+    struct sf_hdtr  hdtr;
+
+    hdtr.headers = headers;
+    hdtr.hdr_cnt = hdr_cnt;
+    hdtr.trailers = trailers;
+    hdtr.trl_cnt = trl_cnt;
+
+#if (HAVE_FREEBSD_SENDFILE_NBYTES_BUG)
+    for (i = 0; i < hdr_cnt; i++)
+        nbytes += headers[i].iov_len;
+#endif
+
+    rc = sendfile(fd, s, offset, nbytes, &hdtr, sent, 0);
+
+    if (rc == -1) {
+        err = ngx_socket_errno;
+        if (err != NGX_EAGAIN && err != NGX_EINTR) {
+            ngx_log_error(NGX_LOG_ERR, log, err,
+                         "ngx_sendfile: sendfile failed");
+            return -1;
+
+        } else {
+            ngx_log_error(NGX_LOG_INFO, log, err,
+                         "ngx_sendfile: sendfile sent only %qd bytes", *sent);
+        }
+    }
+
+    ngx_log_debug(log, "ngx_sendfile: %d, @%qd %d:%qd" _
+                  rc _ offset _ nbytes _ *sent);
+
+    return 0;
+}
+
+#endif
diff --git a/src/os/unix/ngx_sendfile.h b/src/os/unix/ngx_sendfile.h
new file mode 100644
index 0000000..a347c6c
--- /dev/null
+++ b/src/os/unix/ngx_sendfile.h
@@ -0,0 +1,17 @@
+#ifndef _NGX_SENDFILE_H_INCLUDED_
+#define _NGX_SENDFILE_H_INCLUDED_
+
+
+#include <ngx_types.h>
+#include <ngx_log.h>
+#include <ngx_sendv.h>
+
+int ngx_sendfile(ngx_socket_t s,
+                 ngx_iovec_t *headers, int hdr_cnt,
+                 ngx_file_t fd, off_t offset, size_t nbytes,
+                 ngx_iovec_t *trailers, int trl_cnt,
+                 off_t *sent,
+                 ngx_log_t *log);
+
+
+#endif /* _NGX_SENDFILE_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_sendv.c b/src/os/unix/ngx_sendv.c
new file mode 100644
index 0000000..bd95d7a
--- /dev/null
+++ b/src/os/unix/ngx_sendv.c
@@ -0,0 +1,14 @@
+
+#include <ngx_types.h>
+#include <ngx_sendv.h>
+
+ssize_t ngx_sendv(ngx_socket_t s, ngx_iovec_t *iovec, int n, size_t *sent)
+{
+     ssize_t rc = writev(s, iovec, n);
+
+     if (rc == -1)
+         return -1;
+
+     *sent = rc;
+     return 0;
+}
diff --git a/src/os/unix/ngx_sendv.h b/src/os/unix/ngx_sendv.h
new file mode 100644
index 0000000..16c2403
--- /dev/null
+++ b/src/os/unix/ngx_sendv.h
@@ -0,0 +1,14 @@
+#ifndef _NGX_SENDV_H_INCLUDED_
+#define _NGX_SENDV_H_INCLUDED_
+
+
+#include <ngx_types.h>
+
+typedef struct iovec  ngx_iovec_t;
+#define ngx_iov_base  iov_base
+#define ngx_iov_len   iov_len
+
+ssize_t ngx_sendv(ngx_socket_t s, ngx_iovec_t *iovec, int n, size_t *sent);
+
+
+#endif /* _NGX_SENDV_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_stat.h b/src/os/unix/ngx_stat.h
new file mode 100644
index 0000000..f42edff
--- /dev/null
+++ b/src/os/unix/ngx_stat.h
@@ -0,0 +1,19 @@
+#ifndef _NGX_STAT_H_INCLUDED_
+#define _NGX_STAT_H_INCLUDED_
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+typedef struct stat  ngx_stat_t;
+
+#define ngx_is_dir(sb)           (S_ISDIR(sb.st_mode))
+
+#define ngx_stat(file, sb)       stat(file, sb)
+#define ngx_stat_n               "stat"
+
+#define ngx_fstat(file, fd, sb)  fstat(fd, sb)
+#define ngx_fstat_n              "stat"
+
+
+#endif /* _NGX_STAT_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_time.c b/src/os/unix/ngx_time.c
new file mode 100644
index 0000000..d4be966
--- /dev/null
+++ b/src/os/unix/ngx_time.c
@@ -0,0 +1,19 @@
+
+#include <ngx_config.h>
+#include <ngx_time.h>
+
+void ngx_localtime(ngx_tm_t *tm)
+{
+    time_t clock = time(NULL);
+    localtime_r(&clock, tm);
+}
+
+u_int ngx_msec(void)
+{
+    struct timeval  tv;
+
+    gettimeofday(&tv, NULL);
+
+    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
diff --git a/src/os/unix/ngx_time.h b/src/os/unix/ngx_time.h
new file mode 100644
index 0000000..b262da7
--- /dev/null
+++ b/src/os/unix/ngx_time.h
@@ -0,0 +1,22 @@
+#ifndef _NGX_TIME_H_INCLUDED_
+#define _NGX_TIME_H_INCLUDED_
+
+
+#include <ngx_config.h>
+
+typedef struct tm      ngx_tm_t;
+
+#define ngx_tm_sec     tm_sec
+#define ngx_tm_min     tm_min
+#define ngx_tm_hour    tm_hour
+#define ngx_tm_mday    tm_mday
+#define ngx_tm_mon     tm_mon
+#define ngx_tm_year    tm_year
+#define ngx_tm_wday    tm_wday
+
+void ngx_localtime(ngx_tm_t *tm);
+
+u_int ngx_msec(void);
+
+
+#endif /* _NGX_TIME_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_types.h b/src/os/unix/ngx_types.h
new file mode 100644
index 0000000..ebcbb1f
--- /dev/null
+++ b/src/os/unix/ngx_types.h
@@ -0,0 +1,12 @@
+#ifndef _NGX_TYPES_H_INCLUDED_
+#define _NGX_TYPES_H_INCLUDED_
+
+
+#include <ngx_config.h>
+
+
+typedef int  ngx_file_t;
+typedef int  ngx_socket_t;
+
+
+#endif /* _NGX_TYPES_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_errno.c b/src/os/win32/ngx_errno.c
new file mode 100644
index 0000000..ef91e88
--- /dev/null
+++ b/src/os/win32/ngx_errno.c
@@ -0,0 +1,38 @@
+
+/*
+   TODO:
+     add WSA error messages
+     test for English only messages
+*/
+
+#include <ngx_config.h>
+#include <ngx_string.h>
+#include <ngx_errno.h>
+
+int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size)
+{
+    int len;
+
+    len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+                        | FORMAT_MESSAGE_IGNORE_INSERTS,
+                        NULL, err,
+                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                        errstr, size, NULL);
+
+    /* add WSA error messages */
+
+    if (len == 0) {
+
+        len = ngx_snprintf(errstr, size,
+                           "FormatMessage error:(%d)", GetLastError());
+        return len;
+
+    }
+
+    /* remove ".\r\n\0" */
+    while (errstr[len] == '\0' || errstr[len] == CR
+           || errstr[len] == LF || errstr[len] == '.')
+        --len;
+
+    return ++len;
+}
diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h
new file mode 100644
index 0000000..dc4cd50
--- /dev/null
+++ b/src/os/win32/ngx_errno.h
@@ -0,0 +1,18 @@
+#ifndef _NGX_ERRNO_H_INCLUDED_
+#define _NGX_ERRNO_H_INCLUDED_
+
+
+#include <ngx_config.h>
+
+typedef DWORD             ngx_err_t;
+
+#define ngx_errno         GetLastError()
+#define ngx_socket_errno  WSAGetLastError()
+
+#define NGX_ENOENT        ERROR_FILE_NOT_FOUND
+#define NGX_EAGAIN        WSAEWOULDBLOCK
+
+int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size);
+
+
+#endif /* _NGX_ERRNO_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_sendfile.c b/src/os/win32/ngx_sendfile.c
new file mode 100644
index 0000000..922a4f1
--- /dev/null
+++ b/src/os/win32/ngx_sendfile.c
@@ -0,0 +1,89 @@
+
+#include <ngx_config.h>
+#include <ngx_types.h>
+#include <ngx_errno.h>
+#include <ngx_log.h>
+#include <ngx_sendv.h>
+#include <ngx_sendfile.h>
+
+/*
+  TODO:
+       various flags
+       TransmitPackets
+*/
+
+/*
+  returns
+      0 done
+     -1 error
+*/
+
+#if (HAVE_WIN32_TRANSMITFILE)
+
+int ngx_sendfile(ngx_socket_t s,
+                 ngx_iovec_t *headers, int hdr_cnt,
+                 ngx_file_t fd, off_t offset, size_t nbytes,
+                 ngx_iovec_t *trailers, int trl_cnt,
+                 off_t *sent,
+                 ngx_log_t *log)
+{
+    int                    tfrc, rc;
+    ngx_err_t              tf_err, err;
+    OVERLAPPED             olp;
+    TRANSMIT_FILE_BUFFERS  tfb, *ptfb;
+
+    tf_err = 0;
+    err = 0;
+
+    olp.Internal = 0;
+    olp.InternalHigh = 0;
+    olp.Offset = (DWORD) offset;
+    olp.OffsetHigh = (DWORD) (offset >> 32);
+    olp.hEvent = NULL;
+
+    if (headers || trailers) {
+        tfb.Head = headers->ngx_iov_base;
+        tfb.HeadLength = headers->ngx_iov_len;
+        tfb.Tail = trailers->ngx_iov_base;
+        tfb.TailLength = trailers->ngx_iov_len;
+        ptfb = &tfb;
+
+    } else {
+        ptfb = NULL;
+    }
+
+    tfrc = TransmitFile(s, fd, nbytes, 0, &olp, ptfb, 0);
+
+    if (tfrc == 0)
+        tf_err = ngx_socket_errno;
+
+    /* set sent */
+    rc = WSAGetOverlappedResult(s, &olp, (unsigned long *) sent, 0, NULL);
+
+    ngx_log_debug(log, "ngx_sendfile: %d, @%qd %d:%qd" _
+                  tfrc _ offset _ nbytes _ *sent);
+
+    if (rc == 0) {
+        err = ngx_socket_errno;
+        ngx_log_error(NGX_LOG_ERR, log, err,
+                     "ngx_sendfile: WSAGetOverlappedResult failed");
+    }
+
+    if (tfrc == 0) {
+        if (tf_err != NGX_EAGAIN) {
+            ngx_log_error(NGX_LOG_ERR, log, tf_err,
+                          "ngx_sendfile: TransmitFile failed");
+            return -1;
+        }
+
+        ngx_log_error(NGX_LOG_INFO, log, tf_err,
+                     "ngx_sendfile: TransmitFile sent only %qd bytes", *sent);
+    }
+
+    if (rc == 0)
+        return -1;
+
+    return 0;
+}
+
+#endif
diff --git a/src/os/win32/ngx_sendfile.h b/src/os/win32/ngx_sendfile.h
new file mode 100644
index 0000000..5bad2b9
--- /dev/null
+++ b/src/os/win32/ngx_sendfile.h
@@ -0,0 +1,18 @@
+#ifndef _NGX_SENDFILE_H_INCLUDED_
+#define _NGX_SENDFILE_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_types.h>
+#include <ngx_log.h>
+#include <ngx_sendv.h>
+
+int ngx_sendfile(ngx_socket_t s,
+                 ngx_iovec_t *headers, int hdr_cnt,
+                 ngx_file_t fd, off_t offset, size_t nbytes,
+                 ngx_iovec_t *trailers, int trl_cnt,
+                 off_t *sent,
+                 ngx_log_t *log);
+
+
+#endif /* _NGX_SENDFILE_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_sendv.h b/src/os/win32/ngx_sendv.h
new file mode 100644
index 0000000..0de4276
--- /dev/null
+++ b/src/os/win32/ngx_sendv.h
@@ -0,0 +1,14 @@
+#ifndef _NGX_SENDV_H_INCLUDED_
+#define _NGX_SENDV_H_INCLUDED_
+
+
+#include <ngx_config.h>
+
+typedef WSABUF        ngx_iovec_t;
+#define ngx_iov_base  buf
+#define ngx_iov_len   len
+
+#define ngx_sendv(s, iovec, n, sent)  WSASend(s, iovec, n, sent, 0, NULL, NULL)
+
+
+#endif /* _NGX_SENDV_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_stat.c b/src/os/win32/ngx_stat.c
new file mode 100644
index 0000000..5b1af30
--- /dev/null
+++ b/src/os/win32/ngx_stat.c
@@ -0,0 +1,15 @@
+
+#include <windows.h>
+
+#include <ngx_stat.h>
+
+int ngx_stat(char *file, ngx_stat_t *sb)
+{
+    *sb = GetFileAttributes(file);
+
+    if (*sb == INVALID_FILE_ATTRIBUTES) {
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/src/os/win32/ngx_stat.h b/src/os/win32/ngx_stat.h
new file mode 100644
index 0000000..600facd
--- /dev/null
+++ b/src/os/win32/ngx_stat.h
@@ -0,0 +1,26 @@
+#ifndef _NGX_STAT_H_INCLUDED_
+#define _NGX_STAT_H_INCLUDED_
+
+
+#include <windows.h>
+
+/* INVALID_FILE_ATTRIBUTES specified but never defined */
+#ifndef INVALID_FILE_ATTRIBUTES
+#define INVALID_FILE_ATTRIBUTES  0xFFFFFFFF
+#endif
+
+typedef DWORD  ngx_stat_t;
+
+
+#define ngx_is_dir(sb)           (*sb & FILE_ATTRIBUTE_DIRECTORY) 
+
+#define ngx_stat_n               "GetFileAttributes"
+
+#define ngx_fstat(file, fd, sb)  ngx_stat(file, sb)
+#define ngx_fstat_n              "GetFileAttributes"
+
+
+int ngx_stat(char *file, ngx_stat_t *sb);
+
+
+#endif /* _NGX_STAT_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_time.h b/src/os/win32/ngx_time.h
new file mode 100644
index 0000000..57915ac
--- /dev/null
+++ b/src/os/win32/ngx_time.h
@@ -0,0 +1,21 @@
+#ifndef _NGX_TIME_H_INCLUDED_
+#define _NGX_TIME_H_INCLUDED_
+
+
+#include <windows.h>
+
+typedef SYSTEMTIME     ngx_tm_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_localtime  GetLocalTime
+#define ngx_msec       GetTickCount
+
+
+#endif /* _NGX_TIME_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_types.h b/src/os/win32/ngx_types.h
new file mode 100644
index 0000000..5715e3f
--- /dev/null
+++ b/src/os/win32/ngx_types.h
@@ -0,0 +1,14 @@
+#ifndef _NGX_TYPES_H_INCLUDED_
+#define _NGX_TYPES_H_INCLUDED_
+
+
+#include <ngx_config.h>
+
+
+typedef HANDLE            ngx_file_t;
+typedef SOCKET            ngx_socket_t;
+typedef long              time_t;
+typedef unsigned __int64  off_t;
+
+
+#endif /* _NGX_TYPES_H_INCLUDED_ */