# HG changeset patch # User Igor Sysoev # Date 1076312803 0 # Node ID b6793bc5034b87791494ccd29d1d0b13cf29a6cd # Parent 84b1c672ec5aba5943877d1fd31391c6b48ddd63 nginx-0.0.2-2004-02-09-10:46:43 import diff --git a/auto/configure b/auto/configure --- a/auto/configure +++ b/auto/configure @@ -3,8 +3,13 @@ . auto/init . auto/sources +test $OBJ || mkdir $OBJ echo > $NGX_AUTO_CONFIG_H +if [ "$PLATFORM" != win32 ]; then + . auto/headers +fi + . auto/os/conf . auto/modules diff --git a/auto/fmt/xfmt b/auto/fmt/xfmt --- a/auto/fmt/xfmt +++ b/auto/fmt/xfmt @@ -1,6 +1,8 @@ -echo "#ifndef $ngx_fmt_name" >> $NGX_AUTO_CONFIG_H -echo "#define $ngx_fmt_name \"$ngx_fmt\"" | sed -e 's/d"$/x"/' \ - >> $NGX_AUTO_CONFIG_H -echo "#endif" >> $NGX_AUTO_CONFIG_H -echo >> $NGX_AUTO_CONFIG_H +cat << END | sed -e 's/d"$/x"/' >> $NGX_AUTO_CONFIG_H + +#ifndef $ngx_fmt_name +#define $ngx_fmt_name "$ngx_fmt" +#endif + +END diff --git a/auto/func b/auto/func --- a/auto/func +++ b/auto/func @@ -24,15 +24,7 @@ eval "$CC $CC_TEST_FLAGS -o $NGX_AUTOTES if [ -x $NGX_AUTOTEST ]; then echo " found" - - cat << END >> $NGX_AUTO_CONFIG_H - -#ifndef HAVE_$func -#define HAVE_$func 1 -#endif - -END - + have=HAVE_$func . auto/have ngx_found=yes else diff --git a/auto/headers b/auto/headers new file mode 100644 --- /dev/null +++ b/auto/headers @@ -0,0 +1,3 @@ + +ngx_inc="unistd.h"; . auto/inc +ngx_inc="inttypes.h"; . auto/inc diff --git a/auto/inc b/auto/inc --- a/auto/inc +++ b/auto/inc @@ -21,15 +21,7 @@ eval "${CC} -o $NGX_AUTOTEST $NGX_AUTOTE if [ -x $NGX_AUTOTEST ]; then echo " found" - - cat << END >> $NGX_AUTO_CONFIG_H - -#ifndef HAVE_$inc -#define HAVE_$inc 1 -#endif - -END - + have=HAVE_$inc . auto/have eval "NGX_$inc='#include <$ngx_inc>'" ngx_found=yes diff --git a/auto/lib/md5/conf b/auto/lib/md5/conf --- a/auto/lib/md5/conf +++ b/auto/lib/md5/conf @@ -1,5 +1,5 @@ -if [ $MD5 != NO ]; then +if [ $MD5 != NONE ]; then if grep MD5_Init $MD5/md5.h >/dev/null; then # OpenSSL md5 @@ -25,6 +25,8 @@ else ngx_lib_inc="#include #include " + MD5=NO + # Solaris 8/9 ngx_lib="rsaref md5" ngx_lib_test="MD5_CTX md5; MD5Init(&md5)" diff --git a/auto/lib/zlib/conf b/auto/lib/zlib/conf --- a/auto/lib/zlib/conf +++ b/auto/lib/zlib/conf @@ -1,5 +1,5 @@ -if [ $ZLIB != NO ]; then +if [ $ZLIB != NONE ]; then CORE_INCS="$CORE_INCS -I $ZLIB" if [ "$PLATFORM" = "win32" ]; then @@ -23,6 +23,8 @@ else if [ $ngx_found = yes ]; then CORE_LIBS="$CORE_LIBS $ngx_libs" ZLIB=YES + else + ZLIB=NO fi fi diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -22,12 +22,10 @@ HTTP_PROXY=YES PCRE=NO USE_MD5=NO -MD5=NO -MD5_LIB=NO +MD5=NONE USE_ZLIB=NO -ZLIB=NO -ZLIB_LIB=NO +ZLIB=NONE for option diff --git a/auto/os/freebsd b/auto/os/freebsd --- a/auto/os/freebsd +++ b/auto/os/freebsd @@ -1,11 +1,8 @@ - CORE_INCS="$UNIX_INCS" CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS" CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS" -MD5_LIB="-lmd" -ZLIB_LIB="-lz" version=`grep "#define __FreeBSD_version" /usr/include/osreldate.h \ | sed -e 's/^.* \(.*\)$/\1/'` diff --git a/auto/os/linux b/auto/os/linux --- a/auto/os/linux +++ b/auto/os/linux @@ -4,7 +4,6 @@ CORE_DEPS="$UNIX_DEPS $LINUX_DEPS" CORE_SRCS="$UNIX_SRCS $LINUX_SRCS" EVENT_MODULES="$EVENT_MODULES" -ZLIB_LIB="-lz" CC_TEST_FLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" @@ -13,7 +12,7 @@ CC_TEST_FLAGS="-D_GNU_SOURCE -D_FILE_OFF ngx_func="epoll"; ngx_func_inc="#include " -ngx_func_test="int fd = 1; int n; +ngx_func_test="int efd = 0, fd = 1, n; struct epoll_event ee; ee.events = EPOLLIN|EPOLLOUT|EPOLLET; ee.data.ptr = NULL; @@ -21,7 +20,7 @@ ngx_func_test="int fd = 1; int n; . auto/func if [ $ngx_found = yes ]; then - CFLAGS="$CFLAGS -D HAVE_EPOLL=1" + have=HAVE_EPOLL . auto/have CORE_SRCS="$CORE_SRCS $EPOLL_SRCS" EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE" EVENT_FOUND=YES @@ -39,7 +38,6 @@ ngx_func_test="int s = 0, fd = 1; . auto/func if [ $ngx_found = yes ]; then - CFLAGS="$CFLAGS -D HAVE_SENDFILE=1" CORE_SRCS="$CORE_SRCS $LINUX_SENDFILE_SRCS" fi @@ -49,6 +47,14 @@ fi CC_TEST_FLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" ngx_func="sendfile64()"; . auto/func + +# prctl(PR_SET_DUMPABLE) + +ngx_func="prctl()"; +ngx_func_inc="#include " +ngx_func_test="prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)" +. auto/func + if [ $ngx_found = yes ]; then - CFLAGS="$CFLAGS -D HAVE_SENDFILE64=1" + have=HAVE_PR_SET_DUMPABLE . auto/have fi diff --git a/auto/os/solaris b/auto/os/solaris --- a/auto/os/solaris +++ b/auto/os/solaris @@ -4,17 +4,16 @@ CORE_DEPS="$UNIX_DEPS $SOLARIS_DEPS" CORE_SRCS="$UNIX_SRCS $SOLARIS_SRCS " EVENT_MODULES="$EVENT_MODULES" -MD5_LIB="-lmd5" -ZLIB_LIB="-lz" CORE_LIBS="$CORE_LIBS -lsocket -lnsl" + CC_TEST_FLAGS="-D_FILE_OFFSET_BITS=64" ngx_inc="sys/devpoll.h"; . auto/inc if [ $ngx_found = yes ]; then - CFLAGS="$CFLAGS -D HAVE_DEVPOLL=1" + have=HAVE_DEVPOLL . auto/have CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS" EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE" EVENT_FOUND=YES @@ -25,13 +24,13 @@ ngx_func="sendfilev()"; ngx_func_inc="#include " ngx_func_libs="-lsendfile" ngx_func_test="int fd = 1; sendfilevec_t vec[1]; - size_t sent = 1; ssize_t n; + size_t sent; ssize_t n; n = sendfilev(fd, vec, 1, &sent)" . auto/func if [ $ngx_found = yes ]; then - CFLAGS="$CFLAGS -D HAVE_SENDFILE=1" + have=HAVE_SENDFILE . auto/have CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS" CORE_LIBS="$CORE_LIBS -lsendfile" fi diff --git a/auto/summary b/auto/summary --- a/auto/summary +++ b/auto/summary @@ -3,21 +3,24 @@ echo echo "Configuration summary" case $PCRE in - YES) echo " + using system PCRE library" ;; - NO) echo " + PCRE library is not found" ;; - *) echo " + using PCRE library: $PCRE" ;; + YES) echo " + using system PCRE library" ;; + NONE) echo " + PCRE library is not used" ;; + NO) echo " + PCRE library is not found" ;; + *) echo " + using PCRE library: $PCRE" ;; esac case $MD5 in - YES) echo " + using system md5 library" ;; - NO) echo " + md5 library is not found" ;; - *) echo " + using md5 library: $MD5" ;; + YES) echo " + using system md5 library" ;; + NONE) echo " + md5 library is not used" ;; + NO) echo " + md5 library is not found" ;; + *) echo " + using md5 library: $MD5" ;; esac case $ZLIB in - YES) echo " + using system zlib library" ;; - NO) echo " + zlib library is not found" ;; - *) echo " + using zlib library: $ZLIB" ;; + YES) echo " + using system zlib library" ;; + NONE) echo " + zlib library is not used" ;; + NO) echo " + zlib library is not found" ;; + *) echo " + using zlib library: $ZLIB" ;; esac echo diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -16,12 +16,7 @@ ngx_formats="%lld %qd"; . auto/fmt/fmt ngx_type="void *"; . auto/types/sizeof; ngx_ptr_bytes=$ngx_bytes -# headers - -ngx_inc="unistd.h"; . auto/inc -ngx_inc="inttypes.h"; . auto/inc - -#POSIX types +# POSIX types NGX_AUTO_CONFIG="#include \"../$NGX_AUTO_CONFIG_H\"" @@ -43,6 +38,15 @@ ngx_types="int"; . auto/types/typedef . auto/types/uintptr_t +ngx_func="sin_len" +ngx_func_inc="#include +#include +#include " + +ngx_func_test="struct sockaddr_in sa; sa.sin_len = 5" +. auto/func + + # printf() formats CC_WARN=$CC_STRONG @@ -70,19 +74,15 @@ eval ngx_formats=\${ngx_${ngx_bytes}_fmt ngx_func="pread()" ngx_func_inc= -ngx_func_test=" -char buf[1]; -ssize_t n; -n = pread(0, buf, 1, 0)" +ngx_func_test="char buf[1]; ssize_t n; + n = pread(0, buf, 1, 0)" . auto/func ngx_func="pwrite()" ngx_func_inc= -ngx_func_test=" -char buf[1]; -ssize_t n; -n = pwrite(1, buf, 1, 0)" +ngx_func_test="char buf[1]; ssize_t n; + n = pwrite(1, buf, 1, 0)" . auto/func @@ -94,7 +94,7 @@ n = pwrite(1, buf, 1, 0)" ngx_func="strerror_r()" ngx_func_inc="#include " -ngx_func_test="char buf[20]; strerror_r(1, buf, 20)" +ngx_func_test="char buf[20]; int n; n = strerror_r(1, buf, 20)" . auto/func diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -377,8 +377,11 @@ static void ngx_master_process_cycle(ngx ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "can not respawn %s", ngx_processes[i].name); + continue; } + live = 1; + continue; } @@ -443,7 +446,7 @@ static void ngx_master_process_cycle(ngx if (ngx_reopen) { if (ngx_process == NGX_PROCESS_MASTER) { - if (ccf->worker_reopen > 0) { + if (ccf->worker_reopen != 0) { signo = ngx_signal_value(NGX_REOPEN_SIGNAL); ngx_reopen = 0; @@ -461,7 +464,7 @@ static void ngx_master_process_cycle(ngx ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reopening logs"); ngx_reopen_files(cycle, - ccf->worker_reopen > 0 ? ccf->user : -1); + ccf->worker_reopen != 0 ? ccf->user : (uid_t) -1); } } @@ -574,6 +577,17 @@ static void ngx_worker_process_cycle(ngx } } +#if (HAVE_PR_SET_DUMPABLE) + + /* allow coredump after setuid() in Linux 2.4.x */ + + if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "prctl(PR_SET_DUMPABLE) failed"); + } + +#endif + sigemptyset(&set); if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) { diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -2,7 +2,7 @@ #define _NGX_CONFIG_H_INCLUDED_ -#if 1 +#if 0 /* STUB to allocate a big ngx_connections */ #undef FD_SETSIZE #define FD_SETSIZE 5000 diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -48,11 +48,6 @@ ngx_int_t ngx_set_inherited_sockets(ngx_ return NGX_ERROR; } -/* STUB: autoconf & set sin_len in ls[i].sockaddr in ngx_http.c */ -#if __FreeBSD__ - addr_in->sin_len = 0; -#endif - ls[i].family = addr_in->sin_family; ls[i].addr_text.len = ngx_sock_ntop(ls[i].family, ls[i].sockaddr, ls[i].addr_text.data, @@ -68,11 +63,11 @@ ngx_int_t ngx_set_inherited_sockets(ngx_ ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle) { - int tries, failed, reuseaddr, i; - ngx_err_t err; - ngx_log_t *log; - ngx_socket_t s; - ngx_listening_t *ls; + ngx_int_t tries, failed, reuseaddr, i; + ngx_err_t err; + ngx_log_t *log; + ngx_socket_t s; + ngx_listening_t *ls; reuseaddr = 1; #if (NGX_SUPPRESS_WARN) @@ -241,3 +236,39 @@ void ngx_close_listening_sockets(ngx_cyc cycle->connections[fd].fd = -1; } } + + +ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text) +{ + ngx_int_t level; + + if (err == NGX_ECONNRESET + && c->read->log_error == NGX_ERROR_IGNORE_ECONNRESET) + { + return 0; + } + + if (err == NGX_ECONNRESET || err == NGX_EPIPE || err == NGX_ENOTCONN) { + + switch (c->read->log_error) { + + case NGX_ERROR_INFO: + level = NGX_LOG_INFO; + break; + + case NGX_ERROR_ERR: + level = NGX_LOG_ERR; + break; + + default: + level = NGX_LOG_CRIT; + } + + } else { + level = NGX_LOG_CRIT; + } + + ngx_log_error(level, c->log, err, text); + + return NGX_ERROR; +} diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -96,6 +96,7 @@ struct ngx_connection_s { ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle); ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle); void ngx_close_listening_sockets(ngx_cycle_t *cycle); +ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text); extern ngx_os_io_t ngx_io; diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c --- a/src/event/modules/ngx_epoll_module.c +++ b/src/event/modules/ngx_epoll_module.c @@ -202,11 +202,11 @@ static int ngx_epoll_add_event(ngx_event } #endif - ee.events = event; + ee.events = event|EPOLLET; ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "epoll add event: fd:%d ev:%04X", c->fd, ee.events); + "epoll add event: fd:%d ev:%08X", c->fd, ee.events); if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee) == -1) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, @@ -230,8 +230,8 @@ static int ngx_epoll_del_event(ngx_event ee.events = 0; ee.data.ptr = NULL; - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "epoll del event: fd:%d ev:%04X", c->fd, ee.events); + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "epoll del event: fd:%d", c->fd); if (epoll_ctl(ep, EPOLL_CTL_DEL, c->fd, &ee) == -1) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, @@ -249,11 +249,11 @@ static int ngx_epoll_add_connection(ngx_ { struct epoll_event ee; - ee.events = EPOLLIN|EPOLLOUT; + ee.events = EPOLLIN|EPOLLOUT|EPOLLET; ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "epoll add connection: fd:%d ev:%04X", c->fd, ee.events); + "epoll add connection: fd:%d ev:%08X", c->fd, ee.events); if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee) == -1) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, @@ -355,9 +355,9 @@ int ngx_epoll_process_events(ngx_log_t * } if (event_list[i].events & (EPOLLERR|EPOLLHUP)) { - ngx_log_error(NGX_LOG_ALERT, log, 0, - "epoll_wait() error on fd:%d ev:%d", - c->fd, event_list[i].events); + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "epoll_wait() error on fd:%d ev:%04X", + c->fd, event_list[i].events); } if (event_list[i].events & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) { diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c --- a/src/event/modules/ngx_poll_module.c +++ b/src/event/modules/ngx_poll_module.c @@ -286,7 +286,8 @@ static int ngx_poll_process_events(ngx_l delta = ngx_elapsed_msec; ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "poll ready %d", ready); + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, + "poll ready %d of %d", ready, nevents); if (err) { ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -459,6 +459,12 @@ static char *ngx_event_init_conf(ngx_cyc ngx_conf_init_value(ecf->use, ngx_devpoll_module.ctx_index); ngx_conf_init_ptr_value(ecf->name, ngx_devpoll_module_ctx.name->data); +#elif (HAVE_EPOLL) + + ngx_conf_init_value(ecf->connections, DEFAULT_CONNECTIONS); + ngx_conf_init_value(ecf->use, ngx_epoll_module.ctx_index); + ngx_conf_init_ptr_value(ecf->name, ngx_epoll_module_ctx.name->data); + #else /* HAVE_SELECT */ ngx_conf_init_value(ecf->connections, diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -145,7 +145,7 @@ void ngx_event_accept(ngx_event_t *ev) } } else { - if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) { + if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) { if (ngx_nonblocking(s) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, ngx_nonblocking_n " failed"); diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -87,8 +87,8 @@ static ngx_int_t ngx_http_static_handler } /* - * there is a valid cached open file, i.e by index handler, - * and it must be already registered in r->cleanup + * there is a valid cached open file, i.e by the index handler, + * and it should be already registered in r->cleanup */ if (r->cache && !r->cache->expired) { @@ -100,13 +100,14 @@ static ngx_int_t ngx_http_static_handler clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); /* - * make a file name - * 2 bytes is for a trailing '/' in a possible redirect and for '\0' + * make a file name, reserve 2 bytes for a trailing '/' + * in a possible redirect and for the last '\0' */ - ngx_test_null(name.data, - ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2), - NGX_HTTP_INTERNAL_SERVER_ERROR); + name.data = ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2); + if (name.data == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } location.data = ngx_cpymem(name.data, clcf->doc_root.data, clcf->doc_root.len); diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -483,6 +483,9 @@ static char *ngx_http_block(ngx_conf_t * ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)), NGX_CONF_ERROR); +#if (HAVE_SIN_LEN) + addr_in->sin_len = sizeof(struct sockaddr_in); +#endif addr_in->sin_family = AF_INET; addr_in->sin_addr.s_addr = in_addr[a].addr; addr_in->sin_port = htons((u_short) in_port[p].port); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1217,10 +1217,10 @@ static char *ngx_http_core_merge_loc_con prev->default_type, "text/plain"); ngx_conf_merge_msec_value(conf->client_body_timeout, - prev->client_body_timeout, 10000); + prev->client_body_timeout, 60000); ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0); ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0); - ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 10000); + ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000); ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0); ngx_conf_merge_size_value(conf->discarded_buffer_size, prev->discarded_buffer_size, 1500); diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -84,6 +84,8 @@ void ngx_http_init_connection(ngx_connec rev->event_handler = ngx_http_init_request; rev->log_error = NGX_ERROR_INFO; + /* STUB: epoll */ c->write->event_handler = ngx_http_empty_handler; + if (rev->ready) { /* deferred accept, aio, iocp, epoll */ ngx_http_init_request(rev); @@ -160,7 +162,7 @@ static void ngx_http_init_request(ngx_ev if (in_port->addrs.nelts > 1) { /* - * There're the several addresses on this port and one of them + * There are the several addresses on this port and one of them * is "*:port" so getsockname() is needed to determine * the server address. * AcceptEx() already gave this address. @@ -215,8 +217,8 @@ static void ngx_http_init_request(ngx_ev c->log->log_level = clcf->err_log->log_level; if (c->buffer == NULL) { - c->buffer = - ngx_create_temp_hunk(c->pool, cscf->client_header_buffer_size); + c->buffer = ngx_create_temp_hunk(c->pool, + cscf->client_header_buffer_size); if (c->buffer == NULL) { ngx_http_close_connection(c); return; @@ -918,7 +920,7 @@ void ngx_http_finalize_request(ngx_http_ #if (NGX_KQUEUE) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, r->connection->read->kq_errno, - "kevent reported about closed connection by client"); + "kevent() reported about an closed connection"); #endif ngx_http_close_request(r, 0); ngx_http_close_connection(r->connection); diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -115,8 +115,8 @@ int ngx_os_init(ngx_log_t *log) /* * The determination of the sendfile() nbytes bug is complex enough. - * There are two sendfile() syscalls: a new 393 has no bug while - * an old 336 has the bug in some versions and has not in others. + * There are two sendfile() syscalls: a new #393 has no bug while + * an old #336 has the bug in some versions and has not in others. * Besides libc_r wrapper also emulates the bug in some versions. * There's no way to say exactly if a given FreeBSD version has the bug. * Here is the algorithm that works at least for RELEASEs diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -5,17 +5,20 @@ /* - * FreeBSD's sendfile() often sends 4K pages over ethernet in 3 packets: 2x1460 - * and 1176 or in 6 packets: 5x1460 and 892. Besides although sendfile() - * allows to pass the header and the trailer it never sends the header or - * the trailer with the part of the file in one packet. So we use TCP_NOPUSH - * (similar to Linux's TCP_CORK) to postpone the sending - it not only sends - * the header and the first part of the file in one packet but also sends - * 4K pages in the full packets. + * Although FreeBSD sendfile() allows to pass a header and a trailer + * it never sends a header with a part of the file in one packet until + * FreeBSD 5.2-STABLE. Besides over the fast ethernet connection sendfile() + * can send the partially filled packets, i.e. the 8 file pages can be sent + * as 11 full 1460-bytes packets, then one incomplete 324-bytes packet, and + * then again 11 full 1460-bytes packets. * - * Until FreeBSD 4.5 the turning TCP_NOPUSH off does not flush a pending + * So we use the TCP_NOPUSH option (similar to Linux's TCP_CORK) + * to postpone the sending - it not only sends a header and the first part + * of the file in one packet but also sends file pages in the full packets. + * + * But until FreeBSD 4.5 the turning TCP_NOPUSH off does not flush a pending * data that less than MSS so that data can be sent with 5 second delay. - * We do not use TCP_NOPUSH on FreeBSD prior to 4.5 although it can be used + * So we do not use TCP_NOPUSH on FreeBSD prior to 4.5 although it can be used * for non-keepalive HTTP connections. */ @@ -26,7 +29,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( char *prev; off_t sent, fprev; size_t hsize, fsize, size; - ngx_int_t eintr, eagain, level; + ngx_int_t eintr, eagain; struct iovec *iov; struct sf_hdtr hdtr; ngx_err_t err; @@ -45,7 +48,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) && wev->kq_eof) { ngx_log_error(NGX_LOG_INFO, c->log, wev->kq_errno, - "kevent() reported about closed connection"); + "kevent() reported about an closed connection"); wev->error = 1; return NGX_CHAIN_ERROR; @@ -59,7 +62,6 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( hsize = 0; eintr = 0; eagain = 0; - level = NGX_LOG_CRIT; ngx_init_array(header, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); @@ -152,14 +154,26 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( if (file) { if (ngx_freebsd_use_tcp_nopush && c->tcp_nopush == 0) { - c->tcp_nopush = 1; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "tcp_nopush"); if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { - ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, - ngx_tcp_nopush_n " failed"); - return NGX_CHAIN_ERROR; + err = ngx_errno; + + /* + * there is a tiny chance to be interrupted, however + * we continue a processing without the TCP_NOPUSH + */ + + if (err != NGX_EINTR) { + wev->error = 1; + ngx_connection_error(c, err, + ngx_tcp_nopush_n " failed"); + return NGX_CHAIN_ERROR; + } + + } else { + c->tcp_nopush = 1; + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "tcp_nopush"); } } @@ -185,30 +199,21 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( if (rc == -1) { err = ngx_errno; - if (err == NGX_EINTR) { - eintr = 1; - - } else if (err == NGX_EAGAIN) { - eagain = 1; + if (err == NGX_EAGAIN || err == NGX_EINTR) { + if (err == NGX_EINTR) { + eintr = 1; - } else if (err == NGX_EPIPE || err == NGX_ENOTCONN) { - level = NGX_LOG_INFO; - } + } else { + eagain = 1; + } - if (err == NGX_EAGAIN || err == NGX_EINTR) { ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, "sendfile() sent only " OFF_T_FMT " bytes", sent); } else { wev->error = 1; -#if 0 - ngx_log_error(level, c->log, err, - "sendfile() failed"); -#else - ngx_log_error(level, c->log, err, - "sendfile(#%d) failed", c->fd); -#endif + ngx_connection_error(c, err, "sendfile() failed"); return NGX_CHAIN_ERROR; } } @@ -223,20 +228,17 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( if (rc == -1) { err = ngx_errno; - if (err == NGX_EINTR) { - eintr = 1; + if (err == NGX_EAGAIN || err == NGX_EINTR) { + if (err == NGX_EINTR) { + eintr = 1; + } - } else if (err == NGX_EPIPE) { - level = NGX_LOG_INFO; - } - - if (err == NGX_EAGAIN || err == NGX_EINTR) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, "writev() not ready"); } else { wev->error = 1; - ngx_log_error(level, c->log, err, "writev() failed"); + ngx_connection_error(c, err, "writev() failed"); return NGX_CHAIN_ERROR; } } @@ -292,8 +294,9 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( /* * sendfile() can return EAGAIN even if it has sent - * a whole file part and successive sendfile() would - * return EAGAIN right away and would not send anything + * a whole file part but the successive sendfile() call would + * return EAGAIN right away and would not send anything. + * We use it as a hint. */ wev->ready = 0; diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h --- a/src/os/unix/ngx_linux_config.h +++ b/src/os/unix/ngx_linux_config.h @@ -34,8 +34,17 @@ #include #include + +/* Linux has a broken strerror_r() */ +#define HAVE_STRERROR_R 0 + #include + +#if (HAVE_PRCTL) +#include +#endif + #if (HAVE_SENDFILE64) #include #else @@ -67,7 +76,7 @@ extern ssize_t sendfile(int s, int fd, i #ifndef HAVE_INHERITED_NONBLOCK -#define HAVE_INHERITED_NONBLOCK 1 +#define HAVE_INHERITED_NONBLOCK 0 #endif diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -6,8 +6,8 @@ /* * On Linux up to 2.4.21 sendfile() (syscall #187) works with 32-bit - * offsets only and the including breaks the compiling if - * off_t is 64 bit wide. So we use own sendfile() definition where offset + * offsets only and the including breaks the compiling + * if off_t is 64 bit wide. So we use own sendfile() definition where offset * parameter is int32_t and use sendfile() with the file parts below 2G. * * Linux 2.4.21 has a new sendfile64() syscall #239. @@ -80,14 +80,24 @@ ngx_chain_t *ngx_linux_sendfile_chain(ng && cl && cl->hunk->type & NGX_HUNK_FILE) { - c->tcp_nopush = 1; + if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { + err = ngx_errno; - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "tcp_nopush"); + /* + * there is a tiny chance to be interrupted, however + * we continue a processing without the TCP_CORK + */ - if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { - ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, - ngx_tcp_nopush_n " failed"); - return NGX_CHAIN_ERROR; + if (err != NGX_EINTR) { + wev->error = 1; + ngx_connection_error(c, err, ngx_tcp_nopush_n " failed"); + return NGX_CHAIN_ERROR; + } + + } else { + c->tcp_nopush = 1; + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "tcp_nopush"); } } @@ -132,51 +142,52 @@ ngx_chain_t *ngx_linux_sendfile_chain(ng if (rc == -1) { err = ngx_errno; - if (err == NGX_EAGAIN) { - ngx_log_error(NGX_LOG_INFO, c->log, err, - "sendfile() EAGAIN"); - } else if (err == NGX_EINTR) { - eintr = 1; - ngx_log_error(NGX_LOG_INFO, c->log, err, - "sendfile() EINTR"); + if (err == NGX_EAGAIN || err == NGX_EINTR) { + if (err == NGX_EINTR) { + eintr = 1; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "sendfile() is not ready"); } else { - ngx_log_error(NGX_LOG_CRIT, c->log, err, - "sendfile() failed"); + wev->error = 1; + ngx_connection_error(c, err, "sendfile() failed"); return NGX_CHAIN_ERROR; } } sent = rc > 0 ? rc : 0; -#if (NGX_DEBUG_WRITE_CHAIN) - ngx_log_debug(c->log, "sendfile: %d, @" OFF_T_FMT " %d:%d" _ - rc _ file->file_pos _ sent _ fsize); -#endif + ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, + "sendfile: %d, @" OFF_T_FMT " %d:%d", + rc, file->file_pos, sent, fsize); + } else { rc = writev(c->fd, header.elts, header.nelts); if (rc == -1) { err = ngx_errno; - if (err == NGX_EAGAIN) { - ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN"); - } else if (err == NGX_EINTR) { - eintr = 1; - ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR"); + if (err == NGX_EAGAIN || err == NGX_EINTR) { + if (err == NGX_EINTR) { + eintr = 1; + } + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "writev() not ready"); } else { - ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); - return NGX_CHAIN_ERROR; + wev->error = 1; + ngx_connection_error(c, err, "writev() failed"); + return NGX_CHAIN_ERROR; } } sent = rc > 0 ? rc : 0; -#if (NGX_DEBUG_WRITE_CHAIN) - ngx_log_debug(c->log, "writev: %d" _ sent); -#endif + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %d", sent); } c->sent += sent; diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c --- a/src/os/unix/ngx_recv.c +++ b/src/os/unix/ngx_recv.c @@ -4,14 +4,12 @@ #include -static int ngx_unix_recv_error(ngx_event_t *rev, ngx_err_t err); - - #if (HAVE_KQUEUE) ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size) { ssize_t n; + ngx_err_t err; ngx_event_t *rev; rev = c->read; @@ -26,11 +24,12 @@ ssize_t ngx_unix_recv(ngx_connection_t * rev->ready = 0; rev->eof = 1; + ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno, + "kevent() reported about an closed connection"); + if (rev->kq_errno) { rev->error = 1; ngx_set_socket_errno(rev->kq_errno); - ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno, - "kevent() reported about closed connection"); if (rev->kq_errno == NGX_ECONNRESET && rev->log_error == NGX_ERROR_IGNORE_ECONNRESET) @@ -52,7 +51,8 @@ ssize_t ngx_unix_recv(ngx_connection_t * do { n = recv(c->fd, buf, size, 0); - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,"recv: %d:%d", n, size); + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, + "recv: fd:%d %d of %d", c->fd, n, size); if (n >= 0) { if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { @@ -87,11 +87,19 @@ ssize_t ngx_unix_recv(ngx_connection_t * return n; } - n = ngx_unix_recv_error(rev, ngx_socket_errno); + err = ngx_socket_errno; + + if (err == NGX_EAGAIN || err == NGX_EINTR) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, err, + "recv() not ready"); + n = NGX_AGAIN; - } while (n == NGX_EINTR); + } else { + n = ngx_connection_error(c, err, "recv() failed"); + break; + } - /* NGX_ERROR || NGX_AGAIN */ + } while (err == NGX_EINTR); rev->ready = 0; @@ -107,6 +115,7 @@ ssize_t ngx_unix_recv(ngx_connection_t * ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size) { ssize_t n; + ngx_err_t err; ngx_event_t *rev; rev = c->read; @@ -114,7 +123,8 @@ ssize_t ngx_unix_recv(ngx_connection_t * do { n = recv(c->fd, buf, size, 0); - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,"recv: %d:%d", n, size); + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, + "recv: fd:%d %d of %d", c->fd, n, size); if (n >= 0) { if ((size_t) n < size) { @@ -128,11 +138,19 @@ ssize_t ngx_unix_recv(ngx_connection_t * return n; } - n = ngx_unix_recv_error(rev, ngx_socket_errno); + err = ngx_socket_errno; + + if (err == NGX_EAGAIN || err == NGX_EINTR) { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, err, + "recv() not ready"); + n = NGX_AGAIN; - } while (n == NGX_EINTR); + } else { + n = ngx_connection_error(c, err, "recv() failed"); + break; + } - /* NGX_ERROR || NGX_AGAIN */ + } while (err == NGX_EINTR); rev->ready = 0; @@ -144,37 +162,3 @@ ssize_t ngx_unix_recv(ngx_connection_t * } #endif /* NAVE_KQUEUE */ - - -static int ngx_unix_recv_error(ngx_event_t *rev, ngx_err_t err) -{ - ngx_int_t level; - - if (err == NGX_EAGAIN || err == NGX_EINTR) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, err, "recv() not ready"); - return NGX_AGAIN; - } - - if (err == NGX_ECONNRESET) { - - switch (rev->log_error) { - case NGX_ERROR_IGNORE_ECONNRESET: - return 0; - case NGX_ERROR_INFO: - level = NGX_LOG_INFO; - break; - case NGX_ERROR_ERR: - level = NGX_LOG_ERR; - break; - default: - level = NGX_LOG_CRIT; - } - - } else { - level = NGX_LOG_CRIT; - } - - ngx_log_error(level, rev->log, err, "recv() failed"); - - return NGX_ERROR; -} diff --git a/src/os/unix/ngx_recv.h b/src/os/unix/ngx_recv.h deleted file mode 100644 --- a/src/os/unix/ngx_recv.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _NGX_RECV_H_INCLUDED_ -#define _NGX_RECV_H_INCLUDED_ - - -#if 0 -#include - -#define ngx_recv(fd, buf, size, flags) recv(fd, buf, size, flags) -#endif - - -#endif /* _NGX_RECV_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c --- a/src/os/unix/ngx_socket.c +++ b/src/os/unix/ngx_socket.c @@ -4,12 +4,13 @@ /* - ioctl(FIONBIO) set blocking mode with one syscall only while - fcntl(F_SETFL, ~O_NONBLOCK) need to know previous state - using fcntl(F_GETFL). - - ioctl() and fcntl() are syscalls on FreeBSD, Solaris 7/8 and Linux -*/ + * ioctl(FIONBIO) sets a blocking mode with the single syscall + * while fcntl(F_SETFL, ~O_NONBLOCK) needs to learn before + * a previous state using fcntl(F_GETFL). + * + * ioctl() and fcntl() are syscalls on at least FreeBSD 2.x, Linux 2.2 + * and Solaris 7 + */ #if (HAVE_FIONBIO)