nginx-0.0.1-2003-11-25-23:44:56 import

This commit is contained in:
Igor Sysoev 2003-11-25 20:44:56 +00:00
parent d9d0ca1268
commit a8fa0a6a37
74 changed files with 1933 additions and 914 deletions

109
auto/cc Normal file
View File

@ -0,0 +1,109 @@
case $CC in
*gcc)
# optimization
#CFLAGS="$CFLAGS -O2 -fomit-frame-pointer"
# warnings
CFLAGS="$CFLAGS -O -W"
CFLAGS="$CFLAGS -Wall -Wpointer-arith"
#CFLAGS="$CFLAGS -Wconversion"
#CFLAGS="$CFLAGS -Winline"
# we have a lot of the unused function arguments
CFLAGS="$CFLAGS -Wno-unused"
# stop on warning
CFLAGS="$CFLAGS -Werror"
# ANSI C warnings
#CFLAGS="$CFLAGS -pedantic"
# debug
CFLAGS="$CFLAGS -g"
OBJEXT=o
OBJOUT="-o "
BINOUT="-o "
CC_STRONG="$CC -Wall -Werror"
;;
*icc)
# Intel C++ compiler 7.1
# optimization
CFLAGS="$CFLAGS -O"
# optimize for Pentium Pro, Pentium II and Pentium III
#CFLAGS="$CFLAGS -mcpu=pentiumpro"
# optimize for Pentium 4, default
#CFLAGS="$CFLAGS -mcpu=pentium4"
# warnings
CFLAGS="$CFLAGS -w1"
# stop on warning
CFLAGS="$CFLAGS -Werror"
OBJEXT=o
OBJOUT="-o "
BINOUT="-o "
CC_STRONG="$CC -w1 -Werror"
;;
cl)
# MSVC 6.0 SP2
# optimization
# maximize speed
CFLAGS="$CFLAGS -O2"
# enable global optimization
CFLAGS="$CFLAGS -Og"
# enable intrinsic functions
CFLAGS="$CFLAGS -Oi"
# inline expansion
CFLAGS="$CFLAGS -Ob1"
# enable frame pointer omission
CFLAGS="$CFLAGS -Oy"
# disable stack checking calls
CFLAGS="$CFLAGS -Gs"
# optimize for Pentium Pro
CFLAGS="$CFLAGS -G6"
# warnings
CFLAGS="$CFLAGS -W3"
#CFLAGS="$CFLAGS -W4"
# stop on warning
CFLAGS="$CFLAGS -WX"
# multithreaded
CFLAGS="$CFLAGS -MT"
# disable logo
CFLAGS="$CFLAGS -nologo"
# link flags
CORE_LINK="$CORE_LINK -link"
CORE_LINK="$CORE_LINK -nodefaultlib:msvcrt"
CORE_LINK="$CORE_LINK -nodefaultlib:libcpmt"
CORE_LINK="$CORE_LINK -verbose:lib"
# debug
CFLAGS="$CFLAGS -Yd"
CORE_LINK="$CORE_LINK -debug -debugtype:coff"
OBJEXT=obj
OBJOUT="-Fo"
BINOUT="-Fe"
CC_STRONG="$CC -W3 -WX"
;;
esac

60
auto/configure vendored
View File

@ -1,53 +1,17 @@
CC=cc
CC_STRONG="$CC -Wall -Werror"
CPP="$CC -E"
. auto/options
. auto/init
. auto/sources
NGX_AUTO_CONFIG_H=ngx_auto_config.h
. auto/os/conf
. auto/cc
. auto/lib/lib
. auto/make
. auto/lib/make
echo > $NGX_AUTO_CONFIG_H
CC_WARN=$CC_STRONG
NGX_FMT_NAME=OFF_FMT
NGX_TYPE="off_t"; . auto/types/sizeof
NGX_FORMATS="%ld %lld %qd"; . auto/fmt/fmt
NGX_FMT_NAME=TIME_FMT
NGX_TYPE="time_t"; . auto/types/sizeof
NGX_FORMATS="%d %ld %lld %qd"; . auto/fmt/fmt
CC_WARN=$CC
exit
NGX_TYPE="long"; . auto/types/sizeof; NGX_MAX_LONG=$NGX_MAX_SIZE
NGX_FORMATS="l"; . auto/fmt/fmt
NGX_TYPE="long long"; . auto/types/sizeof; NGX_MAX_LONG_LONG=$NGX_MAX_SIZE
NGX_FORMATS="ll q"; . auto/fmt/fmt
CC_WARN=$CC_STRONG
NGX_TYPE="off_t"; . auto/types/sizeof
NGX_FORMATS="l ll q"; . auto/fmt/fmt
CC_WARN=$CC
#NGX_TYPE="__int64_t"; . auto/types/typedef; NGX_TIME_T_FMT=$NGX_FMT
#NGX_TYPE="time_t"; . auto/types/typedef; NGX_TIME_T_FMT=$NGX_FMT
#exit
. auto/types/uint64_t
. auto/types/uintptr_t
. auto/types/socklen_t
if [ "$PLATFORM" != win32 ]; then
. auto/unix
fi

View File

@ -1,22 +1,27 @@
echo "Checking for $NGX_TYPE printf() format"
echo "checking for $NGX_TYPE printf() format"
NGX_FMT=NO
for FMT in $NGX_FORMATS
do
echo "#include <unistd.h>" > autotest.c
echo "#include <stdio.h>" >> autotest.c
echo "#include <sys/types.h>" >> autotest.c
echo "int main() {" >> autotest.c
echo "printf(\"${FMT}\", ($NGX_TYPE) $NGX_MAX_SIZE);" >> autotest.c
echo "return 0; }" >> autotest.c
eval "${CC_WARN} -o autotest autotest.c > /dev/null 2>&1"
eval "$CC_WARN $CC_TEST_FLAGS -o autotest autotest.c > /dev/null 2>&1"
MAX_SIZE=`echo $NGX_MAX_SIZE | sed -e "s/L*\$//"`
if [ -x ./autotest ]; then
if [ "`./autotest`" = $NGX_MAX_SIZE ]; then
echo " + \"${FMT}\" used"
if [ "`./autotest`" = $MAX_SIZE ]; then
if [ $NGX_FMT_COLLECT = YES ]; then
echo " + \"${FMT}\" is appropriate"
else
echo " + \"${FMT}\" used"
fi
NGX_FMT=$FMT
fi
fi
@ -24,7 +29,12 @@ do
rm autotest*
if [ $NGX_FMT != NO ]; then
break
if [ $NGX_FMT_COLLECT = YES ]; then
eval "NGX_${NGX_BYTES}_FMT=\"\${NGX_${NGX_BYTES}_FMT} \$NGX_FMT\""
continue
else
break
fi
fi
echo " + \"${FMT}\" is not appropriate"
@ -32,12 +42,14 @@ done
if [ $NGX_FMT = NO ]; then
echo "printf() $NGX_TYPE format not found"
echo "$0: error: printf() $NGX_TYPE format not found"
exit 1
fi
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
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
fi

View File

@ -1,45 +0,0 @@
echo "Checking for printf() long long format"
NGX_LONG_LONG_FMT=NO
echo "int main() {" > autotest.c
echo "printf(\"%llu\", (unsigned long long) -1);" >> autotest.c
echo "return 0; }" >> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
if [ -x ./autotest -a "`./autotest`" = $NGX_MAX_LONG_LONG ]; then
echo " + \"%ll\" used"
NGX_LONG_LONG_FMT="ll"
else
echo " + \"%ll\" is not appropriate"
fi
rm autotest*
if [ $NGX_LONG_LONG_FMT = NO ]; then
echo "int main() {" > autotest.c
echo "printf(\"%qu\", (unsigned long long) -1);" >> autotest.c
echo "return 0; }" >> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
if [ -x ./autotest -a "`./autotest`" = $NGX_MAX_LONG_LONG ]; then
echo " + \"%q\" used"
NGX_LONG_LONG_FMT="q"
else
echo " + \"%q\" is not appropriate"
fi
rm autotest*
fi
if [ $NGX_LONG_LONG_FMT = NO ]; then
echo "printf() long long format not found"
exit 1
fi

21
auto/func Normal file
View File

@ -0,0 +1,21 @@
echo "checking for $NGX_FUNC"
echo "$NGX_UNISTD_H" > autotest.c
echo "$NGX_FUNC_INC" >> autotest.c
echo "int main() { $NGX_FUNC_TEST; return 0; }" >> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
if [ -x autotest ]; then
echo " + $NGX_FUNC found"
echo "#ifndef $NGX_HAVE" >> $NGX_AUTO_CONFIG_H
echo "#define $NGX_HAVE 1" >> $NGX_AUTO_CONFIG_H
echo "#endif" >> $NGX_AUTO_CONFIG_H
echo >> $NGX_AUTO_CONFIG_H
else
echo " + $NGX_FUNC not found"
fi
rm autotest*

9
auto/init Normal file
View File

@ -0,0 +1,9 @@
MAKEFILE=$OBJS/Makefile
NGX_AUTO_CONFIG_H=$OBJS/ngx_auto_config.h
NGX_MODULES_C=$OBJS/ngx_modules.c
NGX_UNISTD_H="#include <unistd.h>"
NGX_INTTYPES_H="#include <inttypes.h>"

48
auto/lib/lib Normal file
View File

@ -0,0 +1,48 @@
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

26
auto/lib/make Normal file
View File

@ -0,0 +1,26 @@
if [ "$PLATFORM" != "win32" ]; then
if [ $PCRE != NO ]; then
echo "$PCRE/.libs/libpcre.a:" >> $MAKEFILE
echo " cd $PCRE \\" >> $MAKEFILE
echo " && ./configure --disable-shared \\" >> $MAKEFILE
echo " && \$(MAKE)" >> $MAKEFILE
echo >> $MAKEFILE
fi
if [ $MD5 != NO ]; then
echo "$MD5/libmd5.a:" >> $MAKEFILE
echo " cd $MD5 && \$(MAKE) x86-elf" >> $MAKEFILE
echo >> $MAKEFILE
fi
if [ $ZLIB != NO ]; then
echo "$ZLIB/libz.a:" >> $MAKEFILE
echo " cd $ZLIB && ./configure && \$(MAKE)" >> $MAKEFILE
echo >> $MAKEFILE
fi
fi

View File

@ -0,0 +1,4 @@
all:
cl -nologo -c -MT -O2 -D MD5_ASM -D L_ENDIAN md5_dgst.c md5_one.c
link -lib -out:md5.lib md5_dgst.obj md5_one.obj asm/m-win32.obj

View File

@ -0,0 +1,18 @@
CC = cl
CFLAGS = -O2 -Ob1 -Oi -Gs -MT
LINK = link
PCREFLAGS = -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10
all:
$(CC) -Fedftables dftables.c
dftables > chartables.c
$(CC) -nologo -c $(CFLAGS) $(PCREFLAGS) \
maketables.c get.c study.c pcre.c
$(LINK) -lib -out:pcre.lib -verbose:lib \
maketables.obj get.obj study.obj pcre.obj

19
auto/lib/zlib/patch.zlib Normal file
View File

@ -0,0 +1,19 @@
--- msdos/Makefile.w32 Sat Nov 15 13:01:29 2003
+++ msdos/Makefile.w32 Sat Nov 15 13:02:06 2003
@@ -10,7 +10,7 @@
# ------------- Microsoft Visual C++ 4.0 and later -------------
MODEL=
-CFLAGS=-Ox -GA3s -nologo -W3
+CFLAGS=-nologo -O2 -Ob1 -Oi -Gs -MT
CC=cl
LD=link
LDFLAGS=
@@ -79,7 +79,6 @@
$(CC) -c $(CFLAGS) $*.c
zlib.lib: $(OBJ1) $(OBJ2)
- if exist zlib.lib del zlib.lib
lib /OUT:zlib.lib $(OBJ1) $(OBJ2)
example.exe: example.obj zlib.lib

146
auto/make Normal file
View File

@ -0,0 +1,146 @@
mkdir -p $OBJS/src/core $OBJS/src/event $OBJS/src/event/modules \
$OBJS/src/os/unix $OBJS/src/os/win32 \
$OBJS/src/http $OBJS/src/http/modules $OBJS/src/http/modules/proxy
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES \
$HTTP_CHUNKED_FILTER_MODULE \
$HTTP_RANGE_FILTER_MODULE \
$HTTP_CHARSET_FILTER_MODULE"
HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE $HTTP_INDEX_MODULE"
if [ $HTTP_GZIP = YES ]; then
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GZIP_FILTER_MODULE"
HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS"
fi
if [ $HTTP_PROXY = YES ]; then
HTTP_MODULES="$HTTP_MODULES $HTTP_PROXY_MODULE"
HTTP_INCS="$HTTP_INCS $HTTP_PROXY_INCS"
HTTP_DEPS="$HTTP_DEPS $HTTP_PROXY_DEPS"
HTTP_SRCS="$HTTP_SRCS $HTTP_PROXY_SRCS"
fi
modules="$CORE_MODULES $EVENT_MODULES $HTTP_MODULES \
$HTTP_FILTER_MODULES $HTTP_NOT_MODIFIED_FILTER_MODULE"
echo "#include <ngx_config.h>" > $NGX_MODULES_C
echo "#include <ngx_core.h>" >> $NGX_MODULES_C
echo >> $NGX_MODULES_C
for mod in $modules
do
echo "extern ngx_module_t $mod;" >> $NGX_MODULES_C
done
echo >> $NGX_MODULES_C
echo 'ngx_module_t *ngx_modules[] = {' >> $NGX_MODULES_C
for mod in $modules
do
echo " &$mod," >> $NGX_MODULES_C
done
echo " NULL" >> $NGX_MODULES_C
echo "};" >> $NGX_MODULES_C
echo "CC = $CC" > $MAKEFILE
echo "CFLAGS = $CFLAGS" >> $MAKEFILE
echo >> $MAKEFILE
echo "CORE_DEPS = \\" >> $MAKEFILE
for dep in $CORE_DEPS
do
echo " $dep \\" >> $MAKEFILE
done
echo >> $MAKEFILE
echo "CORE_INCS = $CORE_INCS -I $OBJS" >> $MAKEFILE
echo >> $MAKEFILE
echo "HTTP_DEPS = \\" >> $MAKEFILE
for inc in $HTTP_DEPS
do
echo " $inc \\" >> $MAKEFILE
done
echo >> $MAKEFILE
echo "HTTP_INCS = $HTTP_INCS" >> $MAKEFILE
echo >> $MAKEFILE
echo "nginx: \\" >> $MAKEFILE
for src in $CORE_SRCS $HTTP_SRCS
do
obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
echo " $OBJS/$obj \\" >> $MAKEFILE
done
for src in $NGX_MODULES_C $LINK_DEPS
do
obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
echo " $obj \\" >> $MAKEFILE
done
echo >> $MAKEFILE
echo " \$(CC) ${BINOUT}nginx \\" >> $MAKEFILE
for src in $CORE_SRCS $HTTP_SRCS
do
obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
echo " $OBJS/$obj \\" >> $MAKEFILE
done
obj=`echo $NGX_MODULES_C | sed -e "s/\.c\$/.$OBJEXT/"`
echo " $obj \\" >> $MAKEFILE
echo " $CORE_LIBS \\" >> $MAKEFILE
echo " $CORE_LINK" >> $MAKEFILE
echo >> $MAKEFILE
deps="\$(CORE_DEPS)"
args="\$(CFLAGS) \$(CORE_INCS)"
echo "$obj: \\" >> $MAKEFILE
echo " $NGX_MODULES_C $deps" >> $MAKEFILE
echo " \$(CC) -c $args \\" >> $MAKEFILE
echo " $OBJOUT$obj \\" >> $MAKEFILE
echo " $NGX_MODULES_C" >> $MAKEFILE
echo >> $MAKEFILE
for src in $CORE_SRCS
do
obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
echo "$OBJS/$obj: \\" >> $MAKEFILE
echo " $src $deps" >> $MAKEFILE
echo " \$(CC) -c $args \\" >> $MAKEFILE
echo " $OBJOUT$OBJS/$obj \\" >> $MAKEFILE
echo " $src" >> $MAKEFILE
echo >> $MAKEFILE
done
deps="\$(CORE_DEPS) \$(HTTP_DEPS)"
args="\$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)"
for src in $HTTP_SRCS
do
obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
echo "$OBJS/$obj: \\" >> $MAKEFILE
echo " $src $deps" >> $MAKEFILE
echo " \$(CC) -c $args \\" >> $MAKEFILE
echo " $OBJOUT$OBJS/$obj \\" >> $MAKEFILE
echo " $src" >> $MAKEFILE
echo >> $MAKEFILE
done

68
auto/options Normal file
View File

@ -0,0 +1,68 @@
HELP=NO
CC=gcc
OBJS=objs
TEST_BUILD_DEVPOLL=NO
HTTP_GZIP=YES
HTTP_PROXY=YES
PCRE=NO
MD5=NO
MD5_LIB=NO
ZLIB=NO
ZLIB_LIB=NO
for option
do
case "$option" in
-*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
*) value="" ;;
esac
case "$option" in
--help) HELP=YES ;;
--crossbuild=*) PLATFORM="$value" ;;
--builddir=*) OBJS="$value" ;;
--without-http_gzip_module) HTTP_GZIP=NO ;;
--without-http_proxy_module) HTTP_PROXY=NO ;;
--with-cc=*) CC="$value" ;;
--with-pcre=*) PCRE="$value" ;;
--with-md5=*) MD5="$value" ;;
--with-zlib=*) ZLIB="$value" ;;
--test-build-devpoll) TEST_BUILD_DEVPOLL=YES ;;
*)
echo "$0: error: invalid option \"$option\""
exit 1
;;
esac
done
if [ $HELP = YES ]; then
echo " --help this message"
echo " --without-http_gzip_module disable http_gzip_module"
echo " --without-http_proxy_module disable http_proxy_module"
echo " --with-cc=NAME name of or path to C compiler"
echo
echo " --with-pcre=DIR path to PCRE library"
echo " --with-md5=DIR path to md5 library"
echo " --with-zlib=DIR path to zlib library"
exit 1
fi

47
auto/os/conf Normal file
View File

@ -0,0 +1,47 @@
if [ ".$PLATFORM" = "." ]; then
echo "checking for OS"
SYSTEM=`uname -s 2>/dev/null`
RELEASE=`uname -r 2>/dev/null`
MACHINE=`uname -m 2>/dev/null`
echo " + $SYSTEM $RELEASE $MACHINE"
PLATFORM="$SYSTEM:$RELEASE:$MACHINE";
else
echo "building for $PLATFORM"
fi
case $PLATFORM in
FreeBSD:*)
. auto/os/freebsd
;;
Solaris:*)
CC_TEST_FLAGS="-D_FILE_OFFSET_BITS=64"
CORE_LIBS="$CORE_LIBS -lsocket -lnsl"
;;
Linux:*)
CC_TEST_FLAGS="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE"
;;
win32)
CORE_INCS="$WIN32_INCS"
CORE_DEPS="$WIN32_DEPS"
CORE_SRCS="$WIN32_SRCS $SELECT_SRCS $IOCP_SRCS"
EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE $IOCP_MODULE"
CFLAGS="$CFLAGS -D HAVE_AIO=1 -D HAVE_IOCP=1"
CORE_LIBS="$CORE_LIBS ws2_32.lib"
;;
esac
if [ $TEST_BUILD_DEVPOLL = YES ]; then
EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
EVENT_SRCS="$EVENT_SRCS $DEVPOLL_SRCS"
fi

40
auto/os/freebsd Normal file
View File

@ -0,0 +1,40 @@
CORE_INCS="$UNIX_INCS"
CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS $SELECT_SRCS $POLL_SRCS"
EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE $POLL_MODULE"
MD5_LIB="-lmd"
ZLIB_LIB="-lz"
version=`grep "#define __FreeBSD_version" /usr/include/osreldate.h \
| sed -e 's/^.* \(.*\)$/\1/'`
# sendfile
if [ $version -gt 300007 ]; then
CFLAGS="$CFLAGS -D HAVE_SENDFILE=1"
CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
fi
# kqueue
if [ \( $version -lt 500000 -a $version -ge 410000 \) \
-o $version -ge 500011 ]
then
CFLAGS="$CFLAGS -D HAVE_KQUEUE=1"
CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
fi
# kqueue's NOTE_LAWAT
if [ \( $version -lt 500000 -a $version -ge 430000 \) \
-o $version -ge 500018 ]
then
CFLAGS="$CFLAGS -D HAVE_LOWAT_EVENT=1"
fi

194
auto/sources Normal file
View File

@ -0,0 +1,194 @@
CORE_MODULES="ngx_core_module ngx_errlog_module"
CORE_INCS="-I src/core"
CORE_DEPS="src/core/nginx.h \
src/core/ngx_config.h \
src/core/ngx_log.h \
src/core/ngx_alloc.h \
src/core/ngx_array.h \
src/core/ngx_table.h \
src/core/ngx_hunk.h \
src/core/ngx_string.h \
src/core/ngx_parse.h \
src/core/ngx_inet.h \
src/core/ngx_file.h \
src/core/ngx_regex.h \
src/core/ngx_times.h \
src/core/ngx_connection.h \
src/core/ngx_conf_file.h \
src/core/ngx_garbage_collector.h"
CORE_SRCS="src/core/nginx.c \
src/core/ngx_log.c \
src/core/ngx_alloc.c \
src/core/ngx_array.c \
src/core/ngx_hunk.c \
src/core/ngx_output_chain.c \
src/core/ngx_string.c \
src/core/ngx_parse.c \
src/core/ngx_inet.c \
src/core/ngx_file.c \
src/core/ngx_regex.c \
src/core/ngx_times.c \
src/core/ngx_conf_file.c \
src/core/ngx_garbage_collector.c"
EVENT_MODULES="ngx_events_module ngx_event_core_module"
EVENT_INCS="-I src/event -I src/event/modules"
EVENT_DEPS="src/event/ngx_event.h \
src/event/ngx_event_timer.h \
src/event/ngx_event_connect.h \
src/event/ngx_event_pipe.h"
EVENT_SRCS="src/event/ngx_event.c \
src/event/ngx_event_timer.c \
src/event/ngx_event_close.c \
src/event/ngx_event_accept.c \
src/event/ngx_event_connect.c \
src/event/ngx_event_pipe.c"
SELECT_MODULE="ngx_select_module"
SELECT_SRCS=src/event/modules/ngx_select_module.c
POLL_MODULE="ngx_poll_module"
POLL_SRCS=src/event/modules/ngx_poll_module.c
KQUEUE_MODULE="ngx_kqueue_module"
KQUEUE_SRCS=src/event/modules/ngx_kqueue_module.c
DEVPOLL_MODULE="ngx_devpoll_module"
DEVPOLL_SRCS=src/event/modules/ngx_devpoll_module.c
IOCP_MODULE="ngx_iocp_module"
IOCP_SRCS=src/event/modules/ngx_iocp_module.c
AIO_MODULE="ngx_aio_module"
AIO_SRCS=src/event/modules/ngx_aio_module.c
UNIX_INCS="$CORE_INCS $EVENT_INCS -I src/os/unix"
UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \
src/os/unix/ngx_time.h \
src/os/unix/ngx_types.h \
src/os/unix/ngx_errno.h \
src/os/unix/ngx_files.h \
src/os/unix/ngx_process.h \
src/os/unix/ngx_socket.h \
src/os/unix/ngx_os.h"
UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \
src/os/unix/ngx_time.c \
src/os/unix/ngx_sendv.c \
src/os/unix/ngx_files.c \
src/os/unix/ngx_socket.c \
src/os/unix/ngx_recv.c \
src/os/unix/ngx_readv_chain.c \
src/os/unix/ngx_writev_chain.c \
src/os/unix/ngx_posix_init.c \
src/os/unix/ngx_process.c \
src/os/unix/ngx_daemon.c"
LINUX_SENDFILE_SRCS=src/os/unix/ngx_linux_sendfile_chain.c
FREEBSD_DEPS=src/os/unix/ngx_freebsd_config.h
FREEBSD_SRCS=src/os/unix/ngx_freebsd_init.c
FREEBSD_SENDFILE_SRCS=src/os/unix/ngx_freebsd_sendfile_chain.c
WIN32_INCS="$CORE_INCS $EVENT_INCS -I src/os/win32"
WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \
src/os/win32/ngx_win32_config.h \
src/os/win32/ngx_time.h \
src/os/win32/ngx_types.h \
src/os/win32/ngx_errno.h \
src/os/win32/ngx_files.h \
src/os/win32/ngx_process.h \
src/os/win32/ngx_socket.h \
src/os/win32/ngx_os.h"
WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \
src/os/win32/ngx_errno.c \
src/os/win32/ngx_files.c \
src/os/win32/ngx_time.c \
src/os/win32/ngx_socket.c \
src/os/win32/ngx_wsarecv.c \
src/os/win32/ngx_wsarecv_chain.c \
src/os/win32/ngx_wsasend_chain.c \
src/os/win32/ngx_sendv.c \
src/os/win32/ngx_win32_init.c \
src/event/ngx_event_acceptex.c"
HTTP_MODULES="ngx_http_module \
ngx_http_core_module \
ngx_http_log_module \
ngx_http_cache_module"
HTTP_FILTER_MODULES="ngx_http_write_filter_module \
ngx_http_output_filter_module \
ngx_http_header_filter_module"
HTTP_CHUNKED_FILTER_MODULE=ngx_http_chunked_filter_module
HTTP_RANGE_FILTER_MODULE=ngx_http_range_filter_module
HTTP_CHARSET_FILTER_MODULE=ngx_http_charset_filter_module
HTTP_NOT_MODIFIED_FILTER_MODULE=ngx_http_not_modified_filter_module
HTTP_STATIC_MODULE=ngx_http_static_module
HTTP_INDEX_MODULE=ngx_http_index_module
HTTP_INCS="-I src/http -I src/http/modules"
HTTP_DEPS="src/http/ngx_http.h \
src/http/ngx_http_request.h \
src/http/ngx_http_filter.h \
src/http/ngx_http_config.h \
src/http/ngx_http_core_module.h \
src/http/ngx_http_cache.h \
src/http/ngx_http_busy_lock.h \
src/http/ngx_http_log_handler.h"
HTTP_SRCS="src/http/ngx_http.c \
src/http/ngx_http_core_module.c \
src/http/ngx_http_special_response.c \
src/http/ngx_http_request.c \
src/http/ngx_http_cache.c \
src/http/ngx_http_busy_lock.c \
src/http/ngx_http_parse.c \
src/http/ngx_http_headers.c \
src/http/ngx_http_header_filter.c \
src/http/ngx_http_write_filter.c \
src/http/ngx_http_output_filter.c \
src/http/ngx_http_log_handler.c \
src/http/ngx_http_request_body.c \
src/http/ngx_http_parse_time.c \
src/http/modules/ngx_http_static_handler.c \
src/http/modules/ngx_http_index_handler.c \
src/http/modules/ngx_http_chunked_filter.c \
src/http/modules/ngx_http_range_filter.c \
src/http/modules/ngx_http_charset_filter.c \
src/http/modules/ngx_http_not_modified_filter.c"
HTTP_GZIP_FILTER_MODULE=ngx_http_gzip_filter_module
HTTP_GZIP_SRCS=src/http/modules/ngx_http_gzip_filter.c
HTTP_GZIP_UNIX_LIBS=-lz
HTTP_GZIP_WIN_LIBS=zlib.lib
HTTP_PROXY_MODULE=ngx_http_proxy_module
HTTP_PROXY_INCS="-I src/http/modules/proxy"
HTTP_PROXY_DEPS=src/http/modules/proxy/ngx_http_proxy_handler.h
HTTP_PROXY_SRCS="src/http/modules/proxy/ngx_http_proxy_handler.c \
src/http/modules/proxy/ngx_http_proxy_upstream.c \
src/http/modules/proxy/ngx_http_proxy_cache.c \
src/http/modules/proxy/ngx_http_proxy_parse.c \
src/http/modules/proxy/ngx_http_proxy_header.c"

View File

@ -1,31 +0,0 @@
echo "Checking for long long size"
BYTES=
echo "int main() {" > autotest.c
echo "printf(\"%d\", sizeof(long long));" >> autotest.c
echo "return 0; }" >> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
if [ -x ./autotest ]; then
BYTES=`./autotest`
echo " + long long is $BYTES bytes"
fi
rm autotest*
case $BYTES in
4)
NGX_MAX_LONG_LONG=4294967295
;;
8)
NGX_MAX_LONG_LONG=18446744073709551615
;;
*)
echo "$0: error: can not detect long long size"
exit 1
esac

View File

@ -1,29 +1,37 @@
echo "Checking for $NGX_TYPE size"
echo "checking for $NGX_TYPE size"
BYTES=
NGX_BYTES=
echo "#include <sys/types.h>" > autotest.c
echo "int main() {" >> autotest.c
echo "printf(\"%d\", sizeof($NGX_TYPE));" >> autotest.c
echo "return 0; }" >> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
eval "$CC $CC_TEST_FLAGS -o autotest autotest.c > /dev/null 2>&1"
if [ -x ./autotest ]; then
BYTES=`./autotest`
echo " + $NGX_TYPE is $BYTES bytes"
NGX_BYTES=`./autotest`
echo " + $NGX_TYPE is $NGX_BYTES bytes"
fi
rm autotest*
case $BYTES in
case $NGX_BYTES in
4)
NGX_MAX_SIZE=2147483647
if [ "$NGX_TYPE"="long" ]; then
NGX_MAX_SIZE=2147483647L
else
NGX_MAX_SIZE=2147483647
fi
;;
8)
NGX_MAX_SIZE=9223372036854775807
if [ "$NGX_TYPE"="long long" ]; then
NGX_MAX_SIZE=9223372036854775807LL
else
NGX_MAX_SIZE=9223372036854775807L
fi
;;
*)

View File

@ -1,28 +0,0 @@
found=0
echo 'Checking for socklen_t'
echo '#include <sys/types.h>' > autotest.c
echo '#include <sys/socket.h>' >> autotest.c
echo 'int main() { socklen_t i = 0; return 0; }' >> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
if [ -x autotest ]; then
echo ' + socklen_t found'
found=1
else
echo ' + socklen_t not found'
echo ' + uint32_t used'
type='typedef uint32_t socklen_t;'
found=2
fi
rm autotest*
if [ $found = 2 ]; then
echo $type >> ngx_auto_config.h
echo >> ngx_auto_config.h
fi

View File

@ -1,30 +0,0 @@
echo "Checking for printf() time_t format"
echo '#include <sys/types.h>' > autotest.c
type=`${CPP} autotest.c | awk '/^typedef.*time_t/ {print \$2}'`
rm autotest.c
case $type in
long)
echo ' + long: "%ld" used'
fmt='"%ld"'
;;
int)
echo ' + int: "%d" used'
fmt='"%d"'
;;
*)
echo "$0: error: unknown time_t definition: \"$type\""
exit 1
;;
esac
echo "#ifndef TIME_FMT" >> ngx_auto_config.h
echo "#define TIME_FMT $fmt" >> ngx_auto_config.h
echo "#endif" >> ngx_auto_config.h
echo >> ngx_auto_config.h

View File

@ -1,32 +1,42 @@
echo "Checking for $NGX_TYPE definition"
echo "checking for $NGX_TYPE"
echo "#include <sys/types.h>" > autotest.c
TYPE=`${CPP} autotest.c | \
awk "/^typedef.*$NGX_TYPE/ { for (i = 1; i< NF; i++) print $i}"`
#rm autotest.c
FOUND=NO
echo $TYPE
for TYPE in $NGX_TYPE $NGX_TYPES
do
echo "#include <sys/types.h>" > autotest.c
echo "#include <sys/socket.h>" >> autotest.c
echo "$NGX_INTTYPES_H" >> autotest.c
echo "int main() { $TYPE i = 0; return 0; }" >> autotest.c
case $TYPE in
"long long")
echo ' + defined as long long'
NGX_FMT=$NGX_LONG_LONG_FMT
;;
eval "$CC -o autotest autotest.c > /dev/null 2>&1"
long)
echo ' + defined as long'
NGX_FMT=$NGX_LONG_FMT
;;
if [ -x autotest ]; then
if [ $TYPE = $NGX_TYPE ]; then
echo " + $NGX_TYPE found"
FOUND=YES
else
echo " + $TYPE used"
FOUND=$TYPE
fi
fi
int)
echo ' + defined as int'
NGX_FMT=$NGX_INT_FMT
;;
rm autotest*
*)
echo "$0: error: unknown $NGX_TYPE definition: \"$TYPE\""
exit 1
;;
if [ $FOUND = NO ]; then
echo " + $TYPE not found"
else
break
fi
done
esac
if [ $FOUND = NO ]; then
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
fi

View File

@ -1,50 +0,0 @@
found=0
echo 'Checking for uint64_t'
echo '#include <sys/types.h>' > autotest.c
echo 'int main() { uint64_t i = 0; return 0; }' >> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
if [ -x autotest ]; then
echo ' + uint64_t found'
found=1
else
echo ' + uint64_t not found'
fi
rm autotest*
if [ $found = 0 ]; then
echo '#include <sys/types.h>' > autotest.c
echo 'int main() { u_int64_t i = 0; return 0; }' >> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
if [ -x autotest ]; then
echo ' + u_int64_t used'
type='typedef u_int64_t uint64_t;'
found=2
else
echo ' + u_int64_t not found'
fi
rm autotest*
fi
if [ $found = 0 ]; then
echo "$0: error: uint64_t not found"
exit 1
fi
if [ $found = 2 ]; then
echo $type >> ngx_auto_config.h
echo >> ngx_auto_config.h
fi

View File

@ -1,47 +1,26 @@
found=0
echo 'checking for uintptr_t'
echo 'Checking for uintptr_t'
FOUND=NO
echo '#include <sys/types.h>' > autotest.c
echo 'int main() { uintptr_t i = 0; return i; }' >> autotest.c
echo "#include <sys/types.h>" > autotest.c
echo "int main() { uintptr_t i = 0; return 0; }" >> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
eval "$CC -o autotest autotest.c > /dev/null 2>&1"
if [ -x autotest ]; then
echo ' + uintptr_t found'
found=1
else
echo ' + uintptr_t not found'
fi
rm autotest*
if [ $found = 0 ]; then
echo 'int main() { printf("%d", 8 * sizeof(void *)); return 0; }' \
> autotest.c
eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
if [ -x autotest ]; then
type="uint`./autotest`_t"
echo " + $type used"
type="typedef $type uintptr_t;"
found=2
fi
rm autotest*
if [ -x autotest ]; then
echo " + uintptr_t found"
FOUND=YES
else
echo " + uintptr_t not found"
fi
rm autotest*
if [ $found = 0 ]; then
echo "$0: error: uintptr_t not found"
exit 1
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
fi
if [ $found = 2 ]; then
echo $type >> ngx_auto_config.h
echo >> ngx_auto_config.h
fi

70
auto/unix Executable file
View File

@ -0,0 +1,70 @@
CC_WARN=$CC
NGX_FMT_COLLECT=YES
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 long"; . auto/types/sizeof;
NGX_FORMATS="%lld %qd"; . auto/fmt/fmt
NGX_TYPE="void *"; . auto/types/sizeof; NGX_PTR_BYTES=$NGX_BYTES
CC_WARN=$CC_STRONG
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=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_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=RLIM_T_FMT
NGX_TYPE="rlim_t"; . auto/types/sizeof
eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
CC_WARN=$CC
NGX_TYPE="uint64_t"
NGX_TYPES="u_int64_t"; . auto/types/typedef
NGX_TYPE="socklen_t"
NGX_TYPES="u_int32_t"; . auto/types/typedef
. auto/types/uintptr_t
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_HAVE=HAVE_PREAD; NGX_FUNC="pread()"; . 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_HAVE=HAVE_PWRITE; NGX_FUNC="pwrite()"; . auto/func
NGX_FUNC_INC="#include <time.h>"
NGX_FUNC_TEST="struct tm t; time_t c=0; localtime_r(&c, &t)"
NGX_HAVE=HAVE_LOCALTIME_R; NGX_FUNC="localtime_r()"; . auto/func

View File

@ -59,6 +59,7 @@ ngx_array_t ngx_old_cycles;
static ngx_pool_t *ngx_temp_pool;
static ngx_event_t ngx_cleaner_event;
/* STUB NAME */
static ngx_connection_t dumb;
@ -91,7 +92,8 @@ int main(int argc, char *const *argv)
/* TODO */ ngx_max_sockets = -1;
ngx_init_time();
ngx_time_init();
ngx_regex_init();
log = ngx_log_init_errlog();

View File

@ -7,9 +7,9 @@
/*
* NGX_MAX_ALLOC_FROM_POOL should be (PAGE_SIZE - 1), i.e. 4095 on x86.
* NGX_MAX_ALLOC_FROM_POOL should be (NGX_PAGE_SIZE - 1), i.e. 4095 on x86.
* On FreeBSD 5.x it allows to use zero copy send.
* On Windows NT it decreases number of locked pages in kernel.
* On Windows NT it decreases a number of locked pages in a kernel.
*/
#define NGX_MAX_ALLOC_FROM_POOL 4095

View File

@ -3,9 +3,6 @@
#include <ngx_core.h>
#define MAX_CONF_ERRSTR 256
/* Ten fixed arguments */
static int argument_number[] = {
@ -471,7 +468,29 @@ ngx_log_debug(cf->log, "%d:%d:%d:%d:%d '%c'" _
len++)
{
if (*src == '\\') {
src++;
switch (src[1]) {
case '"':
case '\'':
case '\\':
src++;
break;
case 't':
*dst++ = '\t';
src += 2;
continue;
case 'r':
*dst++ = '\r';
src += 2;
continue;
case 'n':
*dst++ = '\n';
src += 2;
continue;
}
}
*dst++ = *src++;
}
@ -525,7 +544,7 @@ void ngx_conf_log_error(int level, ngx_conf_t *cf, ngx_err_t err,
char *fmt, ...)
{
int len;
char errstr[MAX_CONF_ERRSTR];
char errstr[NGX_MAX_CONF_ERRSTR];
va_list args;
va_start(args, fmt);

View File

@ -56,6 +56,9 @@
#define NGX_CONF_MODULE 0x464E4F43 /* "CONF" */
#define NGX_MAX_CONF_ERRSTR 256
struct ngx_command_s {
ngx_str_t name;
int type;

View File

@ -2,9 +2,6 @@
#define _NGX_CONFIG_H_INCLUDED_
#include <ngx_auto_config.h>
#if defined __FreeBSD__
#include <ngx_freebsd_config.h>
@ -32,6 +29,13 @@
#endif
/* STUB: autoconf */
typedef int ngx_int_t;
typedef u_int ngx_uint_t;
#include <ngx_auto_config.h>
#ifndef NGX_SERVER_ROOT
#define NGX_SERVER_ROOT "./"
#if 0

View File

@ -28,6 +28,7 @@ typedef struct ngx_connection_s ngx_connection_t;
#include <ngx_types.h>
#include <ngx_file.h>
#include <ngx_files.h>
#include <ngx_regex.h>
#include <ngx_times.h>
#include <ngx_inet.h>
#include <ngx_conf_file.h>

View File

@ -70,7 +70,10 @@ int ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
#endif
#endif
#if 0
file->fd = ngx_open_tempfile(file->name.data, persistent);
#endif
file->fd = ngx_open_tempfile(file->name.data, 1);
ngx_log_debug(file->log, "temp fd: %d" _ file->fd);
@ -225,14 +228,15 @@ char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return "invalid value";
}
path->len += path->level[i] + level + 1;
path->level[i] = level;
path->len += level + 1;
}
while (i < 3) {
path->level[i++] = 0;
}
path->gc_handler = cmd->post;
path->gc_handler = (ngx_gc_handler_pt) cmd->post;
return NGX_CONF_OK;
}

View File

@ -89,7 +89,7 @@ void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err,
/* pid#tid */
len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1,
PID_FMT "#%d: ", ngx_getpid(), 0);
PID_T_FMT "#%d: ", ngx_getpid(), 0);
if (log->data) {
len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1,

View File

@ -28,6 +28,7 @@ extern ngx_module_t ngx_aio_module;
extern ngx_module_t ngx_http_module;
extern ngx_module_t ngx_http_core_module;
extern ngx_module_t ngx_http_log_module;
extern ngx_module_t ngx_http_cache_module;
extern ngx_module_t ngx_http_write_filter_module;
extern ngx_module_t ngx_http_output_filter_module;
@ -78,6 +79,8 @@ ngx_module_t *ngx_modules[] = {
&ngx_http_core_module,
&ngx_http_log_module,
&ngx_http_cache_module,
&ngx_http_write_filter_module,
&ngx_http_output_filter_module,
&ngx_http_header_filter_module,

71
src/core/ngx_regex.c Normal file
View File

@ -0,0 +1,71 @@
#include <ngx_config.h>
#include <ngx_core.h>
static void *ngx_regex_malloc(size_t size);
static void ngx_regex_free(void *p);
/* THREADS: this pool should be private for each thread */
static ngx_pool_t *ngx_pcre_pool;
void ngx_regex_init()
{
pcre_malloc = ngx_regex_malloc;
pcre_free = ngx_regex_free;
}
ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options,
ngx_pool_t *pool, ngx_str_t *err)
{
int erroff;
const char *errstr;
ngx_regex_t *re;
ngx_pcre_pool = pool;
re = pcre_compile(pattern->data, (int) options, &errstr, &erroff, NULL);
if (re == NULL) {
if ((size_t) erroff == pattern->len) {
ngx_snprintf(err->data, err->len - 1,
"pcre_compile() failed: %s in \"%s\"",
errstr, pattern->data);
} else {
ngx_snprintf(err->data, err->len - 1,
"pcre_compile() failed: %s in \"%s\" at \"%s\"",
errstr, pattern->data, pattern->data + erroff);
}
}
return re;
}
ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s)
{
int rc;
rc = pcre_exec(re, NULL, s->data, s->len, 0, 0, NULL, 0);
if (rc == -1) {
return NGX_DECLINED;
}
return rc;
}
static void *ngx_regex_malloc(size_t size)
{
return ngx_palloc(ngx_pcre_pool, size);
}
static void ngx_regex_free(void *p)
{
return;
}

23
src/core/ngx_regex.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _NGX_REGEX_H_INCLUDED_
#define _NGX_REGEX_H_INCLUDED_
#include <ngx_config.h>
#include <ngx_core.h>
#include <pcre.h>
#define NGX_REGEX_CASELESS PCRE_CASELESS
typedef pcre ngx_regex_t;
void ngx_regex_init();
ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options,
ngx_pool_t *pool, ngx_str_t *err);
ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s);
#define ngx_regex_exec_n "pcre_exec()"
#endif /* _NGX_REGEX_H_INCLUDED_ */

View File

@ -22,7 +22,7 @@ static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
void ngx_init_time()
void ngx_time_init()
{
struct timeval tv;

View File

@ -6,7 +6,7 @@
#include <ngx_core.h>
void ngx_init_time();
void ngx_time_init();
void ngx_time_update();
size_t ngx_http_time(char *buf, time_t t);
void ngx_gmtime(time_t t, ngx_tm_t *tp);

View File

@ -190,6 +190,7 @@ static void ngx_kqueue_done(ngx_cycle_t *cycle)
static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
{
ngx_event_t *e;
ngx_connection_t *c;
ev->active = 1;
@ -200,6 +201,28 @@ static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
&& ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
== (uintptr_t) ev)
{
if (change_list[ev->index].flags == EV_DISABLE) {
#if (NGX_DEBUG_EVENT)
ngx_connection_t *c = (ngx_connection_t *) ev->data;
ngx_log_debug(ev->log, "kqueue event activated: %d: ft:%d" _
c->fd _ event);
#endif
/*
* if the EV_DISABLE is still not passed to a kernel
* we will not pass it
*/
if (ev->index < (u_int) --nchanges) {
e = (ngx_event_t *) change_list[nchanges].udata;
change_list[ev->index] = change_list[nchanges];
e->index = ev->index;
}
return NGX_OK;
}
c = ev->data;
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
"previous event on #%d were not passed in kernel", c->fd);
@ -207,7 +230,7 @@ static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
return NGX_ERROR;
}
return ngx_kqueue_set_event(ev, event, EV_ADD|flags);
return ngx_kqueue_set_event(ev, event, EV_ADD|EV_ENABLE|flags);
}
@ -286,23 +309,26 @@ static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
change_list[nchanges].flags = flags;
change_list[nchanges].udata = (void *) ((uintptr_t) ev | ev->instance);
#if (HAVE_LOWAT_EVENT)
if (flags & NGX_LOWAT_EVENT) {
change_list[nchanges].fflags = NOTE_LOWAT;
change_list[nchanges].data = ev->available;
if (filter == EVFILT_VNODE) {
change_list[nchanges].fflags = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND
|NOTE_ATTRIB|NOTE_RENAME|NOTE_REVOKE;
change_list[nchanges].data = 0;
} else {
#if (HAVE_LOWAT_EVENT)
if (flags & NGX_LOWAT_EVENT) {
change_list[nchanges].fflags = NOTE_LOWAT;
change_list[nchanges].data = ev->available;
} else {
change_list[nchanges].fflags = 0;
change_list[nchanges].data = 0;
}
#else
change_list[nchanges].fflags = 0;
change_list[nchanges].data = 0;
}
#else
change_list[nchanges].fflags = 0;
change_list[nchanges].data = 0;
#endif
}
ev->index = nchanges;
@ -365,12 +391,16 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ (int) delta);
#endif
#if 0
/*
* The expired timers must be handled before a processing of the events
* because the new timers can be added during a processing
*/
ngx_event_expire_timers((ngx_msec_t) delta);
#endif
ngx_event_set_timer_delta((ngx_msec_t) delta);
} else {
if (events == 0) {
@ -452,6 +482,13 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
break;
case EVFILT_VNODE:
ev->kq_vnode = 1;
ev->event_handler(ev);
break;
case EVFILT_AIO:
ev->complete = 1;
ev->ready = 1;
@ -463,10 +500,15 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
default:
ngx_log_error(NGX_LOG_ALERT, log, 0,
"unexpected kevent filter %d" _ event_list[i].filter);
"unexpected kevent() filter %d",
event_list[i].filter);
}
}
if (timer) {
ngx_event_expire_timers((ngx_msec_t) delta);
}
return NGX_OK;
}

View File

@ -107,6 +107,8 @@ struct ngx_event_s {
#endif
#if (HAVE_KQUEUE)
unsigned kq_vnode:1;
/* the pending errno reported by kqueue */
int kq_errno;
#endif
@ -212,7 +214,7 @@ extern ngx_event_actions_t ngx_event_actions;
/*
* Need to add socket or handle only once - i/o completion port.
* It also requires HAVE_AIO_EVENT and NGX_HAVE_AIO_EVENT to be set.
* It also requires HAVE_AIO and NGX_USE_AIO_EVENT to be set.
*/
#define NGX_USE_IOCP_EVENT 0x00000100
@ -233,6 +235,7 @@ extern ngx_event_actions_t ngx_event_actions;
/* these flags have a meaning only for kqueue */
#define NGX_LOWAT_EVENT 0
#define NGX_DISABLE_EVENT 0
#define NGX_VNODE_EVENT 0
#if (HAVE_KQUEUE)
@ -240,6 +243,9 @@ extern ngx_event_actions_t ngx_event_actions;
#define NGX_READ_EVENT EVFILT_READ
#define NGX_WRITE_EVENT EVFILT_WRITE
#undef NGX_VNODE_EVENT
#define NGX_VNODE_EVENT EVFILT_VNODE
/*
* NGX_CLOSE_EVENT and NGX_LOWAT_EVENT are the module flags and they would
* not go into a kernel so we need to choose the value that would not interfere
@ -289,7 +295,7 @@ extern ngx_event_actions_t ngx_event_actions;
#endif /* HAVE_KQUEUE */
#if (HAVE_IOCP_EVENT)
#if (HAVE_IOCP)
#define NGX_IOCP_ACCEPT 0
#define NGX_IOCP_IO 1
#define NGX_IOCP_CONNECT 2
@ -444,7 +450,8 @@ ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, u_int flags)
if (!wev->active && !wev->ready) {
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT|flags)
== NGX_ERROR) {
== NGX_ERROR)
{
return NGX_ERROR;
}
}
@ -457,7 +464,8 @@ ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, u_int flags)
if (!wev->active && !wev->ready) {
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
== NGX_ERROR) {
== NGX_ERROR)
{
return NGX_ERROR;
}
@ -484,7 +492,8 @@ ngx_inline static int ngx_handle_level_write_event(ngx_event_t *wev)
if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
if (!wev->active && !wev->ready) {
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
== NGX_ERROR) {
== NGX_ERROR)
{
return NGX_ERROR;
}

View File

@ -11,7 +11,7 @@
typedef struct {
u_int32_t addr;
in_addr_t addr;
ngx_str_t host;
int port;
ngx_str_t addr_port_text;

View File

@ -8,15 +8,21 @@
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;
static int ngx_expire_timers;
int ngx_event_timer_init(ngx_cycle_t *cycle)
{
int i;
ngx_int_t i;
ngx_msec_t *new_delta;
ngx_event_t *new_queue;
ngx_event_conf_t *ecf;
@ -38,6 +44,21 @@ int ngx_event_timer_init(ngx_cycle_t *cycle)
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;
@ -52,8 +73,10 @@ int ngx_event_timer_init(ngx_cycle_t *cycle)
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;;
}
@ -63,6 +86,10 @@ 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;
}
@ -89,6 +116,15 @@ void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
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;
@ -99,6 +135,7 @@ void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
ngx_timer_cur_queue = 0;
}
}
#endif
for (e = queue->timer_next;
e != queue && timer > e->timer_delta;
@ -123,7 +160,7 @@ void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
int ngx_event_find_timer(void)
{
int i;
ngx_int_t i;
ngx_msec_t timer;
timer = NGX_MAX_MSEC;
@ -146,17 +183,34 @@ int ngx_event_find_timer(void)
}
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)
{
int i;
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;
@ -165,12 +219,21 @@ void ngx_event_expire_timers(ngx_msec_t timer)
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);
@ -186,8 +249,11 @@ void ngx_event_expire_timers(ngx_msec_t timer)
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) {
@ -207,4 +273,5 @@ void ngx_event_expire_timers(ngx_msec_t timer)
ngx_del_timer(ev);
ngx_add_timer(ev, timer);
}
#endif
}

View File

@ -11,6 +11,7 @@ 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);

View File

@ -1,203 +0,0 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_types.h>
#include <ngx_alloc.h>
#include <ngx_array.h>
#include <ngx_hunk.h>
#include <ngx_connection.h>
#include <ngx_sendv.h>
#include <ngx_sendfile.h>
#include <ngx_event_write.h>
ngx_chain_t *ngx_event_write(ngx_connection_t *c, ngx_chain_t *in, off_t flush)
{
int rc, i, last;
u_int flags;
char *prev;
off_t sent;
ngx_iovec_t *iov;
ngx_array_t *header, *trailer;
ngx_hunk_t *file;
ngx_chain_t *ch;
ch = in;
file = NULL;
last = 0;
ngx_test_null(header, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)),
(ngx_chain_t *) -1);
ngx_test_null(trailer, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)),
(ngx_chain_t *) -1);
do {
header->nelts = 0;
trailer->nelts = 0;
if (ch->hunk->type & NGX_HUNK_IN_MEMORY) {
prev = NULL;
iov = NULL;
while (ch && (ch->hunk->type & NGX_HUNK_IN_MEMORY))
{
if (prev == ch->hunk->pos.mem) {
iov->ngx_iov_len += ch->hunk->last.mem - ch->hunk->pos.mem;
} else {
ngx_test_null(iov, ngx_push_array(header),
(ngx_chain_t *) -1);
iov->ngx_iov_base = ch->hunk->pos.mem;
iov->ngx_iov_len = ch->hunk->last.mem - ch->hunk->pos.mem;
prev = ch->hunk->last.mem;
}
if (ch->hunk->type & NGX_HUNK_LAST) {
last = 1;
}
ch = ch->next;
}
}
if (ch && (ch->hunk->type & NGX_HUNK_FILE)) {
file = ch->hunk;
ch = ch->next;
if (ch->hunk->type & NGX_HUNK_LAST) {
last = 1;
}
}
#if (HAVE_MAX_SENDFILE_IOVEC)
if (file && header->nelts > HAVE_MAX_SENDFILE_IOVEC) {
rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts, header->nelts,
&sent);
} else {
#endif
if (ch && ch->hunk->type & NGX_HUNK_IN_MEMORY) {
prev = NULL;
iov = NULL;
while (ch && (ch->hunk->type & NGX_HUNK_IN_MEMORY)) {
if (prev == ch->hunk->pos.mem) {
iov->ngx_iov_len +=
ch->hunk->last.mem - ch->hunk->pos.mem;
} else {
ngx_test_null(iov, ngx_push_array(trailer),
(ngx_chain_t *) -1);
iov->ngx_iov_base = ch->hunk->pos.mem;
iov->ngx_iov_len =
ch->hunk->last.mem - ch->hunk->pos.mem;
prev = ch->hunk->last.mem;
}
if (ch->hunk->type & NGX_HUNK_LAST) {
last = 1;
}
ch = ch->next;
}
}
if (file) {
flags = ngx_sendfile_flags;
#if (HAVE_SENDFILE_DISCONNECT)
if (last && c->close) {
flags |= HAVE_SENDFILE_DISCONNECT;
}
#endif
rc = ngx_sendfile(c,
(ngx_iovec_t *) header->elts, header->nelts,
file->file->fd, file->pos.file,
(size_t) (file->last.file - file->pos.file),
(ngx_iovec_t *) trailer->elts, trailer->nelts,
&sent, flags);
#if (HAVE_AIO_EVENT) && !(HAVE_IOCP_EVENT)
} else if (ngx_event_flags & NGX_HAVE_AIO_EVENT) {
sent = 0;
rc = NGX_AGAIN;
iov = (ngx_iovec_t *) header->elts;
for (i = 0; i < header->nelts; i++) {
rc = ngx_event_aio_write(c, iov[i].ngx_iov_base,
iov[i].ngx_iov_len);
if (rc > 0) {
sent += rc;
} else {
break;
}
if (rc < (int) iov->ngx_iov_len) {
break;
}
}
#endif
} else {
rc = ngx_sendv(c, (ngx_iovec_t *) header->elts, header->nelts);
sent = rc > 0 ? rc: 0;
#if (NGX_DEBUG_EVENT_WRITE)
ngx_log_debug(c->log, "sendv: " OFF_FMT _ sent);
#endif
}
#if (HAVE_MAX_SENDFILE_IOVEC)
}
#endif
if (rc == NGX_ERROR)
return (ngx_chain_t *) NGX_ERROR;
c->sent += sent;
flush -= sent;
for (ch = in; ch; ch = ch->next) {
#if (NGX_DEBUG_EVENT_WRITE)
ngx_log_debug(c->log, "event write: %x " QX_FMT " " OFF_FMT _
ch->hunk->type _
ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
#endif
if (sent >= ch->hunk->last.file - ch->hunk->pos.file) {
sent -= ch->hunk->last.file - ch->hunk->pos.file;
ch->hunk->pos.file = ch->hunk->last.file;
#if (NGX_DEBUG_EVENT_WRITE)
ngx_log_debug(c->log, "event write: " QX_FMT " 0 " OFF_FMT _
ch->hunk->pos.file _ sent);
#endif
/*
if (ch->hunk->type & NGX_HUNK_LAST)
break;
*/
continue;
}
ch->hunk->pos.file += sent;
#if (NGX_DEBUG_EVENT_WRITE)
ngx_log_debug(c->log, "event write: " QX_FMT " " OFF_FMT _
ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
#endif
break;
}
/* flush hunks if threaded state */
} while (c->write->context && flush > 0);
ngx_destroy_array(trailer);
ngx_destroy_array(header);
return ch;
}

View File

@ -1,13 +0,0 @@
#ifndef _NGX_EVENT_WRITE_H_INCLUDED_
#define _NGX_EVENT_WRITE_H_INCLUDED_
#include <ngx_types.h>
#include <ngx_hunk.h>
#include <ngx_connection.h>
ngx_chain_t *ngx_event_write(ngx_connection_t *cn, ngx_chain_t *in,
off_t flush);
#endif /* _NGX_EVENT_WRITE_H_INCLUDED_ */

View File

@ -32,7 +32,7 @@ ssize_t ngx_event_wsarecv(ngx_connection_t *c, char *buf, size_t size)
if (ev->ready) {
ev->ready = 0;
#if (HAVE_IOCP_EVENT) /* iocp */
#if (HAVE_IOCP) /* iocp */
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
if (ev->ovlp.error) {
@ -85,7 +85,7 @@ ssize_t ngx_event_wsarecv(ngx_connection_t *c, char *buf, size_t size)
}
}
#if (HAVE_IOCP_EVENT) /* iocp */
#if (HAVE_IOCP) /* iocp */
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
return NGX_AGAIN;

View File

@ -87,7 +87,7 @@ static int ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
ngx_test_null(chunk, ngx_palloc(r->pool, 11), NGX_ERROR);
len = ngx_snprintf(chunk, 11, SIZEX_FMT CRLF, size);
len = ngx_snprintf(chunk, 11, SIZE_T_X_FMT CRLF, size);
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;

View File

@ -58,11 +58,13 @@ static int ngx_http_not_modified_header_filter(ngx_http_request_t *r)
if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
r->headers_out.content_length_n = -1;
r->headers_out.content_length = NULL;
r->headers_out.content_type->key.len = 0;
r->headers_out.content_type = NULL;
r->headers_out.content_length_n = -1;
r->headers_out.content_length = NULL;
#if 0
r->headers_out.accept_ranges->key.len = 0;
#endif
}
return ngx_http_next_header_filter(r);

View File

@ -215,7 +215,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
r->headers_out.content_range->value.len =
ngx_snprintf(r->headers_out.content_range->value.data,
8 + 20 + 1, "bytes */" OFF_FMT,
8 + 20 + 1, "bytes */" OFF_T_FMT,
r->headers_out.content_length_n);
r->headers_out.content_length_n = -1;
@ -247,11 +247,11 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
/* "Content-Range: bytes SSSS-EEEE/TTTT" header */
r->headers_out.content_range->value.len =
ngx_snprintf(r->headers_out.content_range->value.data,
6 + 20 + 1 + 20 + 1 + 20 + 1,
"bytes " OFF_FMT "-" OFF_FMT "/" OFF_FMT,
range->start, range->end - 1,
r->headers_out.content_length_n);
ngx_snprintf(r->headers_out.content_range->value.data,
6 + 20 + 1 + 20 + 1 + 20 + 1,
"bytes " OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT,
range->start, range->end - 1,
r->headers_out.content_length_n);
r->headers_out.content_length_n = range->end - range->start;
@ -336,11 +336,11 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
/* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */
range[i].content_range.len =
ngx_snprintf(range[i].content_range.data,
20 + 1 + 20 + 1 + 20 + 5,
OFF_FMT "-" OFF_FMT "/" OFF_FMT CRLF CRLF,
range[i].start, range[i].end - 1,
r->headers_out.content_length_n);
ngx_snprintf(range[i].content_range.data,
20 + 1 + 20 + 1 + 20 + 5,
OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT CRLF CRLF,
range[i].start, range[i].end - 1,
r->headers_out.content_length_n);
len += ctx->boundary_header.len + range[i].content_range.len
+ (size_t) (range[i].end - range[i].start);

View File

@ -44,6 +44,8 @@ int ngx_http_static_translate_handler(ngx_http_request_t *r)
int rc, level;
char *location, *last;
ngx_err_t err;
ngx_http_cache_ctx_t ctx;
ngx_http_cache_conf_t *ccf;
ngx_http_core_loc_conf_t *clcf;
if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
@ -73,7 +75,7 @@ int ngx_http_static_translate_handler(ngx_http_request_t *r)
return NGX_HTTP_FORBIDDEN;
}
/* "+ 2" is for trailing '/' in redirect and '\0' */
/* "+ 2" is for trailing '/' in possible redirect and '\0' */
ngx_test_null(r->file.name.data,
ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2),
NGX_HTTP_INTERNAL_SERVER_ERROR);
@ -85,6 +87,38 @@ int ngx_http_static_translate_handler(ngx_http_request_t *r)
ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
/* STUB */
ccf = NULL;
ctx.key.len = 0;
#if 0
ccf = ngx_http_get_module_loc_conf(r, ngx_http_cache_module);
if (ccf->open_files) {
ctx->hash = ccf->open_files;
ctx->key = r->file.name;
cache = ngx_http_cache_get_data(r, ctx);
if (cache
&& ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
|| ccf->hash->life_time >= ngx_time() - cache->updated))
{
cache->refs++;
r->file.fd = cache->fd;
r->file.name = cache->key;
r->content_handler = ngx_http_static_handler;
return NGX_OK;
}
} else {
cache = NULL;
}
#endif
#if (WIN9X)
if (ngx_win32_version < NGX_WIN_NT) {

View File

@ -86,6 +86,7 @@ static int ngx_http_proxy_process_cached_response(ngx_http_proxy_ctx_t *p,
}
if (rc == NGX_HTTP_CACHE_STALE || rc == NGX_HTTP_CACHE_AGED) {
p->state->expired = ngx_time() - p->cache->ctx.expires;
p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) {
@ -487,6 +488,8 @@ int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p)
out[i].hunk->type |= NGX_HUNK_LAST;
}
r->file.fd = p->cache->ctx.file.fd;
return ngx_http_output_filter(r, out);
}
@ -600,7 +603,7 @@ int ngx_http_proxy_update_cache(ngx_http_proxy_ctx_t *p)
ep = p->upstream->event_pipe;
ngx_log_debug(p->request->connection->log, "LEN: " OFF_FMT ", " OFF_FMT _
ngx_log_debug(p->request->connection->log, "LEN: " OFF_T_FMT ", " OFF_T_FMT _
p->cache->ctx.length _ ep->read_length);
if (p->cache->ctx.length == -1) {

View File

@ -485,6 +485,10 @@ ngx_log_debug(r->connection->log, "CACHE FD: %d" _ p->cache->ctx.file.fd);
r->file.fd = p->cache->ctx.file.fd;
}
if (rc == 0 && r->main == NULL) {
rc = ngx_http_send_last(r);
}
ngx_http_finalize_request(r, rc);
}
@ -586,15 +590,25 @@ static char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, char *buf,
*buf++ = '/';
*buf++ = '_';
if (p->state->expired == 0) {
*buf++ = '-';
} else {
buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expired);
}
*buf++ = '/';
*buf++ = '_';
if (p->state->bl_time == 0) {
*buf++ = '-';
} else {
buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->bl_time);
}
*buf++ = '/';
*buf++ = '_';
*buf++ = '*';
*buf++ = ' ';
@ -617,15 +631,15 @@ static char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, char *buf,
*buf++ = '/';
if (p->state->reason >= NGX_HTTP_PROXY_CACHE_XAE) {
if (p->state->reason < NGX_HTTP_PROXY_CACHE_XAE) {
*buf++ = '-';
} else {
buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_FMT, p->state->expires);
buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expires);
}
*buf++ = ' ';
*buf++ = '_';
*buf++ = '*';
return buf;
}
@ -833,9 +847,9 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
int i, len;
char *err, *host;
in_addr_t addr;
ngx_str_t *value;
struct hostent *h;
u_int32_t addr;
ngx_http_conf_ctx_t *ctx;
ngx_http_core_loc_conf_t *clcf;
@ -869,6 +883,8 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
NGX_CONF_ERROR);
ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1);
/* AF_INET only */
addr = inet_addr(host);
if (addr == INADDR_NONE) {
@ -894,7 +910,7 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
for (i = 0; h->h_addr_list[i] != NULL; i++) {
lcf->peers->peers[i].host.data = host;
lcf->peers->peers[i].host.len = lcf->upstream->host.len;
lcf->peers->peers[i].addr = *(u_int32_t *)(h->h_addr_list[i]);
lcf->peers->peers[i].addr = *(in_addr_t *)(h->h_addr_list[i]);
lcf->peers->peers[i].port = lcf->upstream->port;
len = INET_ADDRSTRLEN + lcf->upstream->port_text.len + 1;

View File

@ -1017,8 +1017,7 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
ep->hunk_to_file->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
if (ngx_event_flags & NGX_USE_AIO_EVENT) {
/* the posted aio operation can currupt shadow buf */
/* the posted aio operation can currupt a shadow buffer */
ep->single_buf = 1;
}
@ -1126,26 +1125,38 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev)
}
if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) {
ngx_log_debug(ev->log, "http proxy upstream exit");
ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock);
ngx_http_proxy_close_connection(p);
ngx_http_proxy_finalize_request(p, 0);
return;
}
}
if (ep->downstream_error) {
ngx_log_debug(ev->log, "http proxy downstream error");
if (!p->cachable && p->upstream->peer.connection) {
ngx_http_proxy_finalize_request(p, 0);
}
}
#if 0
if (ep->downstream_done) {
ngx_log_debug(ev->log, "http proxy downstream done");
ngx_http_proxy_finalize_request(p, r->main ? 0 : ngx_http_send_last(r));
ngx_http_proxy_finalize_request(p, 0);
return;
}
if (ep->downstream_error) {
ngx_log_debug(ev->log, "http proxy downstream error");
if (!p->cachable && p->upstream->peer.connection) {
ngx_http_proxy_close_connection(p);
}
if (p->upstream->peer.connection == NULL) {
ngx_http_close_connection(r->connection);
ngx_http_close_request(r);
}
}
#endif
}

View File

@ -205,7 +205,7 @@ char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd,
dup = 0;
invalid = 0;
value = (ngx_str_t *) cf->args->elts;
value = cf->args->elts;
for (i = 1; i < cf->args->nelts; i++) {

View File

@ -13,11 +13,45 @@
#endif
static int ngx_crc(char *data, size_t len);
static void *ngx_http_cache_create_conf(ngx_conf_t *cf);
static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
static ngx_http_module_t ngx_http_cache_module_ctx = {
NULL, /* pre conf */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
ngx_http_cache_create_conf, /* create location configuration */
ngx_http_core_merge_loc_conf /* merge location configuration */
};
ngx_module_t ngx_http_cache_module = {
NGX_MODULE,
&ngx_http_cache_module_ctx, /* module context */
NULL, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init module */
NULL /* init child */
};
int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
{
MD5_CTX md5;
ctx->header_size = sizeof(ngx_http_cache_header_t) + ctx->key.len + 1;
/* we use offsetof() because sizeof() pads struct size to int size */
ctx->header_size = offsetof(ngx_http_cache_header_t, key)
+ ctx->key.len + 1;
ctx->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32;
if (!(ctx->file.name.data = ngx_palloc(r->pool, ctx->file.name.len + 1))) {
@ -46,7 +80,83 @@ ngx_log_debug(r->connection->log, "FILE: %s" _ ctx->file.name.data);
}
/* TODO: Win32 inode analogy */
int ngx_http_cache_get_data(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
{
ngx_uint_t n, i;
ctx->crc = ngx_crc(ctx->key.data, ctx->key.len);
n = ctx->crc % ctx->hash->hash;
for (i = 0; i < ctx->hash->nelts; i++) {
if (ctx->hash->cache[n][i].crc == ctx->crc
&& ctx->hash->cache[n][i].key.len == ctx->key.len
&& ngx_rstrncmp(ctx->hash->cache[n][i].key.data, ctx->key.data,
ctx->key.len) == 0)
{
ctx->cache = ctx->hash->cache[n][i].data;
ctx->hash->cache[n][i].refs++;
return NGX_OK;
}
}
return NGX_DECLINED;
}
ngx_http_cache_entry_t *ngx_http_cache_get_entry(ngx_http_request_t *r,
ngx_http_cache_ctx_t *ctx)
{
time_t old;
ngx_uint_t n, i;
ngx_http_cache_entry_t *ce;
old = ngx_time() + 1;
ce = NULL;
n = ctx->crc % ctx->hash->hash;
for (i = 0; i < ctx->hash->nelts; i++) {
if (ctx->hash->cache[n][i].key.data == NULL) {
/* a free entry is found */
ce = &ctx->hash->cache[n][i];
break;
}
if (ctx->hash->cache[n][i].refs == 0
&& old > ctx->hash->cache[n][i].accessed)
{
/* looking for the oldest cache entry that is not used right now */
old = ctx->hash->cache[n][i].accessed;
ce = &ctx->hash->cache[n][i];
}
}
if (ce) {
if (ce->key.data) {
if (ctx->key.len > ce->key.len) {
ngx_free(ce->key.data);
ce->key.data = NULL;
}
}
if (ce->key.data) {
ce->key.data = ngx_alloc(ctx->key.len, r->connection->log);
if (ce->key.data == NULL) {
return NULL;
}
}
ngx_memcpy(ce->key.data, ctx->key.data, ctx->key.len);
ce->key.len = ctx->key.len;
ce->crc = ctx->crc;
}
return ce;
}
int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq)
{
@ -138,6 +248,48 @@ ngx_log_debug(ctx->log, "EXPIRED");
}
int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx,
ngx_str_t *temp_file)
{
int retry;
ngx_err_t err;
retry = 0;
for ( ;; ) {
if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) {
return NGX_OK;
}
err = ngx_errno;
#if (WIN32)
if (err == NGX_EEXIST) {
if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool)
== NGX_ERROR)
{
return NGX_ERROR;
}
}
#endif
if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
ngx_rename_file_n "(\"%s\", \"%s\") failed",
temp_file->data, ctx->file.name.data);
return NGX_ERROR;
}
if (ngx_create_path(&ctx->file, ctx->path) == NGX_ERROR) {
return NGX_ERROR;
}
retry = 1;
}
}
int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
ngx_dir_t *dir)
{
@ -182,45 +334,69 @@ int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
}
int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx,
ngx_str_t *temp_file)
/* 32-bit crc16 */
static int ngx_crc(char *data, size_t len)
{
int retry;
ngx_err_t err;
uint32_t sum;
retry = 0;
for (sum = 0; len; len--) {
/*
* gcc 2.95.2 x86 and icc 7.1.006 compile that operator
* into the single rol opcode.
* msvc 6.0sp2 compiles it into four opcodes.
*/
sum = sum >> 1 | sum << 31;
for ( ;; ) {
if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) {
return NGX_OK;
}
sum += *data++;
}
err = ngx_errno;
return sum;
}
#if (WIN32)
if (err == NGX_EEXIST) {
if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool)
== NGX_ERROR)
{
return NGX_ERROR;
static void *ngx_http_cache_create_conf(ngx_conf_t *cf)
{
ngx_http_cache_conf_t *conf;
if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_conf_t)))) {
return NGX_CONF_ERROR;
}
return conf;
}
static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child)
{
ngx_http_cache_conf_t *prev = parent;
ngx_http_cache_conf_t *conf = child;
if (conf->hash == NULL) {
if (prev->hash) {
conf->hash = prev->hash;
} else {
conf->hash = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_hash_t));
if (conf->hash == NULL) {
return NGX_CONF_ERROR;
}
conf->hash->hash = NGX_HTTP_CACHE_HASH;
conf->hash->nelts = NGX_HTTP_CACHE_NELTS;
conf->hash->cache = ngx_pcalloc(cf->pool,
NGX_HTTP_CACHE_HASH
* NGX_HTTP_CACHE_NELTS
* sizeof(ngx_http_cache_entry_t));
if (conf->hash->cache == NULL) {
return NGX_CONF_ERROR;
}
}
#endif
if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
ngx_rename_file_n "(\"%s\", \"%s\") failed",
temp_file->data, ctx->file.name.data);
return NGX_ERROR;
}
if (ngx_create_path(&ctx->file, ctx->path) == NGX_ERROR) {
return NGX_ERROR;
}
retry = 1;
}
return NGX_CONF_OK;
}
@ -261,7 +437,7 @@ typedef struct {
typedef struct {
u_int32_t crc;
uint32_t crc;
ngx_str_t uri;
ngx_http_cache_t *cache;
} ngx_http_cache_hash_entry_t;
@ -269,7 +445,7 @@ typedef struct {
typedef struct {
ngx_http_cache_t *cache;
u_int32_t crc;
uint32_t crc;
int n;
} ngx_http_cache_handle_t;
@ -305,7 +481,7 @@ int ngx_http_cache_get(ngx_http_cache_hash_t *cache_hash,
int ngx_crc(char *data, size_t len)
{
u_int32_t sum;
uint32_t sum;
for (sum = 0; len; len--) {
/*

View File

@ -18,32 +18,52 @@ typedef struct {
typedef struct {
u_int32_t crc;
uint32_t crc;
ngx_str_t key;
ngx_fd_t fd;
off_t size;
void *data; /* mmap, memory */
time_t accessed;
time_t last_modified;
time_t updated; /* no needed with kqueue */
time_t updated; /* no needed with kqueue */
int refs;
int flags;
} ngx_http_cache_entry_t;
#define NGX_HTTP_CACHE_HASH 1021
#define NGX_HTTP_CACHE_NELTS 4
typedef struct {
ngx_file_t file;
ngx_str_t key;
u_char md5[16];
ngx_path_t *path;
ngx_hunk_t *buf;
time_t expires;
time_t last_modified;
time_t date;
off_t length;
ssize_t header_size;
size_t file_start;
ngx_log_t *log;
ngx_http_cache_entry_t **cache;
size_t hash;
size_t nelts;
time_t life_time;
time_t check_time;
ngx_pool_t *pool;
} ngx_http_cache_hash_t;
typedef struct {
ngx_http_cache_hash_t *hash;
} ngx_http_cache_conf_t;
typedef struct {
ngx_http_cache_hash_t *hash;
ngx_http_cache_entry_t *cache;
ngx_file_t file;
ngx_str_t key;
uint32_t crc;
u_char md5[16];
ngx_path_t *path;
ngx_hunk_t *buf;
time_t expires;
time_t last_modified;
time_t date;
off_t length;
ssize_t header_size;
size_t file_start;
ngx_log_t *log;
} ngx_http_cache_ctx_t;

View File

@ -88,7 +88,7 @@ static ngx_command_t ngx_http_core_commands[] = {
NULL},
{ngx_string("location"),
NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
ngx_location_block,
NGX_HTTP_SRV_CONF_OFFSET,
0,
@ -368,19 +368,27 @@ static void ngx_http_run_phases(ngx_http_request_t *r)
int ngx_http_find_location_config(ngx_http_request_t *r)
{
int i, rc;
ngx_int_t i, rc, exact;
ngx_str_t *auto_redirect;
ngx_http_core_loc_conf_t *clcf, **clcfp;
ngx_http_core_srv_conf_t *cscf;
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
auto_redirect = NULL;
exact = 0;
clcfp = cscf->locations.elts;
for (i = 0; i < cscf->locations.nelts; i++) {
#if 0
ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data);
#if 1
ngx_log_debug(r->connection->log, "trans: %s: %d" _
clcfp[i]->name.data _ clcfp[i]->exact_match);
#endif
if (clcfp[i]->regex) {
break;
}
if (clcfp[i]->auto_redirect
&& r->uri.len == clcfp[i]->name.len - 1
&& ngx_strncmp(r->uri.data, clcfp[i]->name.data,
@ -406,6 +414,50 @@ ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data);
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
r->connection->log->file = clcf->err_log->file;
r->connection->log->log_level = clcf->err_log->log_level;
if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) {
exact = 1;
break;
}
}
}
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;
}
rc = ngx_regex_exec(clcfp[i]->regex, &r->uri);
if (rc == NGX_DECLINED) {
continue;
}
if (rc < 0) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
ngx_regex_exec_n
" failed: %d on \"%s\" using \"%s\"",
rc, r->uri.data, clcfp[i]->name.data);
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
/* match */
r->loc_conf = clcfp[i]->loc_conf;
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
r->connection->log->file = clcf->err_log->file;
r->connection->log->log_level = clcf->err_log->log_level;
break;
}
}
@ -669,37 +721,58 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
}
static int ngx_cmp_locations(const void *first, const void *second)
static int ngx_cmp_locations(const void *one, const void *two)
{
ngx_http_core_loc_conf_t *one = *(ngx_http_core_loc_conf_t **) first;
ngx_http_core_loc_conf_t *two = *(ngx_http_core_loc_conf_t **) second;
ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one;
ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two;
return ngx_strcmp(one->name.data, two->name.data);
ngx_int_t rc;
if (first->regex && !second->regex) {
/* shift regex matches to the end */
return 1;
}
if (first->regex || second->regex) {
/* do not sort regex matches */
return 0;
}
rc = ngx_strcmp(first->name.data, second->name.data);
if (rc == 0 && second->exact_match) {
/* an exact match must be before the same inclusive one */
return 1;
}
return rc;
}
static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
{
int m;
char *rv;
ngx_str_t *location;
ngx_int_t m;
ngx_str_t *value, err;
ngx_http_module_t *module;
ngx_conf_t pvcf;
ngx_http_conf_ctx_t *ctx, *pvctx;
ngx_http_core_srv_conf_t *cscf;
ngx_http_core_loc_conf_t *clcf, **clcfp;
char errstr[NGX_MAX_CONF_ERRSTR];
ngx_test_null(ctx,
ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
NGX_CONF_ERROR);
if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) {
return NGX_CONF_ERROR;
}
pvctx = (ngx_http_conf_ctx_t *) cf->ctx;
ctx->main_conf = pvctx->main_conf;
ctx->srv_conf = pvctx->srv_conf;
ngx_test_null(ctx->loc_conf,
ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
NGX_CONF_ERROR);
ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
if (ctx->loc_conf == NULL) {
return NGX_CONF_ERROR;
}
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
@ -709,20 +782,61 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
module = ngx_modules[m]->ctx;
if (module->create_loc_conf) {
ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index],
module->create_loc_conf(cf),
NGX_CONF_ERROR);
ctx->loc_conf[ngx_modules[m]->ctx_index] =
module->create_loc_conf(cf);
if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) {
return NGX_CONF_ERROR;
}
}
}
clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
location = (ngx_str_t *) cf->args->elts;
clcf->name.len = location[1].len;
clcf->name.data = location[1].data;
clcf->loc_conf = ctx->loc_conf;
value = (ngx_str_t *) cf->args->elts;
if (cf->args->nelts == 3) {
if (value[1].len == 1 && value[1].data[0] == '=') {
clcf->name.len = value[2].len;
clcf->name.data = value[2].data;
clcf->exact_match = 1;
} else if ((value[1].len == 1 && value[1].data[0] == '~')
|| (value[1].len == 2
&& value[1].data[0] == '~'
&& value[1].data[1] == '*'))
{
err.len = NGX_MAX_CONF_ERRSTR;
err.data = errstr;
clcf->regex = ngx_regex_compile(&value[2],
value[1].len == 2 ? NGX_REGEX_CASELESS: 0,
cf->pool, &err);
if (clcf->regex == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
return NGX_CONF_ERROR;
}
clcf->name.len = value[2].len;
clcf->name.data = value[2].data;
} else {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid location modifier \"%s\"",
value[1].data);
return NGX_CONF_ERROR;
}
} else {
clcf->name.len = value[1].len;
clcf->name.data = value[1].data;
}
cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
ngx_test_null(clcfp, ngx_push_array(&cscf->locations), NGX_CONF_ERROR);
if (!(clcfp = ngx_push_array(&cscf->locations))) {
return NGX_CONF_ERROR;
}
*clcfp = clcf;
pvcf = *cf;
@ -911,6 +1025,10 @@ static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf->err_log = NULL;
lcf->error_pages = NULL;
lcf->regex = NULL;
lcf->exact_match = 0;
lcf->auto_redirect = 0;
*/
lcf->client_body_timeout = NGX_CONF_UNSET;
@ -1079,7 +1197,7 @@ static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
ls->addr = *(u_int32_t *)(h->h_addr_list[0]);
ls->addr = *(in_addr_t *)(h->h_addr_list[0]);
}
return NGX_CONF_OK;

View File

@ -8,7 +8,7 @@
typedef struct {
u_int32_t addr;
in_addr_t addr;
int port;
int family;
int flags; /* 'default' */
@ -65,7 +65,7 @@ typedef struct {
typedef struct {
u_int32_t addr;
in_addr_t addr;
ngx_array_t names; /* array of ngx_http_server_name_t */
ngx_http_core_srv_conf_t *core_srv_conf; /* default server conf
for this address:port */
@ -128,6 +128,10 @@ typedef struct {
int msie_padding; /* msie_padding */
ngx_array_t *error_pages; /* error_page */
ngx_regex_t *regex;
unsigned exact_match:1;
unsigned auto_redirect:1;
ngx_log_t *err_log;

View File

@ -266,7 +266,7 @@ static int ngx_http_header_filter(ngx_http_request_t *r)
#endif
h->last += ngx_snprintf(h->last, /* 2^64 */
sizeof("Content-Length: 18446744073709551616" CRLF),
"Content-Length: " OFF_FMT CRLF,
"Content-Length: " OFF_T_FMT CRLF,
r->headers_out.content_length_n);
#if (NGX_HTTP_LOG_ALL_HEADERS_OUT)

View File

@ -250,7 +250,7 @@ static char *ngx_http_log_status(ngx_http_request_t *r, char *buf,
static char *ngx_http_log_length(ngx_http_request_t *r, char *buf,
uintptr_t data)
{
return buf + ngx_snprintf(buf, NGX_OFF_LEN + 1, OFF_FMT,
return buf + ngx_snprintf(buf, NGX_OFF_LEN + 1, OFF_T_FMT,
r->connection->sent);
}

View File

@ -82,7 +82,7 @@ int ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir);
#define ngx_read_dir_n "readdir()"
#define ngx_create_dir(name) mkdir(name, (mode_t) 0700)
#define ngx_create_dir(name) mkdir(name, 0700)
#define ngx_create_dir_n "mkdir()"

View File

@ -3,7 +3,7 @@
#include <unistd.h>
#include <stddef.h> /* offsetof */
#include <stddef.h> /* offsetof() */
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
@ -27,35 +27,6 @@
#include <osreldate.h>
/* TODO: autoconf */
#if (i386)
#if 0
#define OFF_FMT "%lld"
#endif
#define SIZE_FMT "%d"
#define SIZEX_FMT "%x"
#else /* amd64, alpha, sparc64, ia64 */
#if 0
#define OFF_FMT "%ld"
#endif
#define SIZE_FMT "%ld"
#define SIZEX_FMT "%lx"
#endif
#if 0
#define TIME_FMT "%ld"
#endif
#define PID_FMT "%d"
#define RLIM_FMT "%lld"
#ifndef HAVE_SELECT
#define HAVE_SELECT 1
#endif
@ -89,58 +60,11 @@
#endif
/* STUB */
#define HAVE_PREAD 1
#define HAVE_PWRITE 1
#define HAVE_LOCALTIME_R 1
/* FreeBSD sendfile */
#if __FreeBSD_version >= 300007
#ifndef HAVE_FREEBSD_SENDFILE
#define HAVE_FREEBSD_SENDFILE 1
#endif
#endif
#if (HAVE_FREEBSD_SENDFILE)
#define HAVE_SENDFILE 1
#endif
/* FreeBSD kqueue */
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 410000) \
|| __FreeBSD_version >= 500011
#ifndef HAVE_KQUEUE
#define HAVE_KQUEUE 1
#endif
#endif
#if (HAVE_KQUEUE)
#include <sys/event.h>
#endif
/* kqueue's NOTE_LOWAT */
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
|| __FreeBSD_version >= 500018
#ifndef HAVE_LOWAT_EVENT
#define HAVE_LOWAT_EVENT 1
#endif
#endif
#ifndef HAVE_INHERITED_NONBLOCK
#define HAVE_INHERITED_NONBLOCK 1
#endif

View File

@ -20,12 +20,12 @@ ngx_os_io_t ngx_os_io = {
ngx_unix_recv,
ngx_readv_chain,
NULL,
#if (HAVE_FREEBSD_SENDFILE)
#if (HAVE_SENDFILE)
ngx_freebsd_sendfile_chain,
NGX_HAVE_SENDFILE|NGX_HAVE_ZEROCOPY
NGX_HAVE_SENDFILE
#else
ngx_writev_chain,
NULL
0
#endif
};
@ -97,7 +97,7 @@ int ngx_os_init(ngx_log_t *log)
version, __FreeBSD_version);
#if (HAVE_FREEBSD_SENDFILE)
#if (HAVE_SENDFILE)
/*
* The determination of the sendfile() nbytes bug is complex enough.
@ -127,7 +127,7 @@ int ngx_os_init(ngx_log_t *log)
#endif
#endif /* HAVE_FREEBSD_SENDFILE */
#endif /* HAVE_SENDFILE */
if ((version < 500000 && version >= 440003) || version >= 500017) {

View File

@ -22,16 +22,17 @@
ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
{
int rc, eintr, eagain;
int rc;
char *prev;
off_t sent, fprev;
size_t hsize, fsize, size;
ngx_int_t eintr, eagain;
struct iovec *iov;
struct sf_hdtr hdtr;
ngx_err_t err;
ngx_hunk_t *file;
ngx_array_t header, trailer;
ngx_event_t *wev;
ngx_hunk_t *file;
ngx_chain_t *cl, *tail;
wev = c->write;
@ -53,7 +54,6 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
#endif
do {
cl = in;
file = NULL;
fsize = 0;
hsize = 0;
@ -156,7 +156,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
ngx_log_debug(c->log, "NOPUSH");
if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno,
ngx_tcp_nopush_n " failed");
return NGX_CHAIN_ERROR;
}

8
src/os/unix/ngx_linux.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _NGX_LINUX_H_INCLUDED_
#define _NGX_LINUX_H_INCLUDED_
ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
#endif /* _NGX_LINUX_H_INCLUDED_ */

View File

@ -2,14 +2,14 @@
#define _NGX_LINUX_CONFIG_H_INCLUDED_
#define _GNU_SOURCE /* pread, pwrite, gethostname, bzero */
#define _GNU_SOURCE /* pread(), pwrite(), gethostname() */
#define _FILE_OFFSET_BITS 64
#define _LARGEFILE_SOURCE
#include <unistd.h>
#include <stddef.h> /* offsetof */
#include <stddef.h> /* offsetof() */
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
@ -27,16 +27,17 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <netdb.h>
#define OFF_FMT "%lld"
#if 0
#define SIZE_FMT "%d"
#define SIZEX_FMT "%x"
#define TIME_FMT "%ld"
#define PID_FMT "%d"
#define RLIM_FMT "%lu"
#endif

View File

@ -1,183 +1,214 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_linux_init.h>
#include <ngx_event.h>
ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
{
int rc, on, off;
int rc;
char *prev;
size_t hsize, size;
ssize_t sent;
off_t fprev;
size_t size, fsize, sent;
ngx_int_t use_cork, eintr;
struct iovec *iov;
struct sf_hdtr hdtr;
ngx_err_t err;
ngx_array_t header, trailer;
ngx_hunk_t *file;
ngx_chain_t *ce;
ngx_array_t header;
ngx_event_t *wev;
ngx_chain_t *cl;
ce = in;
file = NULL;
hsize = 0;
wev = c->write;
on = 1;
off = 0;
if (!wev->ready) {
return in;
}
ngx_init_array(header, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
cork = 0;
do {
file = NULL;
fsize = 0;
eintr = 0;
ngx_init_array(header, c->pool, 10, sizeof(struct iovec),
NGX_CHAIN_ERROR);
/* create the header iovec */
if (ngx_hunk_in_memory_only(ce->hunk)) {
prev = NULL;
iov = NULL;
/* create the iovec and coalesce the neighbouring chain entries */
while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
/* create the iovec and coalesce the neighbouring hunks */
if (prev == ce->hunk->pos) {
iov->iov_len += ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
for (cl = in; cl; cl = cl->next) {
if (ngx_hunk_special(cl->hunk)) {
continue;
}
if (!ngx_hunk_in_memory_only(cl->hunk)) {
break;
}
if (prev == cl->hunk->pos) {
iov->iov_len += cl->hunk->last - cl->hunk->pos;
} else {
ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR);
iov->iov_base = ce->hunk->pos;
iov->iov_len = ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
iov->iov_base = cl->hunk->pos;
iov->iov_len = cl->hunk->last - cl->hunk->pos;
}
if (ngx_freebsd_sendfile_nbytes_bug) {
hsize += ce->hunk->last - ce->hunk->pos;
}
ce = ce->next;
}
}
/* TODO: coalesce the neighbouring file hunks */
if (ce && (ce->hunk->type & NGX_HUNK_FILE)) {
file = ce->hunk;
ce = ce->next;
}
/* create the trailer iovec */
if (ce && ngx_hunk_in_memory_only(ce->hunk)) {
prev = NULL;
iov = NULL;
/* create the iovec and coalesce the neighbouring chain entries */
while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
if (prev == ce->hunk->pos) {
iov->iov_len += ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
} else {
ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR);
iov->iov_base = ce->hunk->pos;
iov->iov_len = ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
}
ce = ce->next;
}
}
if (file) {
if (setsockopt(c->fd, IPPROTO_TCP, TCP_CORK,
(const void *) &on, sizeof(int)) == -1) {
ngx_log_error(NGX_LOG_CRIT, c->log, err,
"setsockopt(TCP_CORK, 1) failed");
return NGX_CHAIN_ERROR;
prev = cl->hunk->last;
}
/* set TCP_CORK if there is a header before a file */
rc = sendfile(c->fd, file->file->fd, file->file_pos,
(size_t) (file->file_last - file->file_pos));
if (!c->tcp_nopush
&& header.nelts != 0
&& cl
&& cl->hunk->type & NGX_HUNK_FILE)
{
c->tcp_nopush = 1;
if (rc == -1) {
err = ngx_errno;
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "senfile() EAGAIN");
ngx_log_debug(c->log, "CORK");
} else if (err == NGX_EINTR) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "senfile() EINTR");
} else {
ngx_log_error(NGX_LOG_CRIT, c->log, err, "sendfile() failed");
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;
}
}
sent = rc > 0 ? rc : 0;
if (header.nelts == 0 && cl && cl->hunk->type & NGX_HUNK_FILE) {
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "sendfile: %d, @%qd %d:%d" _
rc _ file->file_pos _ sent _
(size_t) (file->file_last - file->file_pos));
#endif
/* get the file hunk */
} else {
rc = writev(c->fd, (struct iovec *) header.elts, header.nelts);
file = cl->hunk;
fsize = (size_t) (file->file_last - file->file_pos);
fprev = file->file_last;
cl = cl->next;
if (rc == -1) {
err = ngx_errno;
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
/* coalesce the neighbouring file hunks */
} else if (err == NGX_EINTR) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
while (cl && (cl->hunk->type & NGX_HUNK_FILE)) {
if (file->file->fd != cl->hunk->file->fd
|| fprev != cl->hunk->file_pos)
{
break;
}
} else {
ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
return NGX_CHAIN_ERROR;
fsize += (size_t) (cl->hunk->file_last - cl->hunk->file_pos);
fprev = cl->hunk->file_last;
cl = cl->next;
}
}
sent = rc > 0 ? rc : 0;
/*
* the tail is the rest of the chain that exceeded
* a single sendfile() capability
*/
tail = cl;
if (fsize) {
rc = sendfile(c->fd, file->file->fd, file->file_pos, fsize);
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");
} else {
ngx_log_error(NGX_LOG_CRIT, c->log, err,
"sendfile() failed");
return NGX_CHAIN_ERROR;
}
}
sent = rc > 0 ? rc : 0;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "writev: %d" _ sent);
ngx_log_debug(c->log, "sendfile: %d, @" OFF_T_FMT " %d:%d" _
rc _ file->file_pos _ sent _ fsize);
#endif
}
c->sent += sent;
for (ce = in; ce && sent > 0; ce = ce->next) {
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
size = ce->hunk->last - ce->hunk->pos;
} else {
size = ce->hunk->file_last - ce->hunk->file_pos;
}
rc = writev(c->fd, header.elts, header.nelts);
if (sent >= size) {
sent -= size;
if (rc == -1) {
err = ngx_errno;
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
ce->hunk->pos = ce->hunk->last;
} else if (err == NGX_EINTR) {
eintr = 1;
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
} else {
ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
return NGX_CHAIN_ERROR;
}
}
if (ce->hunk->type & NGX_HUNK_FILE) {
ce->hunk->file_pos = ce->hunk->file_last;
sent = rc > 0 ? rc : 0;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "writev: %d" _ sent);
#endif
}
c->sent += sent;
for (cl = in; cl; cl = cl->next) {
if (ngx_hunk_special(cl->hunk)) {
continue;
}
continue;
if (sent == 0) {
break;
}
size = ngx_hunk_size(cl->hunk);
if (sent >= size) {
sent -= size;
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
cl->hunk->pos = cl->hunk->last;
}
if (cl->hunk->type & NGX_HUNK_FILE) {
cl->hunk->file_pos = cl->hunk->file_last;
}
continue;
}
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
cl->hunk->pos += sent;
}
if (cl->hunk->type & NGX_HUNK_FILE) {
cl->hunk->file_pos += sent;
}
break;
}
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
ce->hunk->pos += sent;
}
in = cl;
if (ce->hunk->type & NGX_HUNK_FILE) {
ce->hunk->file_pos += sent;
}
/* "tail == in" means that a single sendfile() is complete */
break;
} while ((tail && tail == in) || eintr);
if (in) {
wev->ready = 0;
}
ngx_destroy_array(&trailer);
ngx_destroy_array(&header);
return ce;
return in;
}

View File

@ -56,7 +56,7 @@ int ngx_posix_init(ngx_log_t *log)
}
ngx_log_error(NGX_LOG_INFO, log, 0,
"getrlimit(RLIMIT_NOFILE): " RLIM_FMT ":" RLIM_FMT,
"getrlimit(RLIMIT_NOFILE): " RLIM_T_FMT ":" RLIM_T_FMT,
rlmt.rlim_cur, rlmt.rlim_max);
ngx_max_sockets = rlmt.rlim_cur;

View File

@ -41,9 +41,10 @@ int ngx_spawn_process(ngx_log_t *log)
break;
default:
break;
}
ngx_log_debug(log, "parent process, child: " PID_FMT _ pid);
ngx_log_debug(log, "parent process, child: " PID_T_FMT _ pid);
/* book keeping */
@ -97,7 +98,7 @@ void ngx_sigchld_handler(int signo)
one = 1;
ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
"process " PID_FMT " exited with code %d", pid, status);
"process " PID_T_FMT " exited with code %d", pid, status);
/* TODO: restart handler */

View File

@ -55,6 +55,28 @@ int ngx_tcp_push(ngx_socket_t s)
(const void *) &tcp_nopush, sizeof(int));
}
#elif __linux__
int ngx_tcp_nopush(ngx_socket_t s)
{
int cork;
cork = 1;
return setsockopt(s, IPPROTO_TCP, TCP_CORK,
(const void *) &cork, sizeof(int));
}
int ngx_tcp_push(ngx_socket_t s)
{
int cork;
cork = 0;
return setsockopt(s, IPPROTO_TCP, TCP_CORK,
(const void *) &cork, sizeof(int));
}
#else
int ngx_tcp_nopush(ngx_socket_t s)

View File

@ -29,11 +29,19 @@ int ngx_blocking(ngx_socket_t s);
#endif
int ngx_tcp_nopush(ngx_socket_t s);
#define ngx_tcp_nopush_n "setsockopt(TCP_NOPUSH)"
int ngx_tcp_push(ngx_socket_t s);
#ifdef __linux__
#define ngx_tcp_nopush_n "setsockopt(TCP_CORK)"
#define ngx_tcp_push_n "setsockopt(!TCP_CORK)"
#else
#define ngx_tcp_nopush_n "setsockopt(TCP_NOPUSH)"
#define ngx_tcp_push_n "setsockopt(!TCP_NOPUSH)"
#endif
#define ngx_shutdown_socket shutdown

View File

@ -10,7 +10,7 @@
#include <unistd.h>
#include <inttypes.h>
#include <stddef.h> /* offsetof */
#include <stddef.h> /* offsetof() */
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
@ -28,14 +28,14 @@
#include <netdb.h>
typedef uint32_t u_int32_t;
#if 0
#define OFF_FMT "%lld"
#define SIZE_FMT "%d"
#define SIZEX_FMT "%x"
#define TIME_FMT "%ld"
#define PID_FMT "%ld"
#define RLIM_FMT "%lu"
#endif
#ifndef HAVE_SELECT

View File

@ -58,7 +58,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
sent = n > 0 ? n : 0;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "writev: " OFF_FMT _ sent);
ngx_log_debug(c->log, "writev: " OFF_T_FMT _ sent);
#endif
c->sent += sent;

View File

@ -42,7 +42,7 @@ int ngx_sendfile(ngx_connection_t *c,
if (ev->ready) {
ev->ready = 0;
#if (HAVE_IOCP_EVENT) /* iocp */
#if (HAVE_IOCP) /* iocp */
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
if (ev->ovlp.error) {

View File

@ -21,7 +21,7 @@
#include <winsock2.h>
#include <mswsock.h>
#include <stddef.h> /* offsetof */
#include <stddef.h> /* offsetof() */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
@ -41,6 +41,7 @@
#if 0
/* owc have not __int32 */
typedef unsigned __int32 uint32_t;
#else
typedef unsigned int uint32_t;
@ -52,18 +53,16 @@ typedef u_int uintptr_t;
typedef int ssize_t;
typedef long time_t;
typedef __int64 off_t;
typedef uint32_t in_addr_t;
#define OFF_FMT "%I64d"
#define SIZE_FMT "%d"
#define SIZEX_FMT "%x"
#define PID_FMT "%d"
#define TIME_FMT "%lu"
#define OFF_T_FMT "%I64d"
#define SIZE_T_FMT "%d"
#define SIZE_T_X_FMT "%x"
#define PID_T_FMT "%d"
#define TIME_T_FMT "%lu"
/* STUB */
typedef uint32_t u_int32_t;
#ifndef HAVE_INHERITED_NONBLOCK
#define HAVE_INHERITED_NONBLOCK 1