diff options
author | Igor Sysoev <igor@sysoev.ru> | 2002-08-06 16:39:45 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2002-08-06 16:39:45 +0000 |
commit | 6de5c2cb63f8aee4bcbec3c363a72fd8e4a4e64d (patch) | |
tree | 0e4da305f8101799b6c6aa3002cecf539c2578c0 /src/core | |
download | nginx-6de5c2cb63f8aee4bcbec3c363a72fd8e4a4e64d.tar.gz nginx-6de5c2cb63f8aee4bcbec3c363a72fd8e4a4e64d.zip |
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.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/nginx.c | 118 | ||||
-rw-r--r-- | src/core/nginx.h | 8 | ||||
-rw-r--r-- | src/core/ngx_alloc.c | 136 | ||||
-rw-r--r-- | src/core/ngx_alloc.h | 42 | ||||
-rw-r--r-- | src/core/ngx_array.c | 69 | ||||
-rw-r--r-- | src/core/ngx_array.h | 23 | ||||
-rw-r--r-- | src/core/ngx_auto_config.h | 4 | ||||
-rw-r--r-- | src/core/ngx_config.h | 130 | ||||
-rw-r--r-- | src/core/ngx_connection.h | 54 | ||||
-rw-r--r-- | src/core/ngx_hunk.c | 85 | ||||
-rw-r--r-- | src/core/ngx_hunk.h | 57 | ||||
-rw-r--r-- | src/core/ngx_listen.c | 44 | ||||
-rw-r--r-- | src/core/ngx_listen.h | 9 | ||||
-rw-r--r-- | src/core/ngx_log.c | 116 | ||||
-rw-r--r-- | src/core/ngx_log.h | 118 | ||||
-rw-r--r-- | src/core/ngx_server.h | 30 | ||||
-rw-r--r-- | src/core/ngx_string.c | 21 | ||||
-rw-r--r-- | src/core/ngx_string.h | 26 |
18 files changed, 1090 insertions, 0 deletions
diff --git a/src/core/nginx.c b/src/core/nginx.c new file mode 100644 index 000000000..f1671b38d --- /dev/null +++ b/src/core/nginx.c @@ -0,0 +1,118 @@ + +#include <nginx.h> + +#include <ngx_config.h> +#include <ngx_string.h> +#include <ngx_log.h> +#include <ngx_alloc.h> +#include <ngx_server.h> +#include <ngx_connection.h> +#include <ngx_listen.h> + +/* +#include <ngx_http.h> +*/ + + +#if !(WIN32) +static int ngx_options(int argc, char *const *argv); +#endif + +char *ngx_root = "/home/is/work/xml/xml/html"; + +int ngx_http_init_connection(void *data); + + +int ngx_max_conn = 512; +struct sockaddr_in ngx_addr = {0, AF_INET, 0, 0, 0}; + + +ngx_pool_t ngx_pool; +ngx_log_t ngx_log; +ngx_server_t ngx_server; + + +int main(int argc, char *const *argv) +{ + char addr_text[22]; + ngx_socket_t fd; + ngx_listen_t ls; +#if (WIN32) + WSADATA wsd; +#endif + + + ngx_log.log_level = NGX_LOG_DEBUG; + ngx_pool.log = &ngx_log; + ngx_addr.sin_port = htons(8000); + ngx_addr.sin_family = AF_INET; + +#if !(WIN32) + if (ngx_options(argc, argv) == -1) + ngx_log_error(NGX_LOG_EMERG, (&ngx_log), 0, "invalid argument"); +#endif + + ngx_log_debug((&ngx_log), "%d, %s:%d" _ ngx_max_conn _ + inet_ntoa(ngx_addr.sin_addr) _ ntohs(ngx_addr.sin_port)); + +#if (WIN32) + if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) + ngx_log_error(NGX_LOG_EMERG, (&ngx_log), ngx_socket_errno, + "WSAStartup failed"); +#endif + + ngx_snprintf(ngx_cpystrn(addr_text, inet_ntoa(ngx_addr.sin_addr), 16), + 7, ":%d", ntohs(ngx_addr.sin_port)); + fd = ngx_listen((struct sockaddr *) &ngx_addr, -1, &ngx_log, addr_text); + + ngx_server.buff_size = 1024; + ngx_server.handler = ngx_http_init_connection; + + /* daemon */ + + ls.fd = fd; + ls.server = &ngx_server; + ls.log = &ngx_log; + + /* fork */ + + ngx_worker(&ls, 1, &ngx_pool, &ngx_log); +} + +#if !(WIN32) +extern char *optarg; + +static int ngx_options(int argc, char *const *argv) +{ + char ch, *pos; + int port; + + while ((ch = getopt(argc, argv, "l:c:")) != -1) { + switch (ch) { + case 'l': + if (pos = strchr(optarg, ':')) { + *(pos) = '\0'; + if ((port = atoi(pos + 1)) <= 0) + return -1; + ngx_addr.sin_port = htons(port); + } + + if ((ngx_addr.sin_addr.s_addr = inet_addr(optarg)) == INADDR_NONE) + return -1; + break; + + case 'c': + if ((ngx_max_conn = atoi(optarg)) <= 0) + return -1; + break; + + case '?': + default: + return -1; + } + + } + + return 0; +} +#endif diff --git a/src/core/nginx.h b/src/core/nginx.h new file mode 100644 index 000000000..0f4b0de0f --- /dev/null +++ b/src/core/nginx.h @@ -0,0 +1,8 @@ +#ifndef _NGINX_H_INCLUDED_ +#define _NGINX_H_INCLUDED_ + + +extern char *gx_root; + + +#endif /* _NGINX_H_INCLUDED_ */ diff --git a/src/core/ngx_alloc.c b/src/core/ngx_alloc.c new file mode 100644 index 000000000..61ecabc4e --- /dev/null +++ b/src/core/ngx_alloc.c @@ -0,0 +1,136 @@ + +#include <ngx_config.h> + +#include <ngx_errno.h> +#include <ngx_log.h> +#include <ngx_alloc.h> + + +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, + "ngx_alloc: malloc %d bytes failed", 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; +} + +ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log) +{ + ngx_pool_t *p; + + ngx_test_null(p, ngx_alloc(size, log), NULL); + + p->last = (char *) p + sizeof(ngx_pool_t); + p->end = (char *) p + size; + p->next = NULL; + p->large = NULL; + p->log = log; + + return p; +} + +void ngx_destroy_pool(ngx_pool_t *pool) +{ + ngx_pool_t *p, *n; + ngx_pool_large_t *l; + + for (l = pool->large; l; l = l->next) + free(l->alloc); + + for (p = pool, n = pool->next; /* void */; p = n, n = n->next) { + free(p); + + if (n == NULL) + break; + } +} + +void *ngx_palloc(ngx_pool_t *pool, size_t size) +{ + void *m; + ngx_pool_t *p, *n; + ngx_pool_large_t *large, *last; + + if (size <= NGX_MAX_ALLOC_FROM_POOL) { + + for (p = pool, n = pool->next; /* void */; p = n, n = n->next) { + if ((size_t) (p->end - p->last) >= size) { + m = p->last; + p->last += size; + + return m; + } + + if (n == NULL) + break; + } + + /* alloc new pool block */ + ngx_test_null(n, ngx_create_pool(p->end - (char *) p, p->log), NULL); + p->next = n; + m = n->last; + n->last += size; + return m; + + /* alloc large block */ + } else { + large = NULL; + last = NULL; + + if (pool->large) { + for (last = pool->large; /* void */; last = last->next) { + if (last->alloc == NULL) { + large = last; + last = NULL; + break; + } + + if (last->next == NULL) + break; + } + } + + if (large == NULL) { + ngx_test_null(large, ngx_palloc(pool, sizeof(ngx_pool_large_t)), + NULL); + } + + ngx_test_null(p, ngx_alloc(size, pool->log), NULL); + + if (pool->large == NULL) { + pool->large = large; + + } else if (last) { + last->next = large; + } + + large->alloc = p; + + return p; + } +} + +void *ngx_pcalloc(ngx_pool_t *pool, size_t size) +{ + void *p; + + p = ngx_palloc(pool, size); + if (p) + ngx_memzero(p, size); + + return p; +} diff --git a/src/core/ngx_alloc.h b/src/core/ngx_alloc.h new file mode 100644 index 000000000..1d1ad8425 --- /dev/null +++ b/src/core/ngx_alloc.h @@ -0,0 +1,42 @@ +#ifndef _NGX_ALLOC_H_INCLUDED_ +#define _NGX_ALLOC_H_INCLUDED_ + + +#include <ngx_config.h> + +#include <ngx_log.h> + + +#define NGX_MAX_ALLOC_FROM_POOL (8192 - sizeof(ngx_pool_t)) +#define NGX_DEFAULT_POOL_SIZE (16 * 1024) + +#define ngx_test_null(p, alloc, rc) if ((p = alloc) == NULL) return rc + + +typedef struct ngx_pool_large_s ngx_pool_large_t; +struct ngx_pool_large_s { + ngx_pool_large_t *next; + void *alloc; +}; + +typedef struct ngx_pool_s ngx_pool_t; +struct ngx_pool_s { + char *last; + char *end; + ngx_pool_t *next; + ngx_pool_large_t *large; + ngx_log_t *log; +}; + + +void *ngx_alloc(size_t size, ngx_log_t *log); +void *ngx_calloc(size_t size, ngx_log_t *log); + +ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log); +void ngx_destroy_pool(ngx_pool_t *pool); + +void *ngx_palloc(ngx_pool_t *pool, size_t size); +void *ngx_pcalloc(ngx_pool_t *pool, size_t size); + + +#endif /* _NGX_ALLOC_H_INCLUDED_ */ diff --git a/src/core/ngx_array.c b/src/core/ngx_array.c new file mode 100644 index 000000000..08ad5887b --- /dev/null +++ b/src/core/ngx_array.c @@ -0,0 +1,69 @@ + +#include <ngx_config.h> + +#include <ngx_alloc.h> +#include <ngx_array.h> + +ngx_array_t *ngx_create_array(ngx_pool_t *p, int n, size_t size) +{ + ngx_array_t *a; + + a = ngx_palloc(p, sizeof(ngx_array_t)); + if (a == NULL) + return NULL; + + a->elts = ngx_palloc(p, n * size); + if (a->elts == NULL) + return NULL; + + a->pool = p; + a->nelts = 0; + a->nalloc = n; + a->size = size; + + return a; +} + +void ngx_destroy_array(ngx_array_t *a) +{ + ngx_pool_t *p = a->pool; + + if (a->elts + a->size * a->nalloc == p->last) + p->last -= a->size * a->nalloc; + + if ((char *) a + sizeof(ngx_array_t) == p->last) + p->last = (char *) a; +} + +void *ngx_push_array(ngx_array_t *a) +{ + void *elt; + + /* array is full */ + if (a->nelts == a->nalloc) { + ngx_pool_t *p = a->pool; + + /* array allocation is the last in the pool */ + if (a->elts + a->size * a->nelts == p->last + && (unsigned) (p->end - p->last) >= a->size) + { + p->last += a->size; + a->nalloc++; + + /* allocate new array */ + } else { + void *new = ngx_palloc(p, 2 * a->nalloc * a->size); + if (new == NULL) + return NULL; + + memcpy(new, a->elts, a->nalloc * a->size); + a->elts = new; + a->nalloc *= 2; + } + } + + elt = a->elts + a->size * a->nelts; + a->nelts++; + + return elt; +} diff --git a/src/core/ngx_array.h b/src/core/ngx_array.h new file mode 100644 index 000000000..d110b7688 --- /dev/null +++ b/src/core/ngx_array.h @@ -0,0 +1,23 @@ +#ifndef _NGX_ARRAY_H_INCLUDED_ +#define _NGX_ARRAY_H_INCLUDED_ + + +#include <ngx_config.h> + +#include <ngx_alloc.h> + +typedef struct { + char *elts; + int nelts; + size_t size; + int nalloc; + ngx_pool_t *pool; +} ngx_array_t; + + +ngx_array_t *ngx_create_array(ngx_pool_t *p, int n, size_t size); +void ngx_destroy_array(ngx_array_t *a); +void *ngx_push_array(ngx_array_t *a); + + +#endif /* _NGX_ARRAY_H_INCLUDED_ */ diff --git a/src/core/ngx_auto_config.h b/src/core/ngx_auto_config.h new file mode 100644 index 000000000..d9865c42d --- /dev/null +++ b/src/core/ngx_auto_config.h @@ -0,0 +1,4 @@ + +#ifndef OFF_EQUAL_PTR +#define OFF_EQUAL_PTR 0 +#endif diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h new file mode 100644 index 000000000..1412da85a --- /dev/null +++ b/src/core/ngx_config.h @@ -0,0 +1,130 @@ +#ifndef _NGX_CONFIG_H_INCLUDED_ +#define _NGX_CONFIG_H_INCLUDED_ + + +#include <ngx_auto_config.h> + +/* + auto_conf + ngx_inline inline __inline __inline__ +*/ + +#define FD_SETSIZE 1024 + + +#ifdef _WIN32 + +#define WIN32 1 + +#include <winsock2.h> +#include <mswsock.h> +#include <stdio.h> +#include <stdarg.h> + + +#define ngx_inline __inline + +#define ngx_memzero ZeroMemory + +#define ngx_close_socket closesocket + +#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 + +#else /* POSIX */ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <fcntl.h> +#include <string.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#define ngx_inline inline + +#define ngx_memzero bzero + +#define ngx_close_socket close + +#endif /* POSIX */ + + + +#define LF 10 +#define CR 13 +#define CRLF "\x0d\x0a" + + + +#if defined SO_ACCEPTFILTER || defined TCP_DEFER_ACCEPT + +#ifndef HAVE_DEFERRED_ACCEPT +#define HAVE_DEFERRED_ACCEPT 1 +#endif + +#endif + + + +#ifdef __FreeBSD__ + +#include <osreldate.h> + +#if __FreeBSD_version >= 300007 + +#ifndef HAVE_FREEBSD_SENDFILE +#define HAVE_FREEBSD_SENDFILE 1 +#endif + +#ifndef HAVE_FREEBSD_SENDFILE_NBYTES_BUG +#define HAVE_FREEBSD_SENDFILE_NBYTES_BUG 2 +#endif + +#endif + +#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460100) \ + || __FreeBSD_version == 460001 + || __FreeBSD_version >= 500029 + +#if (HAVE_FREEBSD_SENDFILE_NBYTES_BUG == 2) +#define HAVE_FREEBSD_SENDFILE_NBYTES_BUG 0 +#endif + +#endif + +#if (HAVE_FREEBSD_SENDFILE) +#define HAVE_SENDFILE 1 +#endif + + +#if (__FreeBSD__ == 4 && __FreeBSD_version >= 410000) \ + || __FreeBSD_version >= 500011 + +#ifndef HAVE_KQUEUE +#define HAVE_KQUEUE 1 +#include <sys/event.h> +#endif + +#endif + + +#endif /* __FreeBSD__ */ + + +#endif /* _NGX_CONFIG_H_INCLUDED_ */ diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h new file mode 100644 index 000000000..17bd58ac5 --- /dev/null +++ b/src/core/ngx_connection.h @@ -0,0 +1,54 @@ +#ifndef _NGX_CONNECTION_H_INCLUDED_ +#define _NGX_CONNECTION_H_INCLUDED_ + +#include <ngx_log.h> +#include <ngx_alloc.h> +#include <ngx_server.h> + +typedef struct ngx_connection_s ngx_connection_t; + +#ifdef NGX_EVENT +#include <ngx_event.h> +#endif + +struct ngx_connection_s { + ngx_socket_t fd; + void *data; + +#ifdef NGX_EVENT + ngx_event_t *read; + ngx_event_t *write; +#endif + + ngx_log_t *log; + ngx_server_t *server; + ngx_server_t *servers; + ngx_pool_t *pool; +}; + + +/* + +cached file + int fd; -2 unused, -1 closed (but read or mmaped), >=0 open + char *name; + + void *buf; addr if read or mmaped + aiocb* if aio_read + OVERLAPPED if TransmitFile or TransmitPackets + NULL if sendfile + + size_t buf_size; for plain read + off_t offset; for plain read + + size_t size; + time_t mod; + char *last_mod; 'Sun, 17 Mar 2002 19:39:50 GMT' + char *etag; '"a6d08-1302-3c94f106"' + char *len; '4866' + +EV_VNODE should notify by some signal if diretory tree is changed + or stat if aged >= N seconds (big enough) +*/ + +#endif /* _NGX_CONNECTION_H_INCLUDED_ */ diff --git a/src/core/ngx_hunk.c b/src/core/ngx_hunk.c new file mode 100644 index 000000000..3defc6d0b --- /dev/null +++ b/src/core/ngx_hunk.c @@ -0,0 +1,85 @@ + +#include <ngx_types.h> +#include <ngx_hunk.h> + + +ngx_hunk_t *ngx_get_hunk(ngx_pool_t *pool, int size, int before, int after) +{ + ngx_hunk_t *h = ngx_palloc(pool, sizeof(ngx_hunk_t)); + +#ifndef OFF_EQUAL_PTR + h->pos.f = h->last.f = 0; +#endif + + h->pre_start = ngx_palloc(pool, size + before + after); + h->start = h->pos.p = h->last.p = h->pre_start + before; + h->end = h->last.p + size; + h->post_end = h->end + after; + + h->type = NGX_HUNK_TEMP; + h->tag = 0; + h->fd = (ngx_file_t) -1; + + return h; +} + +ngx_hunk_t *ngx_get_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size) +{ + ngx_hunk_t *h = ngx_palloc(pool, sizeof(ngx_hunk_t)); + +#ifndef OFF_EQUAL_PTR + h->pos.f = h->last.f = 0; +#endif + + if (hunk->type & NGX_HUNK_TEMP && hunk->pos.p - hunk->pre_start >= size) { + /* keep hunk->start unchanged - used in restore */ + h->pre_start = hunk->pre_start; + h->end = h->post_end = hunk->pre_start = hunk->pos.p; + h->start = h->pos.p = h->last.p = h->end - size; + + h->type = NGX_HUNK_TEMP; + h->tag = 0; + h->fd = (ngx_file_t) -1; + + } else { + h->pre_start = h->start = h->pos.p = h->last.p = ngx_palloc(pool, size); + h->end = h->post_end = h->start + size; + + h->type = NGX_HUNK_TEMP; + h->tag = 0; + h->fd = (ngx_file_t) -1; + } + + return h; +} + +ngx_hunk_t *ngx_get_hunk_after(ngx_pool_t *pool, ngx_hunk_t *hunk, int size) +{ + ngx_hunk_t *h = ngx_palloc(pool, sizeof(ngx_hunk_t)); + +#ifndef OFF_EQUAL_PTR + h->pos.f = h->last.f = 0; +#endif + + if (hunk->type & NGX_HUNK_TEMP + && hunk->last.p == hunk->end + && hunk->post_end - hunk->end >= size) + { + h->post_end = hunk->post_end; + h->pre_start = h->start = h->pos.p = h->last.p = hunk->post_end = + hunk->last.p; + h->type = NGX_HUNK_TEMP; + h->tag = 0; + h->fd = (ngx_file_t) -1; + + } else { + h->pre_start = h->start = h->pos.p = h->last.p = ngx_palloc(pool, size); + h->end = h->post_end = h->start + size; + + h->type = NGX_HUNK_TEMP; + h->tag = 0; + h->fd = (ngx_file_t) -1; + } + + return h; +} diff --git a/src/core/ngx_hunk.h b/src/core/ngx_hunk.h new file mode 100644 index 000000000..e4238b4f5 --- /dev/null +++ b/src/core/ngx_hunk.h @@ -0,0 +1,57 @@ +#ifndef _NGX_CHUNK_H_INCLUDED_ +#define _NGX_CHUNK_H_INCLUDED_ + + +#include <ngx_config.h> +#include <ngx_types.h> +#include <ngx_alloc.h> + + +/* type */ +#define NGX_HUNK_TEMP 0x0001 +#define NGX_HUNK_MEMORY 0x0002 +#define NGX_HUNK_MMAP 0x0004 +#define NGX_HUNK_FILE 0x0008 +#define NGX_HUNK_FLUSH 0x0010 +/* in thread state flush means to write the hunk completely before return + in event-driven state flush means to start to write the hunk */ +#define NGX_HUNK_LAST 0x0020 + +#define NGX_HUNK_IN_MEMORY (NGX_HUNK_TEMP | NGX_HUNK_MEMORY | NGX_HUNK_MMAP ) +#define NGX_HUNK_TYPE 0x0ffff + +/* flags */ +#define NGX_HUNK_SHUTDOWN 0x10000 +/* can be used with NGX_HUNK_LAST only */ + + +typedef struct ngx_hunk_s ngx_hunk_t; +struct ngx_hunk_s { + union { + char *p; /* start of current data */ + off_t f; + } pos; + union { + char *p; /* end of current data */ + off_t f; + } last; + int type; + char *start; /* start of hunk */ + char *end; /* end of hunk */ + char *pre_start; /* start of pre-allocated hunk */ + char *post_end; /* end of post-allocated hunk */ + int tag; + ngx_file_t fd; +}; + +typedef struct ngx_chain_s ngx_chain_t; +struct ngx_chain_s { + ngx_hunk_t *hunk; + ngx_chain_t *next; +}; + + +ngx_hunk_t *ngx_get_hunk(ngx_pool_t *pool, int size, int before, int after); + + +#endif /* _NGX_CHUNK_H_INCLUDED_ */ diff --git a/src/core/ngx_listen.c b/src/core/ngx_listen.c new file mode 100644 index 000000000..873b18de0 --- /dev/null +++ b/src/core/ngx_listen.c @@ -0,0 +1,44 @@ + +#include <ngx_config.h> +#include <ngx_types.h> +#include <ngx_errno.h> +#include <ngx_log.h> +#include <ngx_listen.h> + +ngx_socket_t ngx_listen(struct sockaddr *addr, int backlog, + ngx_log_t *log, char *addr_text) +{ + ngx_socket_t s; + int reuseaddr = 1; +#if (WIN32) + unsigned long nb = 1; +#endif + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, "socket failed"); + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + (const void *) &reuseaddr, sizeof(int)) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "ngx_listen: setsockopt (SO_REUSEADDR) failed"); + +#if (WIN32) + if (ioctlsocket(s, FIONBIO, &nb) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "ngx_listen: ioctlsocket (FIONBIO) failed"); +#else + if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "ngx_listen: fcntl (O_NONBLOCK) failed"); +#endif + + if (bind(s, (struct sockaddr *) addr, sizeof(struct sockaddr_in)) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "ngx_listen: bind to %s failed", addr_text); + + if (listen(s, backlog) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "ngx_listen: listen to %s failed", addr_text); + + return s; +} diff --git a/src/core/ngx_listen.h b/src/core/ngx_listen.h new file mode 100644 index 000000000..3be7162f1 --- /dev/null +++ b/src/core/ngx_listen.h @@ -0,0 +1,9 @@ +#ifndef _NGX_LISTEN_H_INCLUDED_ +#define _NGX_LISTEN_H_INCLUDED_ + + +ngx_socket_t ngx_listen(struct sockaddr *addr, int backlog, + ngx_log_t *log, char *addr_text); + + +#endif /* _NGX_LISTEN_H_INCLUDED_ */ diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c new file mode 100644 index 000000000..6fb02db2f --- /dev/null +++ b/src/core/ngx_log.c @@ -0,0 +1,116 @@ + +/* + TODO: log pid and tid +*/ + +/* + "[time as ctime()] [alert] 412:3 (32)Broken pipe: anything" + + "[time as ctime()] [alert] (32)Broken pipe: anything" + "[time as ctime()] [alert] anything" +*/ + +#include <ngx_config.h> +#include <ngx_errno.h> +#include <ngx_time.h> +#include <ngx_string.h> +#include <ngx_log.h> + + +static const char *err_levels[] = { + "emerg", "alert", "crit", "error", "warn", "notice", "info", "debug" +}; + +#if (HAVE_VARIADIC_MACROS) +void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err, + const char *fmt, ...) +#else +void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err, + const char *fmt, va_list args) +#endif +{ + char errstr[MAX_ERROR_STR]; + ngx_tm_t tm; + size_t len; +#if (HAVE_VARIADIC_MACROS) + va_list args; +#endif + + ngx_localtime(&tm); + len = ngx_snprintf(errstr, sizeof(errstr), "%02d:%02d:%02d", + tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); + + if (err) { + if ((unsigned) err < 0x80000000) + len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, + " [%s] (%d)", + err_levels[level], err); + len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, + " [%s] (%X)", + err_levels[level], err); + + len += ngx_strerror_r(err, errstr + len, sizeof(errstr) - len - 1); + if (len < sizeof(errstr) - 2) { + errstr[len++] = ':'; + errstr[len++] = ' '; + } else { + len = sizeof(errstr) - 2; + } + + } else { + len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1, + " [%s] ", err_levels[level]); + } + +#if (HAVE_VARIADIC_MACROS) + va_start(args, fmt); + len += ngx_vsnprintf(errstr + len, sizeof(errstr) - len - 1, fmt, args); + va_end(args); +#else + len += ngx_vsnprintf(errstr + len, sizeof(errstr) - len - 1, fmt, args); +#endif + + if (len > sizeof(errstr) - 2) + len = sizeof(errstr) - 2; + errstr[len] = '\n'; + errstr[len + 1] = '\0'; + + fputs(errstr, stderr); + + if (level == NGX_LOG_EMERG) + exit(1); +} + +#if !(HAVE_VARIADIC_MACROS) + +void ngx_log_error(int level, ngx_log_t *log, ngx_err_t err, + const char *fmt, ...) +{ + va_list args; + + if (log->log_level >= level) { + va_start(args, fmt); + ngx_log_error_core(level, log, err, fmt, args); + va_end(args); + } +} + +void ngx_log_debug_core(ngx_log_t *log, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + ngx_log_error_core(NGX_LOG_DEBUG, log, 0, fmt, args); + va_end(args); +} + +void ngx_assert_core(ngx_log_t *log, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + ngx_log_error_core(NGX_LOG_ALERT, log, 0, fmt, args); + va_end(args); +} + +#endif diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h new file mode 100644 index 000000000..54c96d364 --- /dev/null +++ b/src/core/ngx_log.h @@ -0,0 +1,118 @@ +#ifndef _NGX_LOG_H_INCLUDED_ +#define _NGX_LOG_H_INCLUDED_ + + +#include <ngx_errno.h> + +typedef enum { + NGX_LOG_EMERG = 0, + NGX_LOG_ALERT, + NGX_LOG_CRIT, + NGX_LOG_ERR, + NGX_LOG_WARN, + NGX_LOG_NOTICE, + NGX_LOG_INFO, + NGX_LOG_DEBUG +} ngx_log_e; + +/* + "... while ", action = "reading client request headers" + "... while reading client request headers" + "... while ", action = "reading client request headers" + context: pop3 user account + "... while reading client command for 'john_doe'" +*/ + +typedef struct { + int log_level; + char *action; + char *context; +/* char *func(ngx_log_t *log); */ +} ngx_log_t; + +#define MAX_ERROR_STR 2048 + +#define _ , + + +#if (HAVE_GCC_VARIADIC_MACROS) + +#define HAVE_VARIADIC_MACROS 1 + +#define ngx_log_error(level, log, args...) \ + if (log->log_level >= level) ngx_log_error_core(level, log, args) + +#ifdef NGX_DEBUG +#define ngx_log_debug(log, args...) \ + if (log->log_level == NGX_LOG_DEBUG) \ + ngx_log_error_core(NGX_LOG_DEBUG, log, 0, args) +#else +#define ngx_log_debug(log, args...) +#endif + +#define ngx_assert(assert, fallback, log, args...) \ + if (!(assert)) { \ + if (log->log_level >= NGX_LOG_ALERT) \ + ngx_log_error_core(NGX_LOG_ALERT, log, 0, args); \ + fallback; \ + } + +void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err, + const char *fmt, ...); + +#elif (HAVE_C99_VARIADIC_MACROS) + +#define HAVE_VARIADIC_MACROS 1 + +#define ngx_log_error(level, log, ...) \ + if (log->log_level >= level) ngx_log_error_core(level, log, __VA_ARGS__) + +#ifdef NGX_DEBUG +#define ngx_log_debug(log, ...) \ + if (log->log_level == NGX_LOG_DEBUG) \ + ngx_log_error_core(NGX_LOG_DEBUG, log, 0, __VA_ARGS__) +#else +#define ngx_log_debug(log, ...) +#endif + +#define ngx_assert(assert, fallback, log, ...) \ + if (!(assert)) { \ + if (log->log_level >= NGX_LOG_ALERT) \ + ngx_log_error_core(NGX_LOG_ALERT, log, 0, __VA_ARGS__); \ + fallback; \ + } + +void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err, + const char *fmt, ...); + +#else /* NO VARIADIC MACROS */ + +#include <stdarg.h> + +#ifdef NGX_DEBUG +#define ngx_log_debug(log, text) \ + if (log->log_level == NGX_LOG_DEBUG) \ + ngx_log_debug_core(log, text) +#else +#define ngx_log_debug(log, text) +#endif + +#define ngx_assert(assert, fallback, log, text) \ + if (!(assert)) { \ + if (log->log_level >= NGX_LOG_ALERT) \ + ngx_assert_core(log, text); \ + fallback; \ + } + +void ngx_log_error(int level, ngx_log_t *log, ngx_err_t err, + const char *fmt, ...); +void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err, + const char *fmt, va_list args); +void ngx_log_debug_core(ngx_log_t *log, const char *fmt, ...); +void ngx_assert_core(ngx_log_t *log, const char *fmt, ...); + + +#endif /* VARIADIC MACROS */ + + +#endif /* _NGX_LOG_H_INCLUDED_ */ diff --git a/src/core/ngx_server.h b/src/core/ngx_server.h new file mode 100644 index 000000000..88eb438f2 --- /dev/null +++ b/src/core/ngx_server.h @@ -0,0 +1,30 @@ +#ifndef _NGX_SERVER_H_INCLUDED_ +#define _NGX_SERVER_H_INCLUDED_ + + +#include <ngx_config.h> +#include <ngx_types.h> +#include <ngx_alloc.h> + +typedef struct { + int log_level; + ngx_pool_t *pool; + int (*handler)(void *data); + int buff_size; +} ngx_server_t; + + +typedef struct { + ngx_socket_t fd; + + ngx_log_t *log; + ngx_server_t *server; + + unsigned shared:1; +#if (HAVE_DEFERRED_ACCEPT) + unsigned accept_filter:1; +#endif +} ngx_listen_t; + + +#endif /* _NGX_SERVER_H_INCLUDED_ */ diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c new file mode 100644 index 000000000..9e32b56f5 --- /dev/null +++ b/src/core/ngx_string.c @@ -0,0 +1,21 @@ + +#include <ngx_config.h> +#include <ngx_string.h> + + +char *ngx_cpystrn(char *dst, char *src, size_t n) +{ + if (n == 0) + return dst; + + for (/* void */; --n; dst++, src++) { + *dst = *src; + + if (*dst == '\0') + return dst; + } + + *dst = '\0'; + + return dst; +} diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h new file mode 100644 index 000000000..0a78a0673 --- /dev/null +++ b/src/core/ngx_string.h @@ -0,0 +1,26 @@ +#ifndef _NGX_STRING_H_INCLUDED_ +#define _NGX_STRING_H_INCLUDED_ + + +#include <ngx_config.h> + + +#if (WIN32) + +#define ngx_snprintf _snprintf +#define ngx_vsnprintf _vsnprintf + +#else + +#define ngx_snprintf snprintf +#define ngx_vsnprintf vsnprintf + +#endif + +#define ngx_memcpy(dst, src, n) memcpy(dst, src, n) +#define ngx_cpymem(dst, src, n) memcpy(dst, src, n) + n + +char *ngx_cpystrn(char *dst, char *src, size_t n); + + +#endif /* _NGX_STRING_H_INCLUDED_ */ |