nginx-0.0.1-2003-05-06-21:03:16 import
diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c
index 45533be..a93922a 100644
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -441,21 +441,26 @@
len = value[1].len;
last = value[1].data[len - 1];
- if (last == 'K' || last == 'k') {
+ switch (last) {
+ case 'K':
+ case 'k':
len--;
scale = 1024;
+ break;
- } else if (last == 'M' || last == 'm') {
+ case 'M':
+ case 'm':
len--;
scale = 1024 * 1024;
+ break;
- } else {
+ default:
scale = 1;
}
size = ngx_atoi(value[1].data, len);
if (size == NGX_ERROR) {
- return "value must be greater or equal to zero";
+ return "invalid value";
}
size *= scale;
@@ -466,71 +471,200 @@
}
-char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
+char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
{
- int size, len, scale;
- char last;
+ int size, total, len, scale, i;
+ u_int max;
+ char last, *start;
ngx_str_t *value;
value = (ngx_str_t *) cf->args->elts;
+ start = value[1].data;
+ len = 0;
+ total = 0;
- len = value[1].len;
- last = value[1].data[len - 1];
+ for (i = 0; /* void */ ; i++) {
- if (last == 'm') {
- len--;
- scale = 1000 * 60;
+ if (i < value[1].len) {
+ if (value[1].data[i] != ' ') {
+ len++;
+ continue;
+ }
- } else if (last == 'h') {
- len--;
- scale = 1000 * 60 * 60;
+ if (value[1].data[i] == ' ' && len == 0) {
+ start = &value[1].data[i + 1];
+ continue;
+ }
+ }
- } else if (last == 'd') {
- len--;
- scale = 1000 * 60 * 60 * 24;
+ if (len == 0) {
+ break;
+ }
- } else if (last == 'w') {
- len--;
- scale = 1000 * 60 * 60 * 24 * 7;
+ last = value[1].data[i - 1];
-#if 0 /* overflow */
-
- } else if (last == 'M') {
- len--;
- scale = 1000 * 60 * 60 * 24 * 30;
-
- } else if (last == 'y') {
- len--;
- scale = 1000 * 60 * 60 * 24 * 365;
-
-#endif
-
- } else if (last == 's') {
- len--;
- if (value[1].data[len - 1] == 'm') {
+ switch (last) {
+ case 'm':
len--;
- scale = 1;
+ max = 35791;
+ scale = 1000 * 60;
+ break;
- } else {
+ case 'h':
+ len--;
+ max = 596;
+ scale = 1000 * 60 * 60;
+ break;
+
+ case 'd':
+ len--;
+ max = 24;
+ scale = 1000 * 60 * 60 * 24;
+ break;
+
+ case 's':
+ len--;
+ if (value[1].data[i - 2] == 'm') {
+ len--;
+ max = 2147483647;
+ scale = 1;
+ break;
+ }
+ /* fall thru */
+
+ default:
+ max = 2147483;
scale = 1000;
}
- } else {
- scale = 1000;
+ size = ngx_atoi(start, len);
+ if (size < 0) {
+ return "invalid value";
+ }
+
+ if ((u_int) size > max) {
+ return "value must be less than 597 hours";
+ }
+
+ total += size * scale;
+
+ if (i >= value[1].len) {
+ break;
+ }
+
+ len = 0;
+ start = &value[1].data[i + 1];
}
- size = ngx_atoi(value[1].data, len);
- if (size < 0) {
- return "value must be greater or equal to zero";
- }
-
- size *= scale;
-
- *(int *) (conf + cmd->offset) = size;
+ *(int *) (conf + cmd->offset) = total;
return NGX_CONF_OK;
}
+
+char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
+{
+ int size, total, len, scale, i;
+ u_int max;
+ char last, *start;
+ ngx_str_t *value;
+
+ value = (ngx_str_t *) cf->args->elts;
+ start = value[1].data;
+ len = 0;
+ total = 0;
+
+ for (i = 0; /* void */ ; i++) {
+
+ if (i < value[1].len) {
+ if (value[1].data[i] != ' ') {
+ len++;
+ continue;
+ }
+
+ if (value[1].data[i] == ' ' && len == 0) {
+ start = &value[1].data[i + 1];
+ continue;
+ }
+ }
+
+ if (len == 0) {
+ break;
+ }
+
+ last = value[1].data[i - 1];
+
+ switch (last) {
+ case 'm':
+ len--;
+ max = 35791394;
+ scale = 60;
+ break;
+
+ case 'h':
+ len--;
+ max = 596523;
+ scale = 60 * 60;
+ break;
+
+ case 'd':
+ len--;
+ max = 24855;
+ scale = 60 * 60 * 24;
+ break;
+
+ case 'w':
+ len--;
+ max = 3550;
+ scale = 60 * 60 * 24 * 7;
+ break;
+
+ case 'M':
+ len--;
+ max = 828;
+ scale = 60 * 60 * 24 * 30;
+ break;
+
+ case 'y':
+ len--;
+ max = 68;
+ scale = 60 * 60 * 24 * 365;
+ break;
+
+ case 's':
+ len--;
+ /* fall thru */
+
+ default:
+ max = 2147483647;
+ scale = 1;
+ }
+
+ size = ngx_atoi(start, len);
+ if (size < 0) {
+ return "invalid value";
+ }
+
+ if ((u_int) size > max) {
+ return "value must be less than 68 years";
+ }
+
+ total += size * scale;
+
+ if (i >= value[1].len) {
+ break;
+ }
+
+ len = 0;
+ start = &value[1].data[i + 1];
+ }
+
+ *(int *) (conf + cmd->offset) = total;
+
+ return NGX_CONF_OK;
+}
+
+
char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
{
return "unsupported on this platform";
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index f6c9e02..5426f59 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -100,6 +100,7 @@
char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
+char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index 3df0856..8287d56 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -87,6 +87,7 @@
#include <signal.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/socket.h>
@@ -167,10 +168,11 @@
/* FreeBSD sendfile nbytes bug */
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460100) \
- || __FreeBSD_version == 460001
+ || __FreeBSD_version == 460001 \
|| __FreeBSD_version >= 500029
#if (HAVE_FREEBSD_SENDFILE_NBYTES_BUG == 2)
+#undef HAVE_FREEBSD_SENDFILE_NBYTES_BUG
#define HAVE_FREEBSD_SENDFILE_NBYTES_BUG 0
#endif
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 1510498..56a9861 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -6,14 +6,16 @@
char *ngx_cpystrn(char *dst, char *src, size_t n)
{
- if (n == 0)
+ if (n == 0) {
return dst;
+ }
for (/* void */; --n; dst++, src++) {
*dst = *src;
- if (*dst == '\0')
+ if (*dst == '\0') {
return dst;
+ }
}
*dst = '\0';
@@ -22,10 +24,36 @@
}
+int ngx_rstrncmp(char *s1, char *s2, size_t n)
+{
+ if (n == 0) {
+ return 0;
+ }
+
+ n--;
+
+ for ( ;; ) {
+ if (s1[n] != s2[n]) {
+ return (u_char) s1[n] - (u_char) s2[n];
+ }
+
+ if (n == 0) {
+ return 0;
+ }
+
+ n--;
+ }
+}
+
+
int ngx_atoi(char *line, size_t n)
{
int value;
+ if (n == 0) {
+ return NGX_ERROR;
+ }
+
for (value = 0; n--; line++) {
if (*line < '0' || *line > '9') {
return NGX_ERROR;
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index 8566d46..e678f73 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -49,6 +49,7 @@
#define ngx_cpymem(dst, src, n) memcpy(dst, src, n) + n
char *ngx_cpystrn(char *dst, char *src, size_t n);
+int ngx_rstrncmp(char *s1, char *s2, size_t n);
int ngx_atoi(char *line, size_t n);
diff --git a/src/http/modules/proxy/ngx_http_event_proxy_handler.c b/src/http/modules/proxy/ngx_http_event_proxy_handler.c
index 9b1ddc4..cb48deb 100644
--- a/src/http/modules/proxy/ngx_http_event_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_event_proxy_handler.c
@@ -298,41 +298,36 @@
/* the request line */
- ngx_memcpy(hunk->last, http_methods[p->method - 1].data,
- http_methods[p->method - 1].len);
- hunk->last += http_methods[p->method - 1].len;
+ hunk->last = ngx_cpymem(hunk->last, http_methods[p->method - 1].data,
+ http_methods[p->method - 1].len);
- ngx_memcpy(hunk->last, p->upstream_url->uri.data, p->upstream_url->uri.len);
- hunk->last += p->upstream_url->uri.len;
+ hunk->last = ngx_cpymem(hunk->last, p->upstream_url->uri.data,
+ p->upstream_url->uri.len);
- ngx_memcpy(hunk->last, r->uri.data + p->upstream_url->location->len,
- r->uri.len - p->upstream_url->location->len);
- hunk->last += r->uri.len - p->upstream_url->location->len;
+ hunk->last = ngx_cpymem(hunk->last,
+ r->uri.data + p->upstream_url->location->len,
+ r->uri.len - p->upstream_url->location->len);
if (r->args.len > 0) {
*(hunk->last++) = '?';
- ngx_memcpy(hunk->last, r->args.data, r->args.len);
- hunk->last += r->args.len;
+ hunk->last = ngx_cpymem(hunk->last, r->args.data, r->args.len);
}
- ngx_memcpy(hunk->last, http_version, sizeof(http_version) - 1);
- hunk->last += sizeof(http_version) - 1;
+ hunk->last = ngx_cpymem(hunk->last, http_version, sizeof(http_version) - 1);
/* the "Host" header */
- ngx_memcpy(hunk->last, host_header, sizeof(host_header) - 1);
- hunk->last += sizeof(host_header) - 1;
+ hunk->last = ngx_cpymem(hunk->last, host_header, sizeof(host_header) - 1);
- ngx_memcpy(hunk->last, p->upstream_url->host.data,
- p->upstream_url->host.len);
- hunk->last += p->upstream_url->host.len;
+ hunk->last = ngx_cpymem(hunk->last, p->upstream_url->host.data,
+ p->upstream_url->host.len);
*(hunk->last++) = CR; *(hunk->last++) = LF;
/* the "Connection: close" header */
- ngx_memcpy(hunk->last, conn_close_header, sizeof(conn_close_header) - 1);
- hunk->last += sizeof(conn_close_header) - 1;
+ hunk->last = ngx_cpymem(hunk->last, conn_close_header,
+ sizeof(conn_close_header) - 1);
for (i = 0; i < r->headers_in.headers->nelts; i++) {
@@ -344,13 +339,13 @@
continue;
}
- ngx_memcpy(hunk->last, header[i].key.data, header[i].key.len);
- hunk->last += header[i].key.len;
+ hunk->last = ngx_cpymem(hunk->last, header[i].key.data,
+ header[i].key.len);
*(hunk->last++) = ':'; *(hunk->last++) = ' ';
- ngx_memcpy(hunk->last, header[i].value.data, header[i].value.len);
- hunk->last += header[i].value.len;
+ hunk->last = ngx_cpymem(hunk->last, header[i].value.data,
+ header[i].value.len);
*(hunk->last++) = CR; *(hunk->last++) = LF;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 9eab6ad..0e67f33 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -43,7 +43,7 @@
{ngx_string("post_accept_timeout"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_time_slot,
+ ngx_conf_set_msec_slot,
0,
addressof(ngx_http_post_accept_timeout)},
@@ -61,7 +61,7 @@
{ngx_string("client_header_timeout"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_time_slot,
+ ngx_conf_set_msec_slot,
0,
addressof(ngx_http_client_header_timeout)},
@@ -103,19 +103,19 @@
{ngx_string("send_timeout"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_time_slot,
+ ngx_conf_set_msec_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, send_timeout)},
{ngx_string("lingering_time"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_time_slot,
+ ngx_conf_set_msec_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, lingering_time)},
{ngx_string("lingering_timeout"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_time_slot,
+ ngx_conf_set_msec_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, lingering_timeout)},
@@ -239,7 +239,7 @@
continue;
}
- rc = ngx_strncmp(r->uri.data, plcf[i]->name.data, plcf[i]->name.len);
+ rc = ngx_rstrncmp(r->uri.data, plcf[i]->name.data, plcf[i]->name.len);
if (rc < 0) {
break;
diff --git a/src/os/unix/freebsd/ngx_rfork_thread.c b/src/os/unix/freebsd/ngx_rfork_thread.c
deleted file mode 100644
index acd5ec6..0000000
--- a/src/os/unix/freebsd/ngx_rfork_thread.c
+++ /dev/null
@@ -1,64 +0,0 @@
-
-#include <ngx_os_thread.h>
-
-char *ngx_stacks_start;
-char *ngx_stacks_end;
-size_t ngx_stack_size;
-
-
-/* handle thread-safe errno */
-static int errno0; /* errno for main thread */
-static int *errnos;
-
-int *__error()
-{
- ngx_tid_t tid = ngx_gettid();
- return tid ? &(errnos[ngx_gettid()]) : &errno0;
-}
-
-
-int ngx_create_thread(ngx_os_tid_t *tid, void *stack,
- int (*func)(void *arg), void *arg, ngx_log_t log)
-{
- int id, err;
-
- id = rfork_thread(RFPROC|RFMEM, stack, func, arg);
- err = ngx_errno;
-
- if (id == -1)
- ngx_log_error(NGX_LOG_ERR, log, err,
- "ngx_create_os_thread: rfork failed");
- else
- *tid = id;
-
- return err;
-}
-
-
-int ngx_create_thread_env(int n, size_t size, ngx_log_t log)
-{
- char *addr;
-
- /* create thread stacks */
- addr = mmap(NULL, n * size, PROT_READ|PROT_WRITE, MAP_ANON, -1, NULL);
- if (addr == MAP_FAILED) {
- ngx_log_error(NGX_LOG_ERR, log, ngx_errno,
- "ngx_create_os_thread_stacks: mmap failed");
- return -1;
- }
-
- nxg_stacks_start = addr;
- nxg_stacks_end = addr + n * size;
- nxg_stack_size = size;
-
- /* create thread errno array */
- ngx_test_null(errnos, ngx_calloc(n * sizeof(int)), -1);
-
- /* create thread tid array */
- ngx_test_null(ngx_os_tids, ngx_calloc(n * sizeof(ngx_os_tid_t)), -1);
-
- /* allow spinlock in malloc() */
- __isthreaded = 1;
-
- return 0;
-}
diff --git a/src/os/unix/freebsd/ngx_rfork_thread.h b/src/os/unix/freebsd/ngx_rfork_thread.h
deleted file mode 100644
index 2ab114e..0000000
--- a/src/os/unix/freebsd/ngx_rfork_thread.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _NGX_OS_THREAD_H_INCLUDED_
-#define _NGX_OS_THREAD_H_INCLUDED_
-
-
-typedef int ngx_os_tid_t;
-typedef int ngx_tid_t;
-
-
-extern char *ngx_stacks_start;
-extern char *ngx_stacks_end;
-extern size_t ngx_stack_size;
-
-
-static inline ngx_tid_t ngx_gettid()
-{
- char *sp;
-
- __asm__ ("mov %%esp,%0" : "=r" (sp));
-
- return (sp > ngx_stacks_end) ? 0:
- (sp - ngx_stacks_start) / ngx_stack_size + 1;
-}
-
-
-#endif /* _NGX_OS_THREAD_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c
new file mode 100644
index 0000000..d74b7ba
--- /dev/null
+++ b/src/os/unix/ngx_freebsd_rfork_thread.c
@@ -0,0 +1,158 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_process.h>
+#include <ngx_log.h>
+#include <ngx_alloc.h>
+
+
+extern int __isthreaded;
+
+
+typedef int ngx_tid_t;
+
+
+static inline int ngx_gettid();
+
+
+static char *stacks_start;
+static char *stacks_end;
+static size_t stack_size;
+static char *last_stack;
+static int last_thread;
+
+static ngx_log_t *log;
+
+static ngx_tid_t *tids;
+
+static int red_zone = 4096;
+
+
+/* the thread-safe errno */
+
+static int errno0; /* the main thread's errno */
+static int *errnos;
+
+int *__error()
+{
+ int tid;
+
+ tid = ngx_gettid();
+ return tid ? &errnos[tid] : &errno0;
+}
+
+
+int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg)
+{
+ int id, err;
+ char *stack_top;
+
+ last_stack += stack_size;
+ stack_top = last_stack - red_zone;
+
+ if (stack_top > stacks_end) {
+ ngx_log_error(NGX_LOG_CRIT, log, 0, "no more threads allocated");
+ return NGX_ERROR;
+ }
+
+#if 0
+ id = rfork_thread(RFPROC|RFMEM|RFFDG|RFCFDG, stack_top, func, arg);
+#elif 1
+ id = rfork_thread(RFPROC|RFMEM, stack_top, func, arg);
+#else
+ id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg);
+#endif
+ err = errno;
+
+ if (id == -1) {
+ ngx_log_error(NGX_LOG_ALERT, log, err, "rfork() failed");
+
+ } else {
+ *tid = id;
+ tids[last_thread++] = id;
+
+ /* allow the spinlock in libc malloc() */
+ __isthreaded = 1;
+ }
+
+ return err;
+}
+
+
+int ngx_init_thread_env(int n, size_t size, ngx_log_t *lg)
+{
+ int len, i;
+ char *usrstack, *zone;
+
+ log = lg;
+
+ /* create the thread stacks */
+
+ len = 4;
+ if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, log, errno,
+ "sysctlbyname(kern.usrstack) failed");
+ return NGX_ERROR;
+ }
+
+printf("usrstack: %08X\n", usrstack);
+printf("red zone: %08X\n", usrstack - (size + red_zone));
+
+#if 1
+ /* red zone */
+ zone = mmap(usrstack - (size + red_zone), red_zone,
+ PROT_NONE, MAP_ANON, -1, 0);
+ if (zone == MAP_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, log, errno,
+ "mmap(%d, PROT_NONE, MAP_ANON) failed", red_zone);
+ return NGX_ERROR;
+ }
+#else
+ zone = usrstack - (size + red_zone);
+#endif
+
+ last_stack = zone + red_zone;
+
+ for (i = 0; i < n; i++) {
+ last_stack -= size + red_zone;
+printf("stack: %08X\n", last_stack);
+ last_stack = mmap(last_stack, size, PROT_READ|PROT_WRITE,
+ MAP_STACK, -1, 0);
+ if (last_stack == MAP_FAILED) {
+ ngx_log_error(NGX_LOG_ALERT, log, errno,
+ "mmap(%d, MAP_STACK) failed", size);
+ return NGX_ERROR;
+ }
+ }
+
+ stacks_start = last_stack;
+ stack_size = size + red_zone;
+ stacks_end = stacks_start + n * stack_size;
+
+ /* create the thread errno array */
+ ngx_test_null(errnos, ngx_calloc(n * sizeof(int), log), NGX_ERROR);
+
+ /* create the thread tid array */
+ ngx_test_null(tids, ngx_calloc(n * sizeof(ngx_tid_t), log), NGX_ERROR);
+
+ tids[0] = ngx_getpid();
+ last_thread = 1;
+
+ return NGX_OK;
+}
+
+
+ngx_tid_t ngx_thread_self()
+{
+ return tids[ngx_gettid()];
+}
+
+
+static inline int ngx_gettid()
+{
+ char *sp;
+
+ __asm__ ("mov %%esp, %0" : "=q" (sp));
+
+ return (sp > stacks_end) ? 0: ((sp - stacks_start) / stack_size + 1);
+}