nginx-0.0.1-2003-05-21-17:28:21 import
diff --git a/src/os/unix/ngx_aio.h b/src/os/unix/ngx_aio.h
new file mode 100644
index 0000000..a37dafc
--- /dev/null
+++ b/src/os/unix/ngx_aio.h
@@ -0,0 +1,13 @@
+#ifndef _NGX_AIO_H_INCLUDED_
+#define _NGX_AIO_H_INCLUDED_
+
+
+#include <ngx_core.h>
+
+
+ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size);
+ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size);
+ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in);
+
+
+#endif /* _NGX_AIO_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_aio_read.c b/src/os/unix/ngx_aio_read.c
new file mode 100644
index 0000000..4896af9
--- /dev/null
+++ b/src/os/unix/ngx_aio_read.c
@@ -0,0 +1,110 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_aio.h>
+
+#if (HAVE_KQUEUE)
+#include <ngx_kqueue_module.h>
+#endif
+
+
+/*
+ The data is ready - 3 syscalls:
+ aio_read(), aio_error(), aio_return()
+ The data is not ready - 4 (kqueue) or 5 syscalls:
+ aio_read(), aio_error(), notifiction,
+ aio_error(), aio_return()
+ aio_cancel(), aio_error()
+*/
+
+
+ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
+{
+ int rc, first, canceled;
+ ngx_event_t *ev;
+
+ ev = c->read;
+
+ canceled = 0;
+
+ if (ev->timedout) {
+ ngx_set_socket_errno(NGX_ETIMEDOUT);
+ ngx_log_error(NGX_LOG_ERR, ev->log, 0, "aio_read() timed out");
+
+ rc = aio_cancel(c->fd, &ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
+ "aio_cancel() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_cancel: %d" _ rc);
+
+ canceled = 1;
+
+ ev->ready = 1;
+ }
+
+ first = 0;
+
+ if (!ev->ready) {
+ ngx_memzero(&ev->aiocb, sizeof(struct aiocb));
+
+ ev->aiocb.aio_fildes = c->fd;
+ ev->aiocb.aio_buf = buf;
+ ev->aiocb.aio_nbytes = size;
+
+#if (HAVE_KQUEUE)
+ ev->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue;
+ ev->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
+ ev->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev;
+#endif
+
+ if (aio_read(&ev->aiocb) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
+ "aio_read() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_read: OK");
+
+ ev->active = 1;
+ first = 1;
+ }
+
+ ev->ready = 0;
+
+ rc = aio_error(&ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_error() failed");
+ return NGX_ERROR;
+ }
+
+ if (rc != 0) {
+ if (rc == NGX_EINPROGRESS) {
+ if (!first) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, rc,
+ "aio_read() still in progress");
+ }
+ return NGX_AGAIN;
+ }
+
+ if (rc == NGX_ECANCELED && canceled) {
+ return NGX_ERROR;
+ }
+
+ ngx_log_error(NGX_LOG_CRIT, ev->log, rc, "aio_read() failed");
+ return NGX_ERROR;
+ }
+
+ rc = aio_return(&ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_return() failed");
+
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_read: %d" _ rc);
+
+ return rc;
+}
diff --git a/src/os/unix/ngx_aio_write.c b/src/os/unix/ngx_aio_write.c
new file mode 100644
index 0000000..918535a
--- /dev/null
+++ b/src/os/unix/ngx_aio_write.c
@@ -0,0 +1,112 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_aio.h>
+
+#if (HAVE_KQUEUE)
+#include <ngx_kqueue_module.h>
+#endif
+
+
+/*
+ The data is ready - 3 syscalls:
+ aio_write(), aio_error(), aio_return()
+ The data is not ready - 4 (kqueue) or 5 syscalls:
+ aio_write(), aio_error(), notifiction,
+ aio_error(), aio_return()
+ aio_cancel(), aio_error()
+*/
+
+ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size)
+{
+ int rc, first, canceled;
+ ngx_event_t *ev;
+
+ ev = c->write;
+
+ canceled = 0;
+
+ngx_log_debug(ev->log, "aio: ev->ready: %d" _ ev->ready);
+ngx_log_debug(ev->log, "aio: aiocb: %08x" _ &ev->aiocb);
+
+ if (ev->timedout) {
+ ngx_set_socket_errno(NGX_ETIMEDOUT);
+ ngx_log_error(NGX_LOG_ERR, ev->log, 0, "aio_write() timed out");
+
+ rc = aio_cancel(c->fd, &ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
+ "aio_cancel() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_cancel: %d" _ rc);
+
+ canceled = 1;
+
+ ev->ready = 1;
+ }
+
+ first = 0;
+
+ if (!ev->ready) {
+ ngx_memzero(&ev->aiocb, sizeof(struct aiocb));
+
+ ev->aiocb.aio_fildes = c->fd;
+ ev->aiocb.aio_buf = buf;
+ ev->aiocb.aio_nbytes = size;
+
+#if (HAVE_KQUEUE)
+ ev->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue;
+ ev->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
+ ev->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev;
+#endif
+
+ if (aio_write(&ev->aiocb) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
+ "aio_write() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_write: OK");
+
+ ev->active = 1;
+ first = 1;
+ }
+
+ ev->ready = 0;
+
+ rc = aio_error(&ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_error() failed");
+ return NGX_ERROR;
+ }
+
+ if (rc != 0) {
+ if (rc == NGX_EINPROGRESS) {
+ if (!first) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, rc,
+ "aio_write() still in progress");
+ }
+ return NGX_AGAIN;
+ }
+
+ if (rc == NGX_ECANCELED && canceled) {
+ return NGX_ERROR;
+ }
+
+ ngx_log_error(NGX_LOG_CRIT, ev->log, rc, "aio_write() failed");
+ return NGX_ERROR;
+ }
+
+ rc = aio_return(&ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_return() failed");
+
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_write: %d" _ rc);
+
+ return rc;
+}
diff --git a/src/os/unix/ngx_aio_write_chain.c b/src/os/unix/ngx_aio_write_chain.c
index 34c4f40..14586ce 100644
--- a/src/os/unix/ngx_aio_write_chain.c
+++ b/src/os/unix/ngx_aio_write_chain.c
@@ -1,14 +1,7 @@
#include <ngx_config.h>
-
#include <ngx_core.h>
-#include <ngx_types.h>
-#include <ngx_alloc.h>
-#include <ngx_array.h>
-#include <ngx_hunk.h>
-#include <ngx_connection.h>
-#include <ngx_sendv.h>
-#include <ngx_sendfile.h>
+#include <ngx_aio.h>
ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in)
@@ -25,19 +18,19 @@
while (ce) {
-ngx_log_debug(c->log, "aio_write ce: %x" _ ce->hunk->pos.mem);
+ngx_log_debug(c->log, "aio_write ce: %x" _ ce->hunk->pos);
- buf = prev = ce->hunk->pos.mem;
+ buf = prev = ce->hunk->pos;
size = 0;
/* coalesce the neighbouring chain entries */
- while (ce && prev == ce->hunk->pos.mem) {
- size += ce->hunk->last.mem - ce->hunk->pos.mem;
- prev = ce->hunk->last.mem;
+ while (ce && prev == ce->hunk->pos) {
+ size += ce->hunk->last - ce->hunk->pos;
+ prev = ce->hunk->last;
ce = ce->next;
}
- rc = ngx_event_aio_write(c, buf, size);
+ rc = ngx_aio_write(c, buf, size);
ngx_log_debug(c->log, "aio_write rc: %d" _ rc);
@@ -62,27 +55,27 @@
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "write chain: %x %qx %qd" _
ce->hunk->type _
- ce->hunk->pos.file _
- ce->hunk->last.file - ce->hunk->pos.file);
+ ce->hunk->file_pos _
+ ce->hunk->file_last - ce->hunk->file_pos);
#endif
- if (sent >= ce->hunk->last.file - ce->hunk->pos.file) {
- sent -= ce->hunk->last.file - ce->hunk->pos.file;
- ce->hunk->pos.file = ce->hunk->last.file;
+ if (sent >= ce->hunk->file_last - ce->hunk->file_pos) {
+ sent -= ce->hunk->file_last - ce->hunk->file_pos;
+ ce->hunk->file_pos = ce->hunk->file_last;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "write chain done: %qx %qd" _
- ce->hunk->pos.file _ sent);
+ ce->hunk->file_pos _ sent);
#endif
continue;
}
- ce->hunk->pos.file += sent;
+ ce->hunk->file_pos += sent;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "write chain rest: %qx %qd" _
- ce->hunk->pos.file _
- ce->hunk->last.file - ce->hunk->pos.file);
+ ce->hunk->file_pos _
+ ce->hunk->file_last - ce->hunk->file_pos);
#endif
break;
diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h
new file mode 100644
index 0000000..f8066e5
--- /dev/null
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -0,0 +1,112 @@
+#ifndef _NGX_FREEBSD_CONFIG_H_INCLUDED_
+#define _NGX_FREEBSD_CONFIG_H_INCLUDED_
+
+
+#include <unistd.h>
+#include <stddef.h> /* offsetof */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <osreldate.h>
+
+
+#ifndef HAVE_SELECT
+#define HAVE_SELECT 1
+#endif
+
+
+#ifndef HAVE_POLL
+#define HAVE_POLL 1
+#endif
+#if (HAVE_POLL)
+#include <poll.h>
+#endif
+
+ /* FreeBSD aio supported via kqueue */
+
+#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
+ || __FreeBSD_version >= 500014
+
+#ifndef HAVE_AIO
+#define HAVE_AIO 1
+#endif
+
+#endif
+
+#if (HAVE_AIO)
+#include <aio.h>
+#endif
+
+
+#if defined SO_ACCEPTFILTER && !defined HAVE_DEFERRED_ACCEPT
+#define HAVE_DEFERRED_ACCEPT 1
+#endif
+
+
+ /* FreeBSD sendfile */
+
+#if __FreeBSD_version >= 300007
+
+#ifndef HAVE_FREEBSD_SENDFILE
+#define HAVE_FREEBSD_SENDFILE 1
+#endif
+
+#endif
+
+
+#if (HAVE_FREEBSD_SENDFILE)
+#define HAVE_SENDFILE 1
+#endif
+
+
+ /* FreeBSD kqueue */
+
+#if (__FreeBSD__ == 4 && __FreeBSD_version >= 410000) \
+ || __FreeBSD_version >= 500011
+
+#ifndef HAVE_KQUEUE
+#define HAVE_KQUEUE 1
+#endif
+
+#endif
+
+#if (HAVE_KQUEUE)
+#include <sys/event.h>
+#endif
+
+
+ /* kqueue's NOTE_LOWAT */
+
+#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
+ || __FreeBSD_version >= 500018
+
+#ifndef HAVE_LOWAT_EVENT
+#define HAVE_LOWAT_EVENT 1
+#endif
+
+#endif
+
+
+
+
+#ifndef HAVE_INHERITED_NONBLOCK
+#define HAVE_INHERITED_NONBLOCK 1
+#endif
+
+
+#endif /* _NGX_FREEBSD_CONFIG_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c
index f9cba48..aac8ed9 100644
--- a/src/os/unix/ngx_freebsd_init.c
+++ b/src/os/unix/ngx_freebsd_init.c
@@ -12,9 +12,10 @@
ngx_os_io_t ngx_os_io = {
ngx_unix_recv,
+ ngx_readv_chain,
NULL,
- NULL,
- ngx_freebsd_write_chain
+ ngx_freebsd_write_chain,
+ NGX_HAVE_SENDFILE|NGX_HAVE_ZEROCOPY
};
@@ -107,5 +108,5 @@
ngx_log_error(NGX_LOG_INFO, log, 0, "net.inet.tcp.sendspace: %d",
ngx_freebsd_net_inet_tcp_sendspace);
- return ngx_unix_init(log);
+ return ngx_posix_init(log);
}
diff --git a/src/os/unix/ngx_freebsd_init.h b/src/os/unix/ngx_freebsd_init.h
index 6f58625..e81942b 100644
--- a/src/os/unix/ngx_freebsd_init.h
+++ b/src/os/unix/ngx_freebsd_init.h
@@ -7,8 +7,11 @@
#include <sys/sysctl.h>
-int ngx_unix_init(ngx_log_t *log);
+/* 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);
+/* */
extern int ngx_freebsd_kern_osreldate;
diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c
index 88ceced..8199d0b 100644
--- a/src/os/unix/ngx_freebsd_rfork_thread.c
+++ b/src/os/unix/ngx_freebsd_rfork_thread.c
@@ -168,7 +168,7 @@
static inline int ngx_gettid()
-{
+{
char *sp;
if (stack_size == 0) {
diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h
new file mode 100644
index 0000000..69a607e
--- /dev/null
+++ b/src/os/unix/ngx_linux_config.h
@@ -0,0 +1,48 @@
+#ifndef _NGX_LINUX_CONFIG_H_INCLUDED_
+#define _NGX_LINUX_CONFIG_H_INCLUDED_
+
+
+#include <unistd.h>
+#include <stddef.h> /* offsetof */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+
+#ifndef HAVE_SELECT
+#define HAVE_SELECT 1
+#endif
+
+
+#ifndef HAVE_POLL
+#define HAVE_POLL 1
+#endif
+#if (HAVE_POLL)
+#include <poll.h>
+#endif
+
+
+#if defined TCP_DEFER_ACCEPT && !defined HAVE_DEFERRED_ACCEPT
+#define HAVE_DEFERRED_ACCEPT 1
+#endif
+
+
+#ifndef HAVE_INHERITED_NONBLOCK
+#define HAVE_INHERITED_NONBLOCK 1
+#endif
+
+
+#endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c
new file mode 100644
index 0000000..aadb64c
--- /dev/null
+++ b/src/os/unix/ngx_posix_init.c
@@ -0,0 +1,70 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+int ngx_max_sockets;
+int ngx_inherited_nonblocking;
+
+
+int ngx_posix_init(ngx_log_t *log)
+{
+ struct sigaction sa;
+ struct rlimit rlmt;
+
+ ngx_memzero(&sa, sizeof(struct sigaction));
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+
+ if (sigaction(SIGPIPE, &sa, NULL) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ "sigaction(SIGPIPE, SIG_IGN) failed");
+ return NGX_ERROR;
+ }
+
+
+ if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, log, errno,
+ "getrlimit(RLIMIT_NOFILE) failed)");
+ return NGX_ERROR;
+ }
+
+ ngx_log_error(NGX_LOG_INFO, log, 0,
+ "getrlimit(RLIMIT_NOFILE): %qd:%qd",
+ rlmt.rlim_cur, rlmt.rlim_max);
+
+ ngx_max_sockets = rlmt.rlim_cur;
+
+#if (HAVE_INHERITED_NONBLOCK)
+ ngx_inherited_nonblocking = 1;
+#else
+ ngx_inherited_nonblocking = 0;
+#endif
+
+ return NGX_OK;
+}
+
+
+int ngx_posix_post_conf_init(ngx_log_t *log)
+{
+ ngx_fd_t pp[2];
+
+ if (pipe(pp) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed");
+ return NGX_ERROR;
+ }
+
+ if (dup2(pp[1], STDERR_FILENO) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed");
+ return NGX_ERROR;
+ }
+
+ if (pp[1] > STDERR_FILENO) {
+ if (close(pp[1]) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed");
+ return NGX_ERROR;
+ }
+ }
+
+ return NGX_OK;
+}
diff --git a/src/os/unix/ngx_recv_chain.c b/src/os/unix/ngx_readv_chain.c
similarity index 87%
rename from src/os/unix/ngx_recv_chain.c
rename to src/os/unix/ngx_readv_chain.c
index 4e93168..8432f0c 100644
--- a/src/os/unix/ngx_recv_chain.c
+++ b/src/os/unix/ngx_readv_chain.c
@@ -1,12 +1,9 @@
#include <ngx_config.h>
#include <ngx_core.h>
-#include <ngx_errno.h>
-#include <ngx_log.h>
-#include <ngx_connection.h>
-ssize_t ngx_recv_chain(ngx_connection_t *c, ngx_chain_t *entry)
+ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry)
{
ssize_t n;
struct iovec *iov;
diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c
index c6e8b03..b2be905 100644
--- a/src/os/unix/ngx_recv.c
+++ b/src/os/unix/ngx_recv.c
@@ -17,7 +17,7 @@
#if (HAVE_KQUEUE) /* DEBUG */
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
- ngx_log_debug(c->log, "ngx_recv: eof:%d, avail:%d, err:%d" _
+ ngx_log_debug(c->log, "recv: eof:%d, avail:%d, err:%d" _
ev->eof _ ev->available _ ev->error);
}
#endif
@@ -38,7 +38,7 @@
} else {
n = recv(c->fd, buf, size, 0);
-ngx_log_debug(c->log, "ngx_recv: read:%d:%d" _ n _ size);
+ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size);
if (n == -1) {
err = ngx_socket_errno;
@@ -49,6 +49,8 @@
n = recv(c->fd, buf, size, 0);
+ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size);
+
if (n == -1) {
err = ngx_socket_errno;
}
diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c
index d213fa8..0746fa0 100644
--- a/src/os/unix/ngx_socket.c
+++ b/src/os/unix/ngx_socket.c
@@ -2,12 +2,15 @@
#include <ngx_socket.h>
-/* ioctl(FIONBIO) set blocking mode with one syscall only while
+/*
+ ioctl(FIONBIO) set blocking mode with one syscall only while
fcntl(F_SETFL, ~O_NONBLOCK) need to know previous state
using fcntl(F_GETFL).
- On FreeBSD both are syscall */
-#ifdef __FreeBSD__
+ ioctl() and fcntl() are syscalls on FreeBSD, Solaris 7/8 and Linux
+*/
+
+#if 1
int ngx_nonblocking(ngx_socket_t s)
{
diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h
index 937c12d..cee1f4a 100644
--- a/src/os/unix/ngx_socket.h
+++ b/src/os/unix/ngx_socket.h
@@ -4,10 +4,6 @@
#include <ngx_config.h>
-#ifdef __FreeBSD__
-#include <sys/ioctl.h>
-#endif
-
#define NGX_WRITE_SHUTDOWN SHUT_WR
@@ -17,7 +13,7 @@
#define ngx_socket_n "socket()"
-#ifdef __FreeBSD__
+#if 1
int ngx_nonblocking(ngx_socket_t s);
int ngx_blocking(ngx_socket_t s);
diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h
new file mode 100644
index 0000000..1545fc9
--- /dev/null
+++ b/src/os/unix/ngx_solaris_config.h
@@ -0,0 +1,64 @@
+#ifndef _NGX_SOLARIS_CONFIG_H_INCLUDED_
+#define _NGX_SOLARIS_CONFIG_H_INCLUDED_
+
+
+#define SOLARIS 1
+
+#define _FILE_OFFSET_BITS 64 /* must be before sys/types.h */
+
+#include <unistd.h>
+#include <stddef.h> /* offsetof */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <time.h>
+#include <signal.h>
+#include <string.h>
+#include <strings.h> /* bzero() */
+#include <sys/types.h>
+#include <sys/filio.h> /* FIONBIO */
+#include <sys/stropts.h> /* INFTIM */
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+
+typedef uint32_t u_int32_t;
+
+
+#ifndef HAVE_SELECT
+#define HAVE_SELECT 1
+#endif
+
+
+#ifndef HAVE_POLL
+#define HAVE_POLL 1
+#endif
+#if (HAVE_POLL)
+#include <poll.h>
+#endif
+
+
+#if (HAVE_AIO)
+#include <aio.h>
+#endif
+
+
+#if (HAVE_DEVPOLL)
+#include <sys/ioctl.h>
+#include <sys/devpoll.h>
+#endif
+
+
+#ifndef HAVE_INHERITED_NONBLOCK
+#define HAVE_INHERITED_NONBLOCK 1
+#endif
+
+
+#endif /* _NGX_SOLARIS_CONFIG_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_unix_init.c b/src/os/unix/ngx_unix_init.c
index 7b38bb1..9574164 100644
--- a/src/os/unix/ngx_unix_init.c
+++ b/src/os/unix/ngx_unix_init.c
@@ -3,61 +3,30 @@
#include <ngx_core.h>
-int ngx_max_sockets;
+/* 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);
+int ngx_posix_post_conf_init(ngx_log_t *log);
+/* */
-int ngx_unix_init(ngx_log_t *log)
+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)
{
- struct sigaction sa;
- struct rlimit rlmt;
-
- ngx_memzero(&sa, sizeof(struct sigaction));
- sa.sa_handler = SIG_IGN;
- sigemptyset(&sa.sa_mask);
-
- if (sigaction(SIGPIPE, &sa, NULL) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "sigaction(SIGPIPE, SIG_IGN) failed");
- return NGX_ERROR;
- }
-
-
- if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, errno,
- "getrlimit(RLIMIT_NOFILE) failed)");
- return NGX_ERROR;
- }
-
- ngx_log_error(NGX_LOG_INFO, log, 0,
- "getrlimit(RLIMIT_NOFILE): %qd:%qd",
- rlmt.rlim_cur, rlmt.rlim_max);
-
- ngx_max_sockets = rlmt.rlim_cur;
-
- return NGX_OK;
+ return ngx_posix_init(log);
}
-int ngx_unix_post_conf_init(ngx_log_t *log)
+int ngx_os_post_conf_init(ngx_log_t *log)
{
- ngx_fd_t pp[2];
-
- if (pipe(pp) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed");
- return NGX_ERROR;
- }
-
- if (dup2(pp[1], STDERR_FILENO) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed");
- return NGX_ERROR;
- }
-
- if (pp[1] > STDERR_FILENO) {
- if (close(pp[1]) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed");
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
+ return ngx_posix_post_conf_init(log);
}
diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c
new file mode 100644
index 0000000..fdaa52a
--- /dev/null
+++ b/src/os/unix/ngx_writev_chain.c
@@ -0,0 +1,93 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
+{
+ char *prev;
+ size_t size;
+ ssize_t n;
+ off_t sent;
+ struct iovec *iov;
+ ngx_err_t err;
+ ngx_array_t io;
+ ngx_chain_t *ce;
+
+ ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
+
+ prev = NULL;
+ iov = NULL;
+
+ /* create the iovec and coalesce the neighbouring chain entries */
+ for (ce = in; ce; ce = ce->next) {
+
+ if (prev == ce->hunk->pos) {
+ iov->iov_len += ce->hunk->last - ce->hunk->pos;
+ prev = ce->hunk->last;
+
+ } else {
+ ngx_test_null(iov, ngx_push_array(&io), NGX_CHAIN_ERROR);
+ iov->iov_base = ce->hunk->pos;
+ iov->iov_len = ce->hunk->last - ce->hunk->pos;
+ prev = ce->hunk->last;
+ }
+ }
+
+ n = writev(c->fd, (struct iovec *) io.elts, io.nelts);
+
+ if (n == -1) {
+ err = ngx_errno;
+ if (err == NGX_EAGAIN) {
+ ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
+
+ } else if (err == NGX_EINTR) {
+ ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
+
+ } else {
+ ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
+ return NGX_CHAIN_ERROR;
+ }
+ }
+
+ sent = n > 0 ? n : 0;
+
+#if (NGX_DEBUG_WRITE_CHAIN)
+ ngx_log_debug(c->log, "writev: %qd" _ sent);
+#endif
+
+ c->sent += sent;
+
+ for (ce = in; ce && sent > 0; ce = ce->next) {
+
+ size = ce->hunk->last - ce->hunk->pos;
+
+ if (sent >= size) {
+ sent -= size;
+
+ if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
+ ce->hunk->pos = ce->hunk->last;
+ }
+
+ if (ce->hunk->type & NGX_HUNK_FILE) {
+ ce->hunk->file_pos = ce->hunk->file_last;
+ }
+
+ continue;
+ }
+
+ if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
+ ce->hunk->pos += sent;
+ }
+
+ if (ce->hunk->type & NGX_HUNK_FILE) {
+ ce->hunk->file_pos += sent;
+ }
+
+ break;
+ }
+
+ ngx_destroy_array(&io);
+
+ return ce;
+}
diff --git a/src/os/win32/ngx_init.c b/src/os/win32/ngx_init.c
index 8c3511f..4f356a1 100644
--- a/src/os/win32/ngx_init.c
+++ b/src/os/win32/ngx_init.c
@@ -7,17 +7,10 @@
ngx_os_io_t ngx_os_io = {
-#if 0
- ngx_unix_recv,
- NULL,
- NULL,
- ngx_freebsd_write_chain
-#else
- NULL,
+ ngx_wsarecv,
NULL,
NULL,
NULL
-#endif
};
diff --git a/src/os/win32/ngx_recv.c b/src/os/win32/ngx_recv.c
new file mode 100644
index 0000000..ad2232c
--- /dev/null
+++ b/src/os/win32/ngx_recv.c
@@ -0,0 +1,93 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
+{
+ int rc;
+ u_int flags;
+ size_t bytes;
+ ngx_err_t err;
+ WSABUF wsabuf[1];
+ ngx_event_t *ev;
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE handler;
+
+ ev = c->read;
+
+/* DEBUG */ bytes = 0;
+
+ if (ev->timedout) {
+ ngx_set_socket_errno(NGX_ETIMEDOUT);
+ ngx_log_error(NGX_LOG_ERR, ev->log, 0, "WSARecv() timed out");
+
+ return NGX_ERROR;
+ }
+
+ if (ev->ready) {
+ ev->ready = 0;
+
+#if (HAVE_IOCP_EVENT) /* iocp */
+
+ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
+ if (ev->ovlp.error) {
+ ngx_log_error(NGX_LOG_ERR, c->log, ev->ovlp.error,
+ "WSARecv() failed");
+ return NGX_ERROR;
+ }
+
+ return ev->available;
+ }
+
+#endif
+
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &ev->ovlp,
+ &bytes, 0, NULL) == 0) {
+ err = ngx_socket_errno;
+ ngx_log_error(NGX_LOG_CRIT, ev->log, err,
+ "WSARecv() or WSAGetOverlappedResult() failed");
+
+ return NGX_ERROR;
+ }
+
+ return bytes;
+ }
+
+ ngx_memzero(&ev->ovlp, sizeof(WSAOVERLAPPED));
+ wsabuf[0].buf = buf;
+ wsabuf[0].len = size;
+ flags = 0;
+
+#if 0
+ handler = ev->handler;
+#else
+ handler = NULL;
+#endif
+
+ rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags,
+ (LPWSAOVERLAPPED) &ev->ovlp, handler);
+
+ ngx_log_debug(ev->log, "WSARecv: %d:%d" _ rc _ bytes);
+
+ if (rc == -1) {
+ err = ngx_socket_errno;
+ if (err == WSA_IO_PENDING) {
+ return NGX_AGAIN;
+
+ } else {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, err, "WSARecv() failed");
+ return NGX_ERROR;
+ }
+ }
+
+#if (HAVE_IOCP_EVENT) /* iocp */
+
+ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
+ return NGX_AGAIN;
+ }
+
+#endif
+
+ return bytes;
+}
diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h
new file mode 100644
index 0000000..1cad3ed
--- /dev/null
+++ b/src/os/win32/ngx_win32_config.h
@@ -0,0 +1,35 @@
+#ifndef _NGX_WIN32_CONFIG_H_INCLUDED_
+#define _NGX_WIN32_CONFIG_H_INCLUDED_
+
+
+#define WIN32 1
+
+#include <winsock2.h>
+#include <mswsock.h>
+#include <stddef.h> /* offsetof */
+#include <stdio.h>
+#include <stdarg.h>
+
+
+#define ngx_inline __inline
+
+
+#ifndef HAVE_INHERITED_NONBLOCK
+#define HAVE_INHERITED_NONBLOCK 1
+#endif
+
+#ifndef HAVE_WIN32_TRANSMITPACKETS
+#define HAVE_WIN32_TRANSMITPACKETS 1
+#define HAVE_WIN32_TRANSMITFILE 0
+#endif
+
+#ifndef HAVE_WIN32_TRANSMITFILE
+#define HAVE_WIN32_TRANSMITFILE 1
+#endif
+
+#if (HAVE_WIN32_TRANSMITPACKETS) || (HAVE_WIN32_TRANSMITFILE)
+#define HAVE_SENDFILE 1
+#endif
+
+
+#endif /* _NGX_WIN32_CONFIG_H_INCLUDED_ */