changeset 210:00cafae0bdf1

nginx-0.0.1-2003-12-14-23:10:27 import
author Igor Sysoev <igor@sysoev.ru>
date Sun, 14 Dec 2003 20:10:27 +0000
parents e1c815be05ae
children fd9fecc4193f
files auto/configure auto/fmt/fmt auto/fmt/xfmt auto/func auto/inc auto/init auto/lib/conf auto/lib/lib auto/lib/md5/conf auto/lib/test auto/lib/zlib/conf auto/options auto/sources auto/summary auto/types/sizeof auto/types/typedef auto/types/uintptr_t auto/unix src/core/nginx.c src/core/nginx.h src/core/ngx_config.h src/core/ngx_log.c src/core/ngx_log.h src/event/modules/ngx_kqueue_module.c src/event/ngx_event_timer.c src/event/ngx_event_timer.h src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_header_filter.c src/http/ngx_http_log_handler.c src/http/ngx_http_parse.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/os/unix/ngx_errno.c src/os/unix/ngx_errno.h src/os/unix/ngx_os.h src/os/unix/ngx_posix_init.c src/os/win32/ngx_time.c src/os/win32/ngx_win32_init.c
diffstat 39 files changed, 819 insertions(+), 671 deletions(-) [+]
line wrap: on
line diff
--- a/auto/configure
+++ b/auto/configure
@@ -6,7 +6,7 @@
 . auto/os/conf
 
 . auto/cc
-. auto/lib/lib
+. auto/lib/conf
 . auto/make
 . auto/lib/make
 
@@ -15,3 +15,5 @@ echo > $NGX_AUTO_CONFIG_H
 if [ "$PLATFORM" != win32 ]; then
     . auto/unix
 fi
+
+. auto/summary
--- a/auto/fmt/fmt
+++ b/auto/fmt/fmt
@@ -1,59 +1,77 @@
 
-echo "checking for $NGX_TYPE printf() format"
+echo -n "checking for $ngx_type printf() format ..."
+echo >> $NGX_ERR
+echo "checking for $ngx_type printf() format" >> $NGX_ERR
 
-NGX_FMT=NO
+ngx_fmt=no
+comma=
 
-for FMT in $NGX_FORMATS
+for fmt in $ngx_formats
 do
-    echo "#include <stdio.h>" > autotest.c
-    echo "#include <sys/types.h>" >> autotest.c
-    echo "#include <sys/time.h>" >> autotest.c
-    echo "#include <sys/resource.h>" >> autotest.c
-    echo "$NGX_INTTYPES_H" >> autotest.c
-    echo "$NGX_AUTO_CONFIG" >> autotest.c
-    echo "int main() {" >> autotest.c
-    echo "printf(\"${FMT}\", ($NGX_TYPE) $NGX_MAX_SIZE);" >> autotest.c
-    echo "return 0; }" >> autotest.c
+
+    cat << END > $NGX_AUTOTEST.c
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+$NGX_INTTYPES_H
+$NGX_AUTO_CONFIG
+
+int main() {
+    printf("$fmt", ($ngx_type) $ngx_max_size);
+    return 0;
+}
 
-    eval "$CC_WARN $CC_TEST_FLAGS -o autotest autotest.c > $NGX_ERR 2>&1"
+END
 
-    MAX_SIZE=`echo $NGX_MAX_SIZE | sed -e "s/L*\$//"`
+    eval "$CC_WARN $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c \
+          >> $NGX_ERR 2>&1"
+
+    max_size=`echo $ngx_max_size | sed -e "s/L*\$//"`
 
-    if [ -x ./autotest ]; then
-        if [ "`./autotest`" = $MAX_SIZE ]; then
-            if [ $NGX_FMT_COLLECT = YES ]; then
-                echo " + \"${FMT}\" is appropriate"
+    if [ -x $NGX_AUTOTEST ]; then
+        if [ "`$NGX_AUTOTEST`" = $max_size ]; then
+            if [ $ngx_fmt_collect = yes ]; then
+                echo -n "$comma \"${fmt}\" is appropriate"
             else
-                echo " + \"${FMT}\" used"
+                echo -n "$comma \"${fmt}\" used"
             fi
-            NGX_FMT=$FMT
+            ngx_fmt=$fmt
         fi
     fi
 
-    rm autotest*
+    rm $NGX_AUTOTEST*
 
-    if [ $NGX_FMT != NO ]; then
-        if [ $NGX_FMT_COLLECT = YES ]; then
-            eval "NGX_${NGX_BYTES}_FMT=\"\${NGX_${NGX_BYTES}_FMT} \$NGX_FMT\""
+    if [ $ngx_fmt != no ]; then
+        if [ $ngx_fmt_collect = yes ]; then
+            eval "ngx_${ngx_bytes}_fmt=\"\${ngx_${ngx_bytes}_fmt} \$ngx_fmt\""
+            comma=","
             continue
         else
             break
         fi
     fi
 
-    echo " + \"${FMT}\" is not appropriate"
+    echo -n "$comma \"${fmt}\" is not appropriate"
+    comma=","
 done
 
+echo
 
-if [ $NGX_FMT = NO ]; then
-    echo "$0: error: printf() $NGX_TYPE format not found"
+if [ $ngx_fmt = no ]; then
+    echo "$0: error: printf() $ngx_type format not found"
     exit 1
 fi
 
 
-if [ $NGX_FMT_COLLECT = NO ]; then
-    echo "#ifndef $NGX_FMT_NAME"                 >> $NGX_AUTO_CONFIG_H
-    echo "#define $NGX_FMT_NAME  \"$NGX_FMT\""   >> $NGX_AUTO_CONFIG_H
-    echo "#endif"                                >> $NGX_AUTO_CONFIG_H
-    echo                                         >> $NGX_AUTO_CONFIG_H
+if [ $ngx_fmt_collect = no ]; then
+    cat << END >> $NGX_AUTO_CONFIG_H
+
+#ifndef $ngx_fmt_name
+#define $ngx_fmt_name  "$ngx_fmt"
+#endif
+
+END
+
 fi
--- a/auto/fmt/xfmt
+++ b/auto/fmt/xfmt
@@ -1,6 +1,6 @@
 
-echo "#ifndef $NGX_FMT_NAME"                 >> $NGX_AUTO_CONFIG_H
-echo "#define $NGX_FMT_NAME  \"$NGX_FMT\"" | sed -e 's/d"$/x"/' \
+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
--- a/auto/func
+++ b/auto/func
@@ -1,28 +1,42 @@
 
-echo "checking for $NGX_FUNC"
+echo -n "checking for $ngx_func ..."
+echo >> $NGX_ERR
+echo "checking for $ngx_func" >> $NGX_ERR
 
-NGX_FOUND=NO
+ngx_found=no
 
-func=`echo $NGX_FUNC | sed -e 's/()$//' | tr '[a-z]' '[A-Z]'`
+func=`echo $ngx_func | sed -e 's/()$//' | tr '[a-z]' '[A-Z]'`
 
-echo "$NGX_UNISTD_H" > autotest.c
-echo "$NGX_FUNC_INC" >> autotest.c
-echo "int main() { $NGX_FUNC_TEST; return 0; }" >> autotest.c
+cat << END > $NGX_AUTOTEST.c
+
+$NGX_UNISTD_H
+$ngx_func_inc
 
-eval "$CC $CC_TEST_FLAGS -o autotest autotest.c $NGX_FUNC_LIBS > $NGX_ERR 2>&1"
+int main() {
+    $ngx_func_test;
+    return 0;
+}
 
-if [ -x autotest ]; then
-    echo " + $NGX_FUNC found"
+END
+
+eval "$CC $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c $ngx_func_libs \
+     >> $NGX_ERR 2>&1"
 
-    echo "#ifndef HAVE_$func"      >> $NGX_AUTO_CONFIG_H
-    echo "#define HAVE_$func  1"   >> $NGX_AUTO_CONFIG_H
-    echo "#endif"                  >> $NGX_AUTO_CONFIG_H
-    echo                           >> $NGX_AUTO_CONFIG_H
+if [ -x $NGX_AUTOTEST ]; then
+    echo " found"
+
+    cat << END >> $NGX_AUTO_CONFIG_H
 
-    NGX_FOUND=YES
+#ifndef HAVE_$func
+#define HAVE_$func  1
+#endif
+
+END
+
+    ngx_found=yes
 
 else
-    echo " + $NGX_FUNC not found"
+    echo " not found"
 fi
 
-rm autotest*
+rm $NGX_AUTOTEST*
--- a/auto/inc
+++ b/auto/inc
@@ -1,28 +1,40 @@
 
-echo "checking for $NGX_INC"
+echo -n "checking for $ngx_inc ..."
+echo >> $NGX_ERR
+echo "checking for $ngx_inc" >> $NGX_ERR
 
-NGX_FOUND=NO
+ngx_found=no
 
-inc=`echo $NGX_INC | sed -e 's/\./_/' | sed -e 's/\//_/' | tr '[a-z]' '[A-Z]'`
+inc=`echo $ngx_inc | sed -e 's/\./_/' | sed -e 's/\//_/' | tr '[a-z]' '[A-Z]'`
+
+cat << END > $NGX_AUTOTEST.c
 
-echo "#include <$NGX_INC>" > autotest.c
-echo "int main() { return 0; }" >> autotest.c
+#include <$ngx_inc>
+
+int main() {
+    return 0;
+}
 
-eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
+END
+
+eval "${CC} -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
 
-if [ -x autotest ]; then
-    echo " + $NGX_INC found"
+if [ -x $NGX_AUTOTEST ]; then
+    echo " found"
+
+    cat << END >> $NGX_AUTO_CONFIG_H
 
-    echo "#ifndef HAVE_$inc"      >> $NGX_AUTO_CONFIG_H
-    echo "#define HAVE_$inc  1"   >> $NGX_AUTO_CONFIG_H
-    echo "#endif"                 >> $NGX_AUTO_CONFIG_H
-    echo                          >> $NGX_AUTO_CONFIG_H
+#ifndef HAVE_$inc
+#define HAVE_$inc  1
+#endif
 
-    eval "NGX_$inc='#include <$NGX_INC>'"
-    NGX_FOUND=YES
+END
+
+    eval "NGX_$inc='#include <$ngx_inc>'"
+    ngx_found=yes
 
 else
-    echo " + $NGX_INC not found"
+    echo " not found"
 fi
 
-rm autotest*
+rm $NGX_AUTOTEST*
--- a/auto/init
+++ b/auto/init
@@ -4,4 +4,5 @@ MAKEFILE=$OBJS/Makefile
 NGX_AUTO_CONFIG_H=$OBJS/ngx_auto_config.h
 NGX_MODULES_C=$OBJS/ngx_modules.c
 
-NGX_ERR=autoconf.err
+NGX_AUTOTEST=$OBJS/autotest
+NGX_ERR=$OBJS/autoconf.err
new file mode 100644
--- /dev/null
+++ b/auto/lib/conf
@@ -0,0 +1,24 @@
+
+if [ $PCRE != NO ]; then
+
+    CORE_INCS="$CORE_INCS -I $PCRE"
+
+    if [ "$PLATFORM" = "win32" ]; then
+        CFLAGS="$CFLAGS -D PCRE_STATIC"
+        CORE_LIBS="$CORE_LIBS pcre.lib"
+        CORE_LINK="$CORE_LINK -libpath:$PCRE"
+    else 
+        CORE_DEPS="$CORE_DEPS $PCRE/.libs/libpcre.a"
+        CORE_LIBS="$CORE_LIBS -L $PCRE/.libs -lpcre"
+    fi
+fi
+
+
+if [ $USE_MD5 = YES ]; then
+    . auto/lib/md5/conf
+fi
+
+
+if [ $USE_ZLIB = YES ]; then
+    . auto/lib/zlib/conf
+fi
deleted file mode 100644
--- a/auto/lib/lib
+++ /dev/null
@@ -1,48 +0,0 @@
-
-if [ $PCRE != NO ]; then
-
-    CORE_INCS="$CORE_INCS -I $PCRE"
-
-    if [ "$PLATFORM" = "win32" ]; then
-        CFLAGS="$CFLAGS -D PCRE_STATIC"
-        CORE_LIBS="$CORE_LIBS pcre.lib"
-        CORE_LINK="$CORE_LINK -libpath:$PCRE"
-    else 
-        CORE_DEPS="$CORE_DEPS $PCRE/.libs/libpcre.a"
-        CORE_LIBS="$CORE_LIBS -L $PCRE/.libs -lpcre"
-    fi
-fi
-
-
-if [ $MD5 != NO ]; then
-
-    CFLAGS="$CFLAGS -D HAVE_OPENSSL_MD5"
-    CORE_INCS="$CORE_INCS -I $MD5"
-
-    if [ "$PLATFORM" = "win32" ]; then
-        CORE_LIBS="$CORE_LIBS md5.lib"
-        CORE_LINK="$CORE_LINK -libpath:$MD5"
-    else 
-        LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
-        CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5"
-    fi
-
-elif [ $MD5_LIB != NO ]; then
-    CORE_LIBS="$CORE_LIBS $MD5_LIB"
-fi
-
-
-if [ $ZLIB != NO ]; then
-    CORE_INCS="$CORE_INCS -I $ZLIB"
-
-    if [ "$PLATFORM" = "win32" ]; then
-        CORE_LIBS="$CORE_LIBS zlib.lib"
-        CORE_LINK="$CORE_LINK -libpath:$ZLIB"
-    else 
-        LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
-        CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
-    fi
-
-elif [ $ZLIB_LIB != NO ]; then
-    CORE_LIBS="$CORE_LIBS $ZLIB_LIB"
-fi
new file mode 100644
--- /dev/null
+++ b/auto/lib/md5/conf
@@ -0,0 +1,67 @@
+
+if [ $MD5 != NO ]; then
+
+    if grep MD5_Init $MD5/md5.h >/dev/null; then
+        # OpenSSL md5
+        OPENSSL_MD5=YES
+        CFLAGS="$CFLAGS -D HAVE_OPENSSL_MD5"
+    else
+        # rsaref md5
+        OPENSSL_MD5=NO
+    fi
+
+    CORE_INCS="$CORE_INCS -I $MD5"
+
+    if [ "$PLATFORM" = "win32" ]; then
+        CORE_LIBS="$CORE_LIBS md5.lib"
+        CORE_LINK="$CORE_LINK -libpath:$MD5"
+    else 
+        LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
+        CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5"
+    fi
+
+else
+
+ngx_lib_inc="#include <sys/types.h>
+#include <md5.h>"
+
+        # Solaris 8/9
+        ngx_lib="rsaref md5"
+        ngx_lib_test="MD5_CTX md5; MD5Init(&md5)"
+        ngx_libs=-lmd5
+        . auto/lib/test
+
+
+    if [ $ngx_found = yes ]; then
+        CORE_LIBS="$CORE_LIBS $ngx_libs"
+        MD5=YES
+        ngx_found=no
+
+    else
+        # FreeBSD
+        ngx_lib="rsaref md"
+        ngx_lib_test="MD5_CTX md5; MD5Init(&md5)"
+        ngx_libs=-lmd
+        . auto/lib/test
+    fi
+
+
+    if [ $ngx_found = yes ]; then
+        CORE_LIBS="$CORE_LIBS $ngx_libs"
+        MD5=YES
+        ngx_found=no
+
+    else
+        ngx_lib="OpenSSL md5"
+        ngx_lib_test="MD5_CTX md5; MD5_Init(&md5)"
+        ngx_libs=-lmd5
+        . auto/lib/test
+    fi
+
+
+    if [ $ngx_found = yes ]; then
+        CFLAGS="$CFLAGS -D HAVE_OPENSSL_MD5"
+        CORE_LIBS="$CORE_LIBS $ngx_libs"
+        MD5=YES
+    fi
+fi
new file mode 100644
--- /dev/null
+++ b/auto/lib/test
@@ -0,0 +1,23 @@
+
+echo "checking for $ngx_lib library"
+echo >> $NGX_ERR
+echo "checking for $ngx_lib library" >> $NGX_ERR
+
+ngx_found=no
+
+echo "$ngx_lib_inc" > $NGX_AUTOTEST.c
+echo "int main() { $ngx_lib_test; return 0; }" >> $NGX_AUTOTEST.c
+
+eval "$CC $cc_test_flags -o $NGX_AUTOTEST $NGX_AUTOTEST.c $ngx_libs \
+     >> $NGX_ERR 2>&1"
+
+if [ -x $NGX_AUTOTEST ]; then
+    echo " + $ngx_lib found"
+
+    ngx_found=yes
+
+else
+    echo " + $ngx_lib not found"
+fi
+
+rm $NGX_AUTOTEST*
new file mode 100644
--- /dev/null
+++ b/auto/lib/zlib/conf
@@ -0,0 +1,28 @@
+
+if [ $ZLIB != NO ]; then
+    CORE_INCS="$CORE_INCS -I $ZLIB"
+
+    if [ "$PLATFORM" = "win32" ]; then
+        CORE_LIBS="$CORE_LIBS zlib.lib"
+        CORE_LINK="$CORE_LINK -libpath:$ZLIB"
+    else
+        LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
+        CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
+    fi
+
+else
+
+    ngx_lib_inc="#include <zlib.h>"
+
+    ngx_lib="zlib"
+    ngx_lib_test="z_stream z; deflate(&z, Z_NO_FLUSH)"
+    ngx_libs=-lz
+    . auto/lib/test
+
+
+    if [ $ngx_found = yes ]; then
+        CORE_LIBS="$CORE_LIBS $ngx_libs"
+        ZLIB=YES
+    fi
+
+fi
--- a/auto/options
+++ b/auto/options
@@ -1,5 +1,5 @@
 
-HELP=NO
+help=no
 
 CC=gcc
 OBJS=objs
@@ -11,9 +11,11 @@ HTTP_PROXY=YES
 
 PCRE=NO
 
+USE_MD5=YES
 MD5=NO
 MD5_LIB=NO
 
+USE_ZLIB=YES
 ZLIB=NO
 ZLIB_LIB=NO
 
@@ -26,7 +28,7 @@ do
     esac
 
     case "$option" in
-        --help)                          HELP=YES                   ;;
+        --help)                          help=yes                   ;;
 
         --crossbuild=*)                  PLATFORM="$value"          ;;
 
@@ -51,7 +53,8 @@ do
 done
 
 
-if [ $HELP = YES ]; then
+if [ $help = yes ]; then
+    echo
     echo "  --help                        this message"
 
     echo "  --without-http_gzip_module    disable http_gzip_module"
@@ -63,6 +66,7 @@ if [ $HELP = YES ]; then
     echo "  --with-pcre=DIR               path to PCRE library"
     echo "  --with-md5=DIR                path to md5 library"
     echo "  --with-zlib=DIR               path to zlib library"
+    echo
 
     exit 1
 fi
--- a/auto/sources
+++ b/auto/sources
@@ -88,6 +88,7 @@ UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \
 
 UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \
             src/os/unix/ngx_time.c \
+            src/os/unix/ngx_errno.c \
             src/os/unix/ngx_sendv.c \
             src/os/unix/ngx_files.c \
             src/os/unix/ngx_socket.c \
new file mode 100644
--- /dev/null
+++ b/auto/summary
@@ -0,0 +1,17 @@
+
+echo
+echo "Configuration summary"
+
+case $MD5 in
+    YES) echo " + using system md5 library" ;;
+    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" ;;
+esac
+
+echo
--- a/auto/types/sizeof
+++ b/auto/types/sizeof
@@ -1,44 +1,52 @@
 
-echo "checking for $NGX_TYPE size"
+echo -n "checking for $ngx_type size ..."
+echo >> $NGX_ERR
+echo "checking for $ngx_type size" >> $NGX_ERR
 
-NGX_BYTES=
+ngx_bytes=
+
+cat << END > $NGX_AUTOTEST.c
 
-echo "#include <sys/types.h>" > autotest.c
-echo "#include <sys/time.h>" >> autotest.c
-echo "#include <sys/resource.h>" >> autotest.c
-echo "$NGX_INTTYPES_H" >> autotest.c
-echo "$NGX_AUTO_CONFIG" >> autotest.c
-echo "int main() {" >> autotest.c
-echo "printf(\"%d\", sizeof($NGX_TYPE));" >> autotest.c
-echo "return 0; }" >> autotest.c
+#include <sys/time.h>
+#include <sys/resource.h>
+$NGX_INTTYPES_H
+$NGX_AUTO_CONFIG
 
-eval "$CC $CC_TEST_FLAGS -o autotest autotest.c > /dev/null 2>&1"
+int main() {
+    printf("%d", sizeof($ngx_type));
+    return 0;
+}
 
-if [ -x ./autotest ]; then
-    NGX_BYTES=`./autotest`
-    echo " + $NGX_TYPE is $NGX_BYTES bytes"
+END
+
+eval "$CC $CC_TEST_FLAGS -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
+
+if [ -x $NGX_AUTOTEST ]; then
+    ngx_bytes=`$NGX_AUTOTEST`
+    echo " $ngx_bytes bytes"
 fi
 
-rm autotest*
+rm $NGX_AUTOTEST*
 
-case $NGX_BYTES in
+case $ngx_bytes in
     4)
-        if [ "$NGX_TYPE"="long" ]; then
-            NGX_MAX_SIZE=2147483647L
+        if [ "$ngx_type"="long" ]; then
+            ngx_max_size=2147483647L
         else
-            NGX_MAX_SIZE=2147483647
+            ngx_max_size=2147483647
         fi
     ;;
 
     8)
-        if [ "$NGX_TYPE"="long long" ]; then
-            NGX_MAX_SIZE=9223372036854775807LL
+        if [ "$ngx_type"="long long" ]; then
+            ngx_max_size=9223372036854775807LL
         else
-            NGX_MAX_SIZE=9223372036854775807L
+            ngx_max_size=9223372036854775807L
         fi
     ;;
 
     *)
-        echo "$0: error: can not detect $NGX_TYPE size"
+        echo
+        echo "$0: error: can not detect $ngx_type size"
         exit 1
 esac
--- a/auto/types/typedef
+++ b/auto/types/typedef
@@ -1,45 +1,56 @@
-
-echo "checking for $NGX_TYPE"
 
-FOUND=NO
+echo -n "checking for $ngx_type ..."
+echo >> $NGX_ERR
+echo "checking for $ngx_type" >> $NGX_ERR
 
-for TYPE in $NGX_TYPE $NGX_TYPES
+found=no
+
+for type in $ngx_type $ngx_types
 do
-    echo "#include <sys/types.h>" > autotest.c
-    echo "#include <sys/socket.h>" >> autotest.c
-    echo "#include <sys/time.h>" >> autotest.c
-    echo "#include <sys/resource.h>" >> autotest.c
-    echo "#include <netinet/in.h>" >> autotest.c
-    echo "$NGX_INTTYPES_H" >> autotest.c
-    echo "int main() { $TYPE i = 0; return 0; }" >> autotest.c
+
+    cat << END > $NGX_AUTOTEST.c
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+$NGX_INTTYPES_H
 
-    eval "$CC -o autotest autotest.c > $NGX_ERR 2>&1"
+int main() {
+    $type i = 0;
+    return 0;
+}
+
+END
 
-    if [ -x autotest ]; then
-        if [ $TYPE = $NGX_TYPE ]; then
-            echo " + $NGX_TYPE found"
-            FOUND=YES
+    eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
+
+    if [ -x $NGX_AUTOTEST ]; then
+        if [ $type = $ngx_type ]; then
+            echo " found"
+            found=yes
         else
-            echo " + $TYPE used"
-            FOUND=$TYPE
+            echo ", $type used"
+            found=$type
         fi
     fi
 
-    rm autotest*
+    rm $NGX_AUTOTEST*
 
-    if [ $FOUND = NO ]; then
-        echo " + $TYPE not found"
+    if [ $found = no ]; then
+        echo -n " $type not found"
     else
         break
     fi
 done
 
-if [ $FOUND = NO ]; then
-    echo "$0: error: can not define $NGX_TYPE"
+if [ $found = no ]; then
+    echo
+    echo "$0: error: can not define $ngx_type"
     exit 1
 fi
 
-if [ $FOUND != YES ]; then
-    echo "typedef $FOUND  $NGX_TYPE;"   >> $NGX_AUTO_CONFIG_H
-    echo                                >> $NGX_AUTO_CONFIG_H
+if [ $found != yes ]; then
+    echo "typedef $found  $ngx_type;"   >> $NGX_AUTO_CONFIG_H
 fi
--- a/auto/types/uintptr_t
+++ b/auto/types/uintptr_t
@@ -1,27 +1,37 @@
 
-echo 'checking for uintptr_t'
+echo -n "checking for uintptr_t ... "
+echo >> $NGX_ERR
+echo "checking for uintptr_t" >> $NGX_ERR
 
-FOUND=NO
+found=no
+
+cat << END > $NGX_AUTOTEST.c
+
+#include <sys/types.h>
+$NGX_INTTYPES_H
 
-echo "#include <sys/types.h>" > autotest.c
-echo "$NGX_INTTYPES_H" >> autotest.c
-echo "int main() { uintptr_t i = 0; return 0; }" >> autotest.c
+int main() {
+    uintptr_t i = 0;
+    return 0;
+}
 
-eval "$CC -o autotest autotest.c > /dev/null 2>&1"
+END
 
-if [ -x autotest ]; then
-    echo " + uintptr_t found"
-    FOUND=YES
+eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
+
+if [ -x $NGX_AUTOTEST ]; then
+    echo " uintptr_t found"
+    found=yes
 else
-    echo " + uintptr_t not found"
+    echo -n " uintptr_t not found"
 fi
 
-rm autotest*
+rm $NGX_AUTOTEST*
 
 
-if [ $FOUND = NO ]; then
-    FOUND="uint`expr 8 \* $NGX_PTR_BYTES`_t"
-    echo " + $FOUND used"
-    echo "typedef $FOUND  uintptr_t;"   >> $NGX_AUTO_CONFIG_H
-    echo                                >> $NGX_AUTO_CONFIG_H
+if [ $found = no ]; then
+    found="uint`expr 8 \* $ngx_ptr_bytes`_t"
+    echo ", $found used"
+
+    echo "typedef $found  uintptr_t;"   >> $NGX_AUTO_CONFIG_H
 fi
--- a/auto/unix
+++ b/auto/unix
@@ -1,41 +1,41 @@
 
 CC_WARN=$CC
-NGX_FMT_COLLECT=YES
+ngx_fmt_collect=yes
 
 # C types
 
-NGX_TYPE="int"; . auto/types/sizeof;
-NGX_FORMATS="%d"; . auto/fmt/fmt
+ngx_type="int"; . auto/types/sizeof;
+ngx_formats="%d"; . auto/fmt/fmt
 
-NGX_TYPE="long"; . auto/types/sizeof;
-NGX_FORMATS="%ld"; . auto/fmt/fmt
+ngx_type="long"; . auto/types/sizeof;
+ngx_formats="%ld"; . auto/fmt/fmt
 
-NGX_TYPE="long long"; . auto/types/sizeof;
-NGX_FORMATS="%lld %qd"; . auto/fmt/fmt
+ngx_type="long long"; . auto/types/sizeof;
+ngx_formats="%lld %qd"; . auto/fmt/fmt
 
-NGX_TYPE="void *"; . auto/types/sizeof; NGX_PTR_BYTES=$NGX_BYTES
+ngx_type="void *"; . auto/types/sizeof; ngx_ptr_bytes=$ngx_bytes
 
 
 # headers
 
-NGX_INC="unistd.h"; . auto/inc
-NGX_INC="inttypes.h"; . auto/inc
+ngx_inc="unistd.h"; . auto/inc
+ngx_inc="inttypes.h"; . auto/inc
 
 #POSIX types
 
-NGX_AUTO_CONFIG="#include \"$NGX_AUTO_CONFIG_H\""
+NGX_AUTO_CONFIG="#include \"../$NGX_AUTO_CONFIG_H\""
 
-NGX_TYPE="uint64_t"
-NGX_TYPES="u_int64_t"; . auto/types/typedef
+ngx_type="uint64_t"
+ngx_types="u_int64_t"; . auto/types/typedef
 
-NGX_TYPE="socklen_t"
-NGX_TYPES="uint32_t"; . auto/types/typedef
+ngx_type="socklen_t"
+ngx_types="uint32_t"; . auto/types/typedef
 
-NGX_TYPE="in_addr_t"
-NGX_TYPES="uint32_t"; . auto/types/typedef
+ngx_type="in_addr_t"
+ngx_types="uint32_t"; . auto/types/typedef
 
-NGX_TYPE="rlim_t"
-NGX_TYPES="int"; . auto/types/typedef
+ngx_type="rlim_t"
+ngx_types="int"; . auto/types/typedef
 
 . auto/types/uintptr_t
 
@@ -43,47 +43,53 @@ NGX_TYPES="int"; . auto/types/typedef
 # printf() formats
 
 CC_WARN=$CC_STRONG
-NGX_FMT_COLLECT=NO
+ngx_fmt_collect=no
 
-NGX_FMT_NAME=OFF_T_FMT
-NGX_TYPE="off_t"; . auto/types/sizeof
-eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+ngx_fmt_name=OFF_T_FMT; ngx_type="off_t"; . auto/types/sizeof
+eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
 
-NGX_FMT_NAME=TIME_T_FMT
-NGX_TYPE="time_t"; . auto/types/sizeof
-eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+ngx_fmt_name=TIME_T_FMT; ngx_type="time_t"; . auto/types/sizeof
+eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
 
-NGX_FMT_NAME=SIZE_T_FMT
-NGX_TYPE="size_t"; . auto/types/sizeof
-eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+ngx_fmt_name=SIZE_T_FMT; ngx_type="size_t"; . auto/types/sizeof
+eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
 
-NGX_FMT_NAME=SIZE_T_X_FMT; . auto/fmt/xfmt
+ngx_fmt_name=SIZE_T_X_FMT; . auto/fmt/xfmt
 
-NGX_FMT_NAME=PID_T_FMT
-NGX_TYPE="pid_t"; . auto/types/sizeof
-eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+ngx_fmt_name=PID_T_FMT; ngx_type="pid_t"; . auto/types/sizeof
+eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
 
-NGX_FMT_NAME=RLIM_T_FMT
-NGX_TYPE="rlim_t"; . auto/types/sizeof
-eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+ngx_fmt_name=RLIM_T_FMT; ngx_type="rlim_t"; . auto/types/sizeof
+eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
 
 
 # syscalls and libc calls
 
-NGX_FUNC_INC=
-NGX_FUNC_TEST="int fd = 0; char buf[1]; size_t size = 1;
-               ssize_t n; off_t offset = 0;
-               n = pread(fd, buf, size, offset)"
-NGX_FUNC="pread()"; . auto/func
+ngx_func="pread()"
+ngx_func_inc=
+ngx_func_test="
+char    buf[1];
+ssize_t n;
+n = pread(0, buf, 1, 0)"
+. auto/func
 
 
-NGX_FUNC_INC=
-NGX_FUNC_TEST="int fd = 1; char buf[1]; size_t size = 1;
-               ssize_t n; off_t offset = 0;
-               n = pwrite(fd, buf, size, offset)"
-NGX_FUNC="pwrite()"; . auto/func
+ngx_func="pwrite()"
+ngx_func_inc=
+ngx_func_test="
+char    buf[1];
+ssize_t n;
+n = pwrite(1, buf, 1, 0)"
+. auto/func
 
 
-NGX_FUNC_INC="#include <time.h>"
-NGX_FUNC_TEST="struct tm t; time_t c=0; localtime_r(&c, &t)"
-NGX_FUNC="localtime_r()"; . auto/func
+ngx_func="strerror_r()"
+ngx_func_inc="#include <string.h>"
+ngx_func_test="char buf[20]; strerror_r(1, buf, 20)"
+. auto/func
+
+
+ngx_func="localtime_r()"
+ngx_func_inc="#include <time.h>"
+ngx_func_test="struct tm t; time_t c=0; localtime_r(&c, &t)"
+. auto/func
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -16,7 +16,8 @@ static void ngx_clean_old_cycles(ngx_eve
 
 
 typedef struct {
-     int   daemon;
+     int        daemon;
+     ngx_str_t  pid;
 } ngx_core_conf_t;
 
 
@@ -61,6 +62,7 @@ static ngx_connection_t  dumb;
 u_int ngx_connection_counter;
 
 
+int done;
 int restart;
 int rotate;
 
@@ -73,6 +75,9 @@ int main(int argc, char *const *argv)
     ngx_cycle_t      *cycle;
     ngx_open_file_t  *file;
 #if !(WIN32)
+    size_t            len;
+    char              pid[/* STUB */ 10];
+    ngx_file_t        pidfile;
     ngx_core_conf_t  *ccf;
 #endif
 
@@ -119,6 +124,33 @@ int main(int argc, char *const *argv)
         return 1;
     }
 
+    if (ccf->pid.len == 0) {
+        ccf->pid.len = sizeof(NGINX_PID) - 1;
+        ccf->pid.data = NGINX_PID;
+    }
+
+    len = ngx_snprintf(pid, /* STUB */ 10, PID_T_FMT, ngx_getpid());
+    ngx_memzero(&pidfile, sizeof(ngx_file_t));
+    pidfile.name = ccf->pid;
+
+    pidfile.fd = ngx_open_file(pidfile.name.data, NGX_FILE_RDWR,
+                               NGX_FILE_CREATE_OR_OPEN);
+
+    if (pidfile.fd == NGX_INVALID_FILE) {
+        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+                      ngx_open_file_n " \"%s\" failed", pidfile.name.data);
+        return 1;
+    }
+
+    if (ngx_write_file(&pidfile, pid, len, 0) == NGX_ERROR) {
+        return 1;
+    }
+
+    if (ngx_close_file(pidfile.fd) == NGX_FILE_ERROR) {
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                      ngx_close_file_n " \"%s\" failed", pidfile.name.data);
+    }
+
 #endif
 
     /* life cycle */
@@ -162,8 +194,20 @@ int main(int argc, char *const *argv)
 
                 ngx_process_events(cycle->log);
 
+                if (done) {
+                    if (ngx_delete_file(pidfile.name.data) == NGX_FILE_ERROR) {
+                        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                                      ngx_delete_file_n " \"%s\" failed",
+                                      pidfile.name.data);
+                    }
+
+                    ngx_log_error(NGX_LOG_INFO,
+                                  cycle->log, 0, "exiting");
+                    exit(0);
+                }
+
                 if (rotate) {
-                    ngx_log_debug(cycle->log, "rotate");
+                    ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "rotating logs");
 
                     file = cycle->open_files.elts;
                     for (i = 0; i < cycle->open_files.nelts; i++) {
@@ -313,6 +357,10 @@ static ngx_cycle_t *ngx_init_cycle(ngx_c
         ngx_destroy_pool(pool);
         return NULL;
     }
+    /* set by pcalloc()
+     *
+     * ccf->pid = NULL;
+     */
     ccf->daemon = -1;
     ((void **)(cycle->conf_ctx))[ngx_core_module.index] = ccf;
 
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -4,6 +4,7 @@
 
 #define  NGINX_VER   "nginx/0.0.1"
 #define  NGINX_CONF  "nginx.conf"
+#define  NGINX_PID   "nginx.pid"
 
 
 extern int           ngx_max_module;
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -39,7 +39,7 @@ typedef int    ngx_int_t;
 typedef u_int  ngx_uint_t;
 
 /* STUB: autoconf */
-#define PTR_FMT  "%X"
+#define PTR_FMT  "%08X"
 
 #include <ngx_auto_config.h>
 
@@ -60,6 +60,8 @@ typedef u_int  ngx_uint_t;
 /* TODO: #ifndef */
 #define NGX_RESTART_SIGNAL    HUP
 #define NGX_ROTATE_SIGNAL     USR1
+#define NGX_SHUTDOWN_SIGNAL   TERM
+#define NGX_INTERRUPT_SIGNAL  INT
 
 #endif
 
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -82,13 +82,6 @@ void ngx_log_error_core(int level, ngx_l
 
     len = ngx_cached_err_log_time.len;
 
-#if 0
-    ngx_localtime(&tm);
-    len = ngx_snprintf(errstr, sizeof(errstr), "%4d/%02d/%02d %02d:%02d:%02d",
-                       tm.ngx_tm_year, tm.ngx_tm_mon, tm.ngx_tm_mday,
-                       tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec);
-#endif
-
     len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1,
                         " [%s] ", err_levels[level]);
 
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -190,6 +190,24 @@ void ngx_assert_core(ngx_log_t *log, con
 #define ngx_log_debug1(level, log, err, fmt, arg1)
 #endif
 
+#if (NGX_DEBUG)
+#define ngx_log_debug2(level, log, err, fmt, arg1, arg2) \
+    if (log->log_level & level) \
+        ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, arg1, arg2)
+#else
+#define ngx_log_debug2(level, log, err, fmt, arg1, arg2)
+#endif
+
+#if (NGX_DEBUG)
+#define ngx_log_debug6(level, log, err, fmt, \
+                       arg1, arg2, arg3, arg4, arg5, arg6) \
+    if (log->log_level & level) \
+        ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, \
+                           arg1, arg2, arg3, arg4, arg5, arg6)
+#else
+#define ngx_log_debug6(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
+#endif
+
 /*********************************/
 
 #else /* NO VARIADIC MACROS */
@@ -209,6 +227,24 @@ void ngx_assert_core(ngx_log_t *log, con
 #else
 #define ngx_log_debug1(level, log, err, fmt, arg1)
 #endif
+
+#if (NGX_DEBUG)
+#define ngx_log_debug2(level, log, err, fmt, arg1, arg2) \
+    if (log->log_level & level) \
+        ngx_log_debug_core(log, err, fmt, arg1, arg2)
+#else
+#define ngx_log_debug2(level, log, err, fmt, arg1, arg2)
+#endif
+
+#if (NGX_DEBUG)
+#define ngx_log_debug6(level, log, err, fmt, \
+                       arg1, arg2, arg3, arg4, arg5, arg6) \
+    if (log->log_level & level) \
+        ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
+#else
+#define ngx_log_debug6(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
+#endif
+
 #endif
 
 
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -419,23 +419,17 @@ static int ngx_kqueue_process_events(ngx
 
     for (i = 0; i < events; i++) {
 
-#if (NGX_DEBUG_EVENT)
-        if (event_list[i].ident > 0x8000000
-            && event_list[i].ident != (unsigned) -1)
-        {
-            ngx_log_debug(log,
-                          "kevent: %08x: ft:%d fl:%08x ff:%08x d:%d ud:%08x" _
-                          event_list[i].ident _ event_list[i].filter _
-                          event_list[i].flags _ event_list[i].fflags _
-                          event_list[i].data _ event_list[i].udata);
-        } else {
-            ngx_log_debug(log,
-                          "kevent: %d: ft:%d fl:%08x ff:%08x d:%d ud:%08x" _
-                          event_list[i].ident _ event_list[i].filter _
-                          event_list[i].flags _ event_list[i].fflags _
-                          event_list[i].data _ event_list[i].udata);
-        }
-#endif
+        ngx_log_debug6(NGX_LOG_DEBUG_EVENT, log, 0,
+
+                       (event_list[i].ident > 0x8000000
+                        && event_list[i].ident != (unsigned) -1) ?
+                        "kevent: " PTR_FMT ": ft:%d fl:%04X ff:%08X d:%d ud:"
+                                                                     PTR_FMT:
+                        "kevent: %d: ft:%d fl:%04X ff:%08X d:%d ud:" PTR_FMT,
+
+                        event_list[i].ident, event_list[i].filter,
+                        event_list[i].flags, event_list[i].fflags,
+                        event_list[i].data, event_list[i].udata);
 
         if (event_list[i].flags & EV_ERROR) {
             ngx_log_error(NGX_LOG_ALERT, log, event_list[i].data,
@@ -453,13 +447,15 @@ static int ngx_kqueue_process_events(ngx
             instance = (uintptr_t) ev & 1;
             ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
 
-            /*
-             * it's a stale event from a file descriptor
-             * that was just closed in this iteration
-             */
+            if (ev->active == 0 || ev->instance != instance) {
 
-            if (ev->active == 0 || ev->instance != instance) {
-                ngx_log_debug(log, "stale kevent");
+                /*
+                 * it's a stale event from a file descriptor
+                 * that was just closed in this iteration
+                 */
+
+                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
+                               "kevent: stale event " PTR_FMT, ev);
                 continue;
             }
 
@@ -511,6 +507,29 @@ static int ngx_kqueue_process_events(ngx
 }
 
 
+static void ngx_kqueue_thread_handler(ngx_event_t *ev, ngx_log_t *log)
+{
+    ngx_int_t  instance;
+
+    instance = (uintptr_t) ev & 1;
+    ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
+
+    if (ev->active && ev->instance == instance) {
+        ev->event_handler(ev);
+        return;
+    }
+
+    /*
+     * it's a stale event from a file descriptor
+     * that was just closed in this iteration
+     */
+
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
+                   "kevent: stale event " PTR_FMT, ev);
+
+}
+
+
 static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle)
 {
     ngx_kqueue_conf_t  *kcf;
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -4,6 +4,12 @@
 #include <ngx_event.h>
 
 
+/*
+ * TODO: in multithreaded enviroment all timer operations must be
+ * protected by the single mutex
+ */
+
+
 ngx_rbtree_t  *ngx_event_timer_rbtree;
 ngx_rbtree_t   ngx_event_timer_sentinel;
 
@@ -39,7 +45,11 @@ ngx_msec_t ngx_event_find_timer(void)
 
     } else {
         return (ngx_msec_t)
+         (node->key * NGX_TIMER_RESOLUTION -
+               ngx_elapsed_msec / NGX_TIMER_RESOLUTION * NGX_TIMER_RESOLUTION);
+#if 0
                          (node->key * NGX_TIMER_RESOLUTION - ngx_elapsed_msec);
+#endif
     }
 }
 
@@ -82,281 +92,3 @@ void ngx_event_expire_timers(ngx_msec_t 
         break;
     }
 }
-
-
-#if 0
-
-/* TODO: in multithreaded enviroment all timer operations must be
-   protected by the single mutex */
-
-
-#if 0
-static ngx_event_t  *ngx_timer_queue, ngx_temp_timer_queue;
-static int           ngx_expire_timers;
-#endif
-
-static ngx_event_t  *ngx_timer_queue;
-static ngx_msec_t   *ngx_timer_delta;
-static int           ngx_timer_cur_queue;
-static int           ngx_timer_queue_num;
-
-
-int ngx_event_timer_init(ngx_cycle_t *cycle)
-{
-    ngx_int_t          i;
-    ngx_msec_t        *new_delta;
-    ngx_event_t       *new_queue;
-    ngx_event_conf_t  *ecf;
-
-    ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
-    if (ngx_timer_queue_num < ecf->timer_queues) {
-        ngx_test_null(new_queue,
-                      ngx_alloc(ecf->timer_queues * sizeof(ngx_event_t),
-                                cycle->log),
-                      NGX_ERROR);
-
-        for (i = 0; i < ngx_timer_queue_num; i++) {
-            new_queue[i] = ngx_timer_queue[i];
-        }
-
-        if (ngx_timer_queue) {
-            ngx_free(ngx_timer_queue);
-        }
-
-        ngx_timer_queue = new_queue;
-
-        ngx_test_null(new_delta,
-                      ngx_calloc(ecf->timer_queues * sizeof(ngx_msec_t),
-                                 cycle->log),
-                      NGX_ERROR);
-
-        for (i = 0; i < ngx_timer_queue_num; i++) {
-            new_delta[i] = ngx_timer_delta[i];
-        }
-
-        if (ngx_timer_delta) {
-            ngx_free(ngx_timer_delta);
-        }
-
-        ngx_timer_delta = new_delta;
-
-        ngx_timer_queue_num = ecf->timer_queues;
-        ngx_timer_cur_queue = 0;
-
-        for (/* void */; i < ngx_timer_queue_num; i++) {
-            ngx_timer_queue[i].timer_prev = &ngx_timer_queue[i];
-            ngx_timer_queue[i].timer_next = &ngx_timer_queue[i];
-        }
-
-    } else if (ngx_timer_queue_num > ecf->timer_queues) {
-        /* STUB */
-        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "NOT READY: timer");
-        exit(1);
-    }
-
-#if 0
-    ngx_temp_timer_queue.timer_prev = &ngx_temp_timer_queue;
-    ngx_temp_timer_queue.timer_next = &ngx_temp_timer_queue;
-#endif
-
-    return NGX_OK;;
-}
-
-
-void ngx_event_timer_done(ngx_cycle_t *cycle)
-{
-    ngx_free(ngx_timer_queue);
-    ngx_timer_queue = NULL;
-
-    ngx_free(ngx_timer_delta);
-    ngx_timer_delta = NULL;
-
-    ngx_timer_queue_num = 0;
-}
-
-
-void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
-{
-    ngx_event_t  *e, *queue;
-#if (NGX_DEBUG_EVENT)
-    ngx_connection_t *c;
-#endif
-
-    if (ev->timer_set) {
-        ngx_del_timer(ev);
-    }
-
-#if (NGX_DEBUG_EVENT)
-    c = ev->data;
-    ngx_log_debug(ev->log, "set timer: %d:%d:%d, slot: %d" _
-                  c->fd _ ev->write _ timer _ ngx_timer_cur_queue);
-#endif
-
-    if (ev->timer_next || ev->timer_prev) {
-        ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "timer already set");
-        return;
-    }
-
-    queue = &ngx_timer_queue[ngx_timer_cur_queue];
-    timer += ngx_timer_delta[ngx_timer_cur_queue++];
-
-    if (ngx_timer_cur_queue >= ngx_timer_queue_num) {
-        ngx_timer_cur_queue = 0;
-    }
-
-
-#if 0
-    if (ngx_expire_timers) {
-        queue = &ngx_temp_timer_queue;
-
-    } else {
-        queue = &ngx_timer_queue[ngx_timer_cur_queue++];
-
-        if (ngx_timer_cur_queue >= ngx_timer_queue_num) {
-            ngx_timer_cur_queue = 0;
-        }
-    }
-#endif
-
-    for (e = queue->timer_next;
-         e != queue && timer > e->timer_delta;
-         e = e->timer_next)
-    {
-        timer -= e->timer_delta;
-    }
-
-    ev->timer_delta = timer;
-
-    ev->timer_next = e;
-    ev->timer_prev = e->timer_prev;
-
-    e->timer_prev->timer_next = ev;
-    e->timer_prev = ev;
-
-    ev->timer_set = 1;
-
-    return;
-}
-
-
-int ngx_event_find_timer(void)
-{
-    ngx_int_t   i;
-    ngx_msec_t  timer;
-
-    timer = NGX_MAX_MSEC;
-
-    for (i = 0; i < ngx_timer_queue_num; i++) {
-        if (ngx_timer_queue[i].timer_next == &ngx_timer_queue[i]) {
-            continue;
-        }
-
-        if (timer > ngx_timer_queue[i].timer_next->timer_delta) {
-            timer = ngx_timer_queue[i].timer_next->timer_delta;
-        }
-    }
-
-    if (timer == NGX_MAX_MSEC) {
-        return 0;
-    }
-
-    return timer;
-}
-
-
-void ngx_event_set_timer_delta(ngx_msec_t timer)
-{
-    ngx_int_t  i;
-
-    for (i = 0; i < ngx_timer_queue_num; i++) {
-        ngx_timer_delta[i] = timer;
-    }
-}
-
-
-/* void ngx_event_expire_timers() */
-void ngx_event_expire_timers(ngx_msec_t timer)
-{
-    ngx_int_t     i;
-#if 0
-    ngx_msec_t    delta;
-#endif
-    ngx_event_t  *ev;
-
-#if 0
-    ngx_expire_timers = 1;
-#endif
-
-    for (i = 0; i < ngx_timer_queue_num; i++) {
-
-#if 0
-        delta = timer;
-#endif
-
-        for ( ;; ) {
-            ev = ngx_timer_queue[i].timer_next;
-
-            if (ev == &ngx_timer_queue[i]) {
-                break;
-            }
-
-            if (ev->timer_delta > ngx_timer_delta[i]) {
-                ev->timer_delta -= ngx_timer_delta[i];
-                break;
-            }
-
-            ngx_timer_delta[i] -= ev->timer_delta;
-
-#if 0
-            if (ev->timer_delta > delta) {
-                ev->timer_delta -= delta;
-                break;
-            }
-
-            delta -= ev->timer_delta;
-#endif
-
-            ngx_del_timer(ev);
-
-            if (ev->delayed) {
-                ev->delayed = 0;
-                if (ev->ready == 0) {
-                    continue;
-                }
-
-            } else {
-                ev->timedout = 1;
-            }
-
-            ev->event_handler(ev);
-        }
-
-        ngx_timer_delta[i] = 0;
-    }
-
-#if 0
-    ngx_expire_timers = 0;
-
-    if (ngx_temp_timer_queue.timer_next == &ngx_temp_timer_queue) {
-        return;
-    }
-
-    timer = 0;
-
-    while (ngx_temp_timer_queue.timer_next != &ngx_temp_timer_queue) {
-        timer += ngx_temp_timer_queue.timer_next->timer_delta;
-        ev = ngx_temp_timer_queue.timer_next;
-
-#if (NGX_DEBUG_EVENT)
-        ngx_log_debug(ev->log, "process temp timer queue");
-#endif
-
-        ngx_del_timer(ev);
-        ngx_add_timer(ev, timer);
-    }
-#endif
-}
-
-
-#endif
--- a/src/event/ngx_event_timer.h
+++ b/src/event/ngx_event_timer.h
@@ -8,7 +8,7 @@
 
 
 /*
- * 32 bit key value resolution
+ * 32 bit timer key value resolution
  *
  * 1 msec - 49 days
  * 10 msec - 1 years 4 months
@@ -28,15 +28,6 @@ int  ngx_event_timer_init(void);
 ngx_msec_t ngx_event_find_timer(void);
 void ngx_event_expire_timers(ngx_msec_t timer);
 
-#if 0
-int  ngx_event_timer_init(ngx_cycle_t *cycle);
-void ngx_event_timer_done(ngx_cycle_t *cycle);
-void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer);
-int  ngx_event_find_timer(void);
-void ngx_event_set_timer_delta(ngx_msec_t timer);
-void ngx_event_expire_timers(ngx_msec_t timer);
-#endif
-
 
 extern ngx_rbtree_t  *ngx_event_timer_rbtree;
 extern ngx_rbtree_t   ngx_event_timer_sentinel;
@@ -59,7 +50,11 @@ ngx_inline static void ngx_event_add_tim
     }
 
     ev->rbtree_key = (ngx_int_t)
+              (ngx_elapsed_msec / NGX_TIMER_RESOLUTION * NGX_TIMER_RESOLUTION
+                                              + timer) / NGX_TIMER_RESOLUTION;
+#if 0
                              (ngx_elapsed_msec + timer) / NGX_TIMER_RESOLUTION;
+#endif
 
     ngx_rbtree_insert(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel,
                       (ngx_rbtree_t *) &ev->rbtree_key);
@@ -68,38 +63,4 @@ ngx_inline static void ngx_event_add_tim
 }
 
 
-#if 0
-
-ngx_inline static void ngx_event_del_timer(ngx_event_t *ev)
-{
-#if (NGX_DEBUG_EVENT)
-    ngx_connection_t *c = ev->data;
-    ngx_log_debug(ev->log, "del timer: %d:%d" _ c->fd _ ev->write);
-#endif
-
-    if (!ev->timer_next || !ev->timer_prev) {
-        ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "timer already deleted");
-        return;
-    }
-
-    if (ev->timer_prev) {
-        ev->timer_prev->timer_next = ev->timer_next;
-    }
-
-    if (ev->timer_next) {
-        ev->timer_next->timer_delta += ev->timer_delta;
-        ev->timer_next->timer_prev = ev->timer_prev;
-        ev->timer_next = NULL;
-    }
-
-    if (ev->timer_prev) {
-        ev->timer_prev = NULL;
-    }
-
-    ev->timer_set = 0;
-}
-
-#endif
-
-
 #endif /* _NGX_EVENT_TIMER_H_INCLUDED_ */
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -407,14 +407,17 @@ int ngx_http_find_location_config(ngx_ht
     clcfp = cscf->locations.elts;
     for (i = 0; i < cscf->locations.nelts; i++) {
 
-#if 1
-ngx_log_debug(r->connection->log, "trans: %s: %d" _
-              clcfp[i]->name.data _ clcfp[i]->exact_match);
-#endif
+#if (HAVE_PCRE)
 
         if (clcfp[i]->regex) {
             break;
         }
+#endif
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "find location: %s\"%s\"",
+                       clcfp[i]->exact_match ? "= " : "",
+                       clcfp[i]->name.data);
 
         if (clcfp[i]->auto_redirect
             && r->uri.len == clcfp[i]->name.len - 1
@@ -449,20 +452,23 @@ ngx_log_debug(r->connection->log, "trans
         }
     }
 
+#if (HAVE_PCRE)
+
     if (!exact && !auto_redirect) {
         /* regex matches */
 
         for (/* void */; i < cscf->locations.nelts; i++) {
 
-#if 1
-ngx_log_debug(r->connection->log, "trans: %s: %d" _
-              clcfp[i]->name.data _ clcfp[i]->exact_match);
-#endif
-
             if (!clcfp[i]->regex) {
                 continue;
             }
 
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "find location: %s\"%s\"",
+                           clcfp[i]->exact_match ? "= " :
+                                 clcfp[i]->regex ? "~ " : "",
+                           clcfp[i]->name.data);
+
             rc = ngx_regex_exec(clcfp[i]->regex, &r->uri);
 
             if (rc == NGX_DECLINED) {
@@ -488,6 +494,8 @@ ngx_log_debug(r->connection->log, "trans
         }
     }
 
+#endif /* HAVE_PCRE */
+
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
     if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) {
@@ -504,10 +512,6 @@ ngx_log_debug(r->connection->log, "trans
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
-#if 0
-        r->headers_out.location->key.len = 8;
-        r->headers_out.location->key.data = "Location";
-#endif
         r->headers_out.location->value = *auto_redirect;
 
         return NGX_HTTP_MOVED_PERMANENTLY;
@@ -614,7 +618,8 @@ int ngx_http_internal_redirect(ngx_http_
 {
     int  i;
 
-    ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri->data);
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "internal redirect: \"%s\"", uri->data);
 
     r->uri.len = uri->len;
     r->uri.data = uri->data;
@@ -798,6 +803,8 @@ static int ngx_cmp_locations(const void 
 
     ngx_int_t  rc;
 
+#if (HAVE_PCRE)
+
     if (first->regex && !second->regex) {
         /* shift regex matches to the end */
         return 1;
@@ -808,6 +815,8 @@ static int ngx_cmp_locations(const void 
         return 0;
     }
 
+#endif
+
     rc = ngx_strcmp(first->name.data, second->name.data);
 
     if (rc == 0 && second->exact_match) {
@@ -876,6 +885,7 @@ static char *ngx_location_block(ngx_conf
                        && value[1].data[0] == '~'
                        && value[1].data[1] == '*'))
         {
+#if (HAVE_PCRE)
             err.len = NGX_MAX_CONF_ERRSTR;
             err.data = errstr;
 
@@ -890,6 +900,13 @@ static char *ngx_location_block(ngx_conf
 
             clcf->name.len = value[2].len;
             clcf->name.data = value[2].data;
+#else
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "the using of the regex \"%s\" "
+                               "requires PCRE library",
+                               value[2].data);
+            return NGX_CONF_ERROR;
+#endif
 
         } else {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -134,7 +134,9 @@ typedef struct {
 
     ngx_http_cache_hash_t  *open_files;
 
+#if (HAVE_PCRE)
     ngx_regex_t  *regex;
+#endif
 
     unsigned      exact_match:1;
     unsigned      auto_redirect:1;
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -340,6 +340,8 @@ static int ngx_http_header_filter(ngx_ht
     /* the end of HTTP header */
     *(h->last++) = CR; *(h->last++) = LF;
 
+    r->header_size = h->last - h->pos;
+
     if (r->header_only) {
         h->type |= NGX_HUNK_LAST;
     }
--- a/src/http/ngx_http_log_handler.c
+++ b/src/http/ngx_http_log_handler.c
@@ -19,6 +19,8 @@ static char *ngx_http_log_status(ngx_htt
                                  uintptr_t data);
 static char *ngx_http_log_length(ngx_http_request_t *r, char *buf,
                                  uintptr_t data);
+static char *ngx_http_log_apache_length(ngx_http_request_t *r, char *buf,
+                                        uintptr_t data);
 static char *ngx_http_log_header_in(ngx_http_request_t *r, char *buf,
                                     uintptr_t data);
 static char *ngx_http_log_connection_header_out(ngx_http_request_t *r,
@@ -97,7 +99,7 @@ static char *months[] = { "Jan", "Feb", 
                           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
 
 static ngx_str_t ngx_http_combined_fmt =
-    ngx_string("%addr - - [%time] \"%request\" %status %length "
+    ngx_string("%addr - - [%time] \"%request\" %status %apache_length "
                "\"%{Referer}i\" %{User-Agent}i\"");
 
 
@@ -110,6 +112,7 @@ ngx_http_log_op_name_t ngx_http_log_fmt_
     { ngx_string("request"), 0, ngx_http_log_request },
     { ngx_string("status"), 3, ngx_http_log_status },
     { ngx_string("length"), NGX_OFF_T_LEN, ngx_http_log_length },
+    { ngx_string("apache_length"), NGX_OFF_T_LEN, ngx_http_log_apache_length },
     { ngx_string("i"), NGX_HTTP_LOG_ARG, ngx_http_log_header_in },
     { ngx_string("o"), NGX_HTTP_LOG_ARG, ngx_http_log_header_out },
     { ngx_null_string, 0, NULL }
@@ -129,7 +132,8 @@ int ngx_http_log_handler(ngx_http_reques
     u_int                     written;
 #endif
 
-    ngx_log_debug(r->connection->log, "log handler");
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http log handler");
 
     lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
 
@@ -248,6 +252,14 @@ static char *ngx_http_log_length(ngx_htt
 }
 
 
+static char *ngx_http_log_apache_length(ngx_http_request_t *r, char *buf,
+                                        uintptr_t data)
+{
+    return buf + ngx_snprintf(buf, NGX_OFF_T_LEN + 1, OFF_T_FMT,
+                              r->connection->sent - r->header_size);
+}
+
+
 static char *ngx_http_log_header_in(ngx_http_request_t *r, char *buf,
                                     uintptr_t data)
 {
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -3,7 +3,7 @@
 #include <ngx_core.h>
 #include <ngx_http.h>
 
-int ngx_http_parse_request_line(ngx_http_request_t *r)
+ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r)
 {
     char   ch, *p;
     enum {
@@ -419,7 +419,7 @@ int ngx_http_parse_request_line(ngx_http
 }
 
 
-int ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h)
+ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h)
 {
     char   c, ch, *p;
     enum {
@@ -621,7 +621,7 @@ int ngx_http_parse_header_line(ngx_http_
 }
 
 
-int ngx_http_parse_complex_uri(ngx_http_request_t *r)
+ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
 {
     char  c, ch, decoded, *p, *u;
     enum {
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -42,10 +42,12 @@ static char *client_header_errors[] = {
 };
 
 
+#if 0
 static void ngx_http_dummy(ngx_event_t *wev)
 {
     return;
 }
+#endif
 
 
 void ngx_http_init_connection(ngx_connection_t *c)
@@ -110,7 +112,7 @@ void ngx_http_init_connection(ngx_connec
 
 static void ngx_http_init_request(ngx_event_t *rev)
 {
-    int                        i;
+    ngx_int_t                  i;
     socklen_t                  len;
     struct sockaddr_in         addr_in;
     ngx_connection_t          *c;
@@ -147,8 +149,6 @@ static void ngx_http_init_request(ngx_ev
     in_port = c->servers;
     in_addr = in_port->addrs.elts;
 
-ngx_log_debug(rev->log, "IN: %08x" _ in_port);
-
     r->port = in_port->port;
     r->port_name = &in_port->port_name;
 
@@ -274,8 +274,8 @@ ngx_log_debug(rev->log, "IN: %08x" _ in_
 
 static void ngx_http_process_request_line(ngx_event_t *rev)
 {
-    int                        rc, offset;
     ssize_t                    n;
+    ngx_int_t                  rc, offset;
     ngx_connection_t          *c;
     ngx_http_request_t        *r;
     ngx_http_log_ctx_t        *ctx;
@@ -439,15 +439,18 @@ static void ngx_http_process_request_lin
             ngx_cpystrn(r->args.data, r->args_start, r->args.len + 1);
         }
 
-#if 1 /* DEBUG */
-        if (r->exten.data == NULL) { r->exten.data = ""; }
-        if (r->args.data == NULL) { r->args.data = ""; }
-        ngx_log_debug(c->log, "HTTP: %d, %d, '%s', '%s', '%s'" _
-                      r->method _ r->http_version _
-                      r->uri.data _ r->exten.data _ r->args.data);
-        if (r->exten.data[0] == '\0') { r->exten.data = NULL; }
-        if (r->args.data[0] == '\0') { r->args.data = NULL; }
-#endif
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http request line: \"%s\"", r->request_line.data);
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http uri: \"%s\"", r->uri.data);
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http args: \"%s\"", r->args.data ? r->args.data : "");
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http exten: \"%s\"",
+                       r->exten.data ? r->exten.data : "");
 
         if (r->http_version < NGX_HTTP_VERSION_10) {
             rev->event_handler = ngx_http_block_read;
@@ -532,8 +535,8 @@ static void ngx_http_process_request_lin
 
 static void ngx_http_process_request_headers(ngx_event_t *rev)
 {
-    int                        rc, i, offset;
     ssize_t                    n;
+    ngx_int_t                  rc, i, offset;
     ngx_table_elt_t           *h;
     ngx_connection_t          *c;
     ngx_http_request_t        *r;
@@ -616,8 +619,9 @@ static void ngx_http_process_request_hea
                 }
             }
 
-            ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
-                          h->key.data _ h->value.data);
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "http header: \"%s: %s\"'",
+                           h->key.data, h->value.data);
 
             if (cscf->large_client_header
                 && r->header_in->pos == r->header_in->last)
@@ -631,7 +635,8 @@ static void ngx_http_process_request_hea
 
             /* a whole header has been parsed successfully */
 
-            ngx_log_debug(r->connection->log, "HTTP header done");
+            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "http header done");
 
             rc = ngx_http_process_request_header(r);
 
@@ -746,10 +751,10 @@ static ssize_t ngx_http_read_request_hea
 }
 
 
-static int ngx_http_process_request_header(ngx_http_request_t *r)
+static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r)
 {
-    int                        i;
     size_t                     len;
+    ngx_int_t                  i;
     ngx_http_server_name_t    *name;
     ngx_http_core_loc_conf_t  *clcf;
 
@@ -828,13 +833,16 @@ static int ngx_http_process_request_head
 
 void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
 {
+    ngx_http_core_loc_conf_t  *clcf;
+
     /* r can be already destroyed when rc == NGX_DONE */
 
     if (rc == NGX_DONE || r->main) {
         return;
     }
 
-    ngx_log_debug(r->connection->log, "finalize http request");
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http finalize request");
 
     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
 
@@ -868,10 +876,12 @@ void ngx_http_finalize_request(ngx_http_
         ngx_del_timer(r->connection->write);
     }
 
-    if (r->keepalive != 0) {
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+    if (r->keepalive != 0 && clcf->keepalive_timeout > 0) {
         ngx_http_set_keepalive(r);
 
-    } else if (r->lingering_close) {
+    } else if (r->lingering_close && clcf->lingering_timeout > 0) {
         ngx_http_set_lingering_close(r);
 
     } else {
@@ -916,7 +926,7 @@ void ngx_http_writer(ngx_event_t *wev)
     ngx_http_request_t        *r;
     ngx_http_core_loc_conf_t  *clcf;
 
-    ngx_log_debug(wev->log, "http writer handler");
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http writer handler");
 
     c = wev->data;
     r = c->data;
@@ -934,7 +944,8 @@ void ngx_http_writer(ngx_event_t *wev)
 
     rc = ngx_http_output_filter(r, NULL);
 
-    ngx_log_debug(c->log, "writer output filter: %d" _ rc);
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                  "http writer output filter: %d", rc);
 
     if (rc == NGX_AGAIN) {
         if (!wev->ready) {
@@ -951,7 +962,7 @@ void ngx_http_writer(ngx_event_t *wev)
         return;
     }
 
-    ngx_log_debug(c->log, "http writer done");
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http writer done");
 
     ngx_http_finalize_request(r, rc);
 }
@@ -962,7 +973,7 @@ static void ngx_http_block_read(ngx_even
     ngx_connection_t          *c;
     ngx_http_request_t        *r;
 
-    ngx_log_debug(rev->log, "http read blocked");
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http read blocked");
 
     /* aio does not call this handler */
 
@@ -986,7 +997,7 @@ int ngx_http_discard_body(ngx_http_reque
 
     rev = r->connection->read;
 
-    ngx_log_debug(rev->log, "set discard body");
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body");
 
     if (rev->timer_set) {
         ngx_del_timer(rev);
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -217,6 +217,8 @@ struct ngx_http_request_s {
 
     ngx_array_t          cleanup;
 
+    size_t               header_size;
+
     char                *discarded_buffer;
     void               **err_ctx;
     int                  err_status;
new file mode 100644
--- /dev/null
+++ b/src/os/unix/ngx_errno.c
@@ -0,0 +1,24 @@
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+ngx_int_t ngx_strerror_r(int err, char *errstr, size_t size)
+{
+    size_t  len;
+
+    if (size == 0) {
+        return 0;
+    }
+
+    errstr[0] = '\0';
+
+    strerror_r(err, errstr, size);
+
+    for (len = 0; len < size; len++) {
+        if (errstr[len] == '\0') {
+            break;
+        }
+    }
+
+    return len;
+}
--- a/src/os/unix/ngx_errno.h
+++ b/src/os/unix/ngx_errno.h
@@ -29,12 +29,17 @@ typedef int               ngx_err_t;
 #define ngx_set_errno(err)         errno = err
 #define ngx_set_socket_errno(err)  errno = err
 
-#if 0
-#define ngx_strerror(err)          strerror(err)
-#endif
+
+#if (HAVE_STRERROR_R)
+
+ngx_int_t ngx_strerror_r(int err, char *errstr, size_t size);
+
+#else
 
 #define ngx_strerror_r(err, errstr, size)  \
              ngx_cpystrn(errstr, strerror(err), size) - (errstr)
 
+#endif
+
 
 #endif /* _NGX_ERRNO_H_INCLUDED_ */
--- a/src/os/unix/ngx_os.h
+++ b/src/os/unix/ngx_os.h
@@ -49,6 +49,7 @@ extern int          ngx_max_sockets;
 extern int          ngx_inherited_nonblocking;
 
 
+extern int          done;
 extern int          restart;
 extern int          rotate;
 
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -7,48 +7,66 @@ int  ngx_max_sockets;
 int  ngx_inherited_nonblocking;
 
 
+void ngx_signal_handler(int signo);
+void ngx_exit_signal_handler(int signo);
 void ngx_restart_signal_handler(int signo);
 void ngx_rotate_signal_handler(int signo);
 
 
+typedef struct {
+     int     signo;
+     char   *signame;
+     char   *action;
+     void  (*handler)(int signo);
+} ngx_signal_t;
+
+
+ngx_signal_t  signals[] = {
+    { ngx_signal_value(NGX_RESTART_SIGNAL),
+      "SIG" ngx_value(NGX_RESTART_SIGNAL),
+      "restarting",
+      ngx_signal_handler },
+
+    { ngx_signal_value(NGX_ROTATE_SIGNAL),
+      "SIG" ngx_value(NGX_ROTATE_SIGNAL),
+      "reopen logs",
+      ngx_signal_handler },
+
+    { ngx_signal_value(NGX_INTERRUPT_SIGNAL),
+      "SIG" ngx_value(NGX_INTERRUPT_SIGNAL),
+      "exiting",
+      ngx_signal_handler },
+
+    { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
+      "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
+      "shutdowning",
+      ngx_signal_handler },
+
+    { SIGCHLD, "SIGCHLD", NULL, ngx_sigchld_handler },
+
+    { SIGPIPE, "SIGPIPE, SIG_IGN", NULL, SIG_IGN },
+
+    { 0, NULL, NULL, NULL }
+};
+
+
 int ngx_posix_init(ngx_log_t *log)
 {
-    struct rlimit     rlmt;
-    struct sigaction  sa;
-
-    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;
-    }
+    ngx_signal_t      *sig;
+    struct rlimit      rlmt;
+    struct sigaction   sa;
 
-    ngx_memzero(&sa, sizeof(struct sigaction));
-    sa.sa_handler = ngx_sigchld_handler;
-    sigemptyset(&sa.sa_mask);
-    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
-        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
-                      "sigaction(SIGCHLD) failed");
-        return NGX_ERROR;
+    for (sig = signals; sig->signo != 0; sig++) {
+        ngx_memzero(&sa, sizeof(struct sigaction));
+        sa.sa_handler = sig->handler;
+        sigemptyset(&sa.sa_mask);
+        if (sigaction(sig->signo, &sa, NULL) == -1) {
+            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+                          "sigaction(%s) failed", sig->signame);
+            return NGX_ERROR;
+        }
     }
 
-    sa.sa_handler = ngx_restart_signal_handler;
-    if (sigaction(ngx_signal_value(NGX_RESTART_SIGNAL), &sa, NULL) == -1) {
-        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
-                      "sigaction(SIG" ngx_value(NGX_RESTART_SIGNAL) ") failed");
-        return NGX_ERROR;
-    }
-
-    sa.sa_handler = ngx_rotate_signal_handler;
-    if (sigaction(ngx_signal_value(NGX_ROTATE_SIGNAL), &sa, NULL) == -1) {
-        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
-                      "sigaction(SIG" ngx_value(NGX_ROTATE_SIGNAL) ") failed");
-        return NGX_ERROR;
-    }
-
-
     if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
         ngx_log_error(NGX_LOG_ALERT, log, errno,
                       "getrlimit(RLIMIT_NOFILE) failed)");
@@ -71,6 +89,56 @@ int ngx_posix_init(ngx_log_t *log)
 }
 
 
+void ngx_signal_handler(int signo)
+{
+    char          *name;
+    ngx_signal_t  *sig;
+
+    for (sig = signals; sig->signo != 0; sig++) {
+        if (sig->signo == signo) {
+            break;
+        }
+    }
+
+    /* STUB */
+    name = strsignal(signo);
+    ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
+                  "signal #%d (%s: %s) received, %s",
+                  signo, sig->signame, name, sig->action);
+
+    switch (signo) {
+
+    /* STUB */
+    case SIGQUIT:
+    case SIGABRT:
+
+    case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
+    case ngx_signal_value(NGX_INTERRUPT_SIGNAL):
+        done = 1;
+        break;
+
+    case ngx_signal_value(NGX_RESTART_SIGNAL):
+        restart = 1;
+        break;
+
+    case ngx_signal_value(NGX_ROTATE_SIGNAL):
+        rotate = 1;
+        break;
+    }
+}
+
+
+void ngx_exit_signal_handler(int signo)
+{
+    char *s;
+
+    s = strsignal(signo);
+    ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
+                  "%s signal received, exiting", s);
+    done = 1;
+}
+
+
 void ngx_restart_signal_handler(int signo)
 {
     restart = 1;
--- a/src/os/win32/ngx_time.c
+++ b/src/os/win32/ngx_time.c
@@ -19,6 +19,8 @@ void ngx_gettimeofday(struct timeval *tp
      * 134744 days,
      * 11644473600 seconds or
      * 11644473600,000,000,0 100-nanosecond intervals.
+     *
+     * See also MSKB Q167296.
      */
 
     intervals = ((uint64_t) ft.dwHighDateTime << 32) | ft.dwLowDateTime;
--- a/src/os/win32/ngx_win32_init.c
+++ b/src/os/win32/ngx_win32_init.c
@@ -52,6 +52,8 @@ int ngx_os_init(ngx_log_t *log)
     }
 
     /*
+     *  Windows 3.1 Win32s   0xxxxx
+     *
      *  Windows 95           140000
      *  Windows 98           141000
      *  Windows ME           149000
@@ -61,6 +63,8 @@ int ngx_os_init(ngx_log_t *log)
      *  Windows 2000         250000
      *  Windows XP           250100
      *  Windows 2003         250200
+     *
+     *  Windows CE x.x       3xxxxx
      */
 
     ngx_win32_version = osvi.dwPlatformId * 100000
@@ -84,7 +88,7 @@ int ngx_os_init(ngx_log_t *log)
 #endif
 
     } else {
-        if (osvi.dwPlatformId == 1) {
+        if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
 
             /* Win9x build */
 
@@ -96,6 +100,14 @@ int ngx_os_init(ngx_log_t *log)
                           osvi.szCSDVersion);
 
         } else {
+
+            /*
+             * VER_PLATFORM_WIN32_NT
+             *
+             * we do not currently support VER_PLATFORM_WIN32_CE
+             * and we do not support VER_PLATFORM_WIN32s at all
+             */
+
             ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %u build:%u, \"%s\"",
                           ngx_win32_version, osvi.dwBuildNumber,
                           osvi.szCSDVersion);