changeset 482:392c16f2d858 NGINX_0_7_53

nginx 0.7.53 *) Change: now a log set by --error-log-path is created from the very start-up. *) Feature: now the start up errors and warnings are outputted to an error_log and stderr. *) Feature: the empty --prefix= configure parameter forces nginx to use a directory where it was run as prefix. *) Feature: the -p switch. *) Feature: the -s switch on Unix platforms. *) Feature: the -? and -h switches. Thanks to Jerome Loyet. *) Feature: now switches may be set in condensed form. *) Bugfix: nginx/Windows did not work if configuration file was given by the -c switch. *) Bugfix: temporary files might be not removed if the "proxy_store", "fastcgi_store", "proxy_cache", or "fastcgi_cache" were used. Thanks to Maxim Dounin. *) Bugfix: an incorrect value was passed to mail proxy authentication server in "Auth-Method" header line; the bug had appeared in 0.7.34. Thanks to Simon Lecaille. *) Bugfix: system error text descriptions were not logged on Linux; the bug had appeared in 0.7.45. *) Bugfix: the "fastcgi_cache_min_uses" directive did not work. Thanks to Andrew Vorobyoff.
author Igor Sysoev <http://sysoev.ru>
date Mon, 27 Apr 2009 00:00:00 +0400
parents 0c98173187ac
children 0a2f4b42ddad
files CHANGES CHANGES.ru auto/cc/gcc auto/install auto/lib/openssl/conf auto/options auto/os/linux auto/os/win32 auto/stubs configure src/core/nginx.c src/core/nginx.h src/core/ngx_conf_file.c src/core/ngx_cycle.c src/core/ngx_cycle.h src/core/ngx_log.c src/core/ngx_log.h src/core/ngx_open_file_cache.c src/core/ngx_open_file_cache.h src/http/modules/ngx_http_fastcgi_module.c src/http/modules/ngx_http_flv_module.c src/http/modules/ngx_http_gzip_static_module.c src/http/modules/ngx_http_index_module.c src/http/modules/ngx_http_log_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_static_module.c src/http/modules/perl/nginx.pm src/http/modules/perl/nginx.xs src/http/ngx_http_core_module.c src/http/ngx_http_parse.c src/http/ngx_http_request.c src/http/ngx_http_script.c src/http/ngx_http_script.h src/http/ngx_http_upstream.c src/http/ngx_http_upstream.h src/mail/ngx_mail_auth_http_module.c src/mail/ngx_mail_ssl_module.c src/os/unix/ngx_files.h src/os/unix/ngx_os.h src/os/unix/ngx_process.c src/os/unix/ngx_process_cycle.h
diffstat 41 files changed, 857 insertions(+), 435 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES	Mon Apr 20 00:00:00 2009 +0400
+++ b/CHANGES	Mon Apr 27 00:00:00 2009 +0400
@@ -1,4 +1,43 @@
 
+Changes with nginx 0.7.53                                        27 Apr 2009
+
+    *) Change: now a log set by --error-log-path is created from the very 
+       start-up.
+
+    *) Feature: now the start up errors and warnings are outputted to an 
+       error_log and stderr.
+
+    *) Feature: the empty --prefix= configure parameter forces nginx to use 
+       a directory where it was run as prefix.
+
+    *) Feature: the -p switch.
+
+    *) Feature: the -s switch on Unix platforms.
+
+    *) Feature: the -? and -h switches.
+       Thanks to Jerome Loyet.
+
+    *) Feature: now switches may be set in condensed form.
+
+    *) Bugfix: nginx/Windows did not work if configuration file was given 
+       by the -c switch.
+
+    *) Bugfix: temporary files might be not removed if the "proxy_store", 
+       "fastcgi_store", "proxy_cache", or "fastcgi_cache" were used.
+       Thanks to Maxim Dounin.
+
+    *) Bugfix: an incorrect value was passed to mail proxy authentication 
+       server in "Auth-Method" header line; the bug had appeared
+       in 0.7.34.
+       Thanks to Simon Lecaille.
+
+    *) Bugfix: system error text descriptions were not logged on Linux;
+       the bug had appeared in 0.7.45.
+
+    *) Bugfix: the "fastcgi_cache_min_uses" directive did not work.
+       Thanks to Andrew Vorobyoff.
+
+
 Changes with nginx 0.7.52                                        20 Apr 2009
 
     *) Feature: the first native Windows binary release.
--- a/CHANGES.ru	Mon Apr 20 00:00:00 2009 +0400
+++ b/CHANGES.ru	Mon Apr 27 00:00:00 2009 +0400
@@ -1,4 +1,43 @@
 
+Изменения в nginx 0.7.53                                          27.04.2009
+
+    *) Изменение: теперь лог, указанный в --error-log-path, создаётся с 
+       самого начала работы.
+
+    *) Добавление: теперь ошибки и предупреждения при старте записываются в 
+       error_log и выводятся на stderr.
+
+    *) Добавление: при сборке с пустым параметром --prefix= nginx 
+       использует как префикс каталог, в котором он был запущен.
+
+    *) Добавление: ключ -p.
+
+    *) Добавление: ключ -s на Unix-платформах.
+
+    *) Добавление: ключи -? и -h.
+       Спасибо Jerome Loyet.
+
+    *) Добавление: теперь ключи можно задавать в сжатой форме.
+
+    *) Исправление: nginx/Windows не работал, если файл конфигурации был 
+       задан ключём -c.
+
+    *) Исправление: при использовании директив proxy_store, fastcgi_store, 
+       proxy_cache или fastcgi_cache временные файлы могли не удаляться.
+       Спасибо Максиму Дунину.
+
+    *) Исправление: в заголовке Auth-Method запроса серверу аутентификации 
+       почтового прокси-сервера передавалось неверное значение; ошибка 
+       появилась в 0.7.34.
+       Спасибо Simon Lecaille.
+
+    *) Исправление: при логгировании на Linux не писались текстовые 
+       описания системных ошибок; ошибка появилась в 0.7.45.
+
+    *) Исправление: директива fastcgi_cache_min_uses не работала.
+       Спасибо Андрею Воробьёву.
+
+
 Изменения в nginx 0.7.52                                          20.04.2009
 
     *) Добавление: первая бинарная версия под Windows.
--- a/auto/cc/gcc	Mon Apr 20 00:00:00 2009 +0400
+++ b/auto/cc/gcc	Mon Apr 27 00:00:00 2009 +0400
@@ -158,9 +158,10 @@
     3.* | 4.* )
         # we have a lot of the unused function arguments
         CFLAGS="$CFLAGS -Wno-unused-parameter"
-        CFLAGS="$CFLAGS -Wno-unused-function"
+        CFLAGS="$CFLAGS -Wunused-function"
         CFLAGS="$CFLAGS -Wunused-variable"
         CFLAGS="$CFLAGS -Wunused-value"
+        # 4.2.1 shows the warning in wrong places
         #CFLAGS="$CFLAGS -Wunreachable-code"
     ;;
 
--- a/auto/install	Mon Apr 20 00:00:00 2009 +0400
+++ b/auto/install	Mon Apr 27 00:00:00 2009 +0400
@@ -15,6 +15,63 @@
 fi
 
 
+case ".$NGX_SBIN_PATH" in
+    ./*)
+    ;;
+
+    .)
+        NGX_SBIN_PATH=$NGX_PREFIX/sbin/nginx
+    ;;
+
+    *)
+        NGX_SBIN_PATH=$NGX_PREFIX/$NGX_SBIN_PATH
+    ;;
+esac
+
+
+case ".$NGX_CONF_PATH" in
+    ./*)
+    ;;
+
+    *)
+        NGX_CONF_PATH=$NGX_PREFIX/$NGX_CONF_PATH
+    ;;
+esac
+
+
+NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`
+
+
+case ".$NGX_PID_PATH" in
+    ./*)
+    ;;
+
+    *)
+        NGX_PID_PATH=$NGX_PREFIX/$NGX_PID_PATH
+    ;;
+esac
+
+
+case ".$NGX_ERROR_LOG_PATH" in
+    ./*)
+    ;;
+
+    *)
+        NGX_ERROR_LOG_PATH=$NGX_PREFIX/$NGX_ERROR_LOG_PATH
+    ;;
+esac
+
+
+case ".$NGX_HTTP_LOG_PATH" in
+    ./*)
+    ;;
+
+    *)
+        NGX_HTTP_LOG_PATH=$NGX_PREFIX/$NGX_HTTP_LOG_PATH
+    ;;
+esac
+
+
 cat << END                                                    >> $NGX_MAKEFILE
 
 install:	$NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \
--- a/auto/lib/openssl/conf	Mon Apr 20 00:00:00 2009 +0400
+++ b/auto/lib/openssl/conf	Mon Apr 27 00:00:00 2009 +0400
@@ -17,8 +17,8 @@
             LINK_DEPS="$LINK_DEPS $OPENSSL/out32/libeay32.lib"
             CORE_LIBS="$CORE_LIBS $OPENSSL/out32/libeay32.lib"
 
-            # libeay32.lib requires gdi32.lib and advapi32.lib
-            CORE_LIBS="$CORE_LIBS gdi32.lib advapi32.lib"
+            # libeay32.lib requires gdi32.lib
+            CORE_LIBS="$CORE_LIBS gdi32.lib"
         ;;
 
         *)
@@ -49,8 +49,8 @@
             CORE_LIBS="$CORE_LIBS c:/openssl/ssleay32.lib"
             CORE_LIBS="$CORE_LIBS c:/openssl/libeay32.lib"
 
-            # libeay32.lib requires gdi32.lib and advapi32.lib
-            CORE_LIBS="$CORE_LIBS gdi32.lib advapi32.lib"
+            # libeay32.lib requires gdi32.lib
+            CORE_LIBS="$CORE_LIBS gdi32.lib"
         ;;
 
         *)
--- a/auto/options	Mon Apr 20 00:00:00 2009 +0400
+++ b/auto/options	Mon Apr 27 00:00:00 2009 +0400
@@ -129,9 +129,12 @@
 
 NGX_CPU_CACHE_LINE=
 
+opt=
 
 for option
 do
+     opt="$opt `echo $option | sed -e \"s/\(--[^=]*=\)\(.* .*\)/\1'\2'/\"`"
+
     case "$option" in
         -*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
            *) value="" ;;
@@ -140,6 +143,7 @@
     case "$option" in
         --help)                          help=yes                   ;;
 
+        --prefix=)                       NGX_PREFIX="!"             ;;
         --prefix=*)                      NGX_PREFIX="$value"        ;;
         --sbin-path=*)                   NGX_SBIN_PATH="$value"     ;;
         --conf-path=*)                   NGX_CONF_PATH="$value"     ;;
@@ -267,6 +271,9 @@
 done
 
 
+NGX_CONFIGURE="$opt"
+
+
 if [ $help = yes ]; then
 
 cat << END
@@ -409,141 +416,21 @@
 fi
 
 
-NGX_PREFIX=${NGX_PREFIX:-/usr/local/nginx}
-
-
-case ".$NGX_SBIN_PATH" in
-    ./*)
-    ;;
-
-    .)
-        NGX_SBIN_PATH=$NGX_PREFIX/sbin/nginx
-    ;;
-
-    *)
-        NGX_SBIN_PATH=$NGX_PREFIX/$NGX_SBIN_PATH
-    ;;
-esac
-
-
-case ".$NGX_CONF_PATH" in
-    ./*)
-    ;;
-
-    .)
-        NGX_CONF_PATH=$NGX_PREFIX/conf/nginx.conf
-    ;;
-
-    *)
-        NGX_CONF_PATH=$NGX_PREFIX/$NGX_CONF_PATH
-    ;;
-esac
-
-
+NGX_CONF_PATH=${NGX_CONF_PATH:-conf/nginx.conf}
 NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`
-
-
-case ".$NGX_PID_PATH" in
-    ./*)
-    ;;
-
-    .)
-        NGX_PID_PATH=$NGX_PREFIX/logs/nginx.pid
-    ;;
-
-    *)
-        NGX_PID_PATH=$NGX_PREFIX/$NGX_PID_PATH
-    ;;
-esac
-
-
-case ".$NGX_LOCK_PATH" in
-    ./*)
-    ;;
-
-    .)
-        NGX_LOCK_PATH=$NGX_PREFIX/logs/nginx.lock
-    ;;
-
-    *)
-        NGX_LOCK_PATH=$NGX_PREFIX/$NGX_LOCK_PATH
-    ;;
-esac
-
-
-case ".$NGX_ERROR_LOG_PATH" in
-    ./*)
-    ;;
+NGX_PID_PATH=${NGX_PID_PATH:-logs/nginx.pid}
+NGX_LOCK_PATH=${NGX_LOCK_PATH:-logs/nginx.lock}
 
-    .)
-        NGX_ERROR_LOG_PATH=$NGX_PREFIX/logs/error.log
-    ;;
-
-    .stderr)
-        NGX_ERROR_LOG_PATH=
-    ;;
-
-    *)
-        NGX_ERROR_LOG_PATH=$NGX_PREFIX/$NGX_ERROR_LOG_PATH
-    ;;
-esac
-
-
-case ".$NGX_HTTP_LOG_PATH" in
-    ./*)
-    ;;
-
-    .)
-        NGX_HTTP_LOG_PATH=$NGX_PREFIX/logs/access.log
-    ;;
-
-    *)
-        NGX_HTTP_LOG_PATH=$NGX_PREFIX/$NGX_HTTP_LOG_PATH
-    ;;
-esac
-
-
-case ".$NGX_HTTP_CLIENT_TEMP_PATH" in
-    ./*)
-    ;;
+if [ ".$NGX_ERROR_LOG_PATH" = ".stderr" ]; then
+    NGX_ERROR_LOG_PATH=
+else
+    NGX_ERROR_LOG_PATH=${NGX_ERROR_LOG_PATH:-logs/error.log}
+fi
 
-    .)
-        NGX_HTTP_CLIENT_TEMP_PATH=$NGX_PREFIX/client_body_temp
-    ;;
-
-    *)
-        NGX_HTTP_CLIENT_TEMP_PATH=$NGX_PREFIX/$NGX_HTTP_CLIENT_TEMP_PATH
-    ;;
-esac
-
-
-case ".$NGX_HTTP_PROXY_TEMP_PATH" in
-    ./*)
-    ;;
-
-    .)
-        NGX_HTTP_PROXY_TEMP_PATH=$NGX_PREFIX/proxy_temp
-    ;;
-
-    *)
-        NGX_HTTP_PROXY_TEMP_PATH=$NGX_PREFIX/$NGX_HTTP_PROXY_TEMP_PATH
-    ;;
-esac
-
-
-case ".$NGX_HTTP_FASTCGI_TEMP_PATH" in
-    ./*)
-    ;;
-
-    .)
-        NGX_HTTP_FASTCGI_TEMP_PATH=$NGX_PREFIX/fastcgi_temp
-    ;;
-
-    *)
-        NGX_HTTP_FASTCGI_TEMP_PATH=$NGX_PREFIX/$NGX_HTTP_FASTCGI_TEMP_PATH
-    ;;
-esac
-
+NGX_HTTP_LOG_PATH=${NGX_HTTP_LOG_PATH:-logs/access.log}
+NGX_HTTP_CLIENT_TEMP_PATH=${NGX_HTTP_CLIENT_TEMP_PATH:-client_body_temp}
+NGX_HTTP_PROXY_TEMP_PATH=${NGX_HTTP_PROXY_TEMP_PATH:-proxy_temp}
+NGX_HTTP_FASTCGI_TEMP_PATH=${NGX_HTTP_FASTCGI_TEMP_PATH:-fastcgi_temp}
 
 case ".$NGX_PERL_MODULES" in
     ./*)
--- a/auto/os/linux	Mon Apr 20 00:00:00 2009 +0400
+++ b/auto/os/linux	Mon Apr 27 00:00:00 2009 +0400
@@ -140,4 +140,4 @@
 ngx_include="sys/vfs.h";     . auto/include
 
 
-CC_AUX_FLAGS=$cc_aux_flags
+CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
--- a/auto/os/win32	Mon Apr 20 00:00:00 2009 +0400
+++ b/auto/os/win32	Mon Apr 27 00:00:00 2009 +0400
@@ -8,7 +8,7 @@
 CORE_DEPS="$WIN32_DEPS"
 CORE_SRCS="$WIN32_SRCS $IOCP_SRCS"
 OS_CONFIG="$WIN32_CONFIG"
-CORE_LIBS="$CORE_LIBS shell32.lib ws2_32.lib"
+CORE_LIBS="$CORE_LIBS advapi32.lib ws2_32.lib"
 NGX_ICONS="$NGX_WIN32_ICONS"
 
 EVENT_MODULES="$EVENT_MODULES $IOCP_MODULE"
--- a/auto/stubs	Mon Apr 20 00:00:00 2009 +0400
+++ b/auto/stubs	Mon Apr 27 00:00:00 2009 +0400
@@ -2,7 +2,6 @@
 # Copyright (C) Igor Sysoev
 
 
-have=NGX_USE_HTTP_FILE_CACHE_UNIQ . auto/have
 have=NGX_SUPPRESS_WARN . auto/have
 
 have=NGX_SMP . auto/have
--- a/configure	Mon Apr 20 00:00:00 2009 +0400
+++ b/configure	Mon Apr 27 00:00:00 2009 +0400
@@ -3,8 +3,6 @@
 # Copyright (C) Igor Sysoev
 
 
-NGX_CONFIGURE=`echo $@ | sed 's/"/\\\\"/g'`
-
 . auto/options
 . auto/init
 . auto/sources
@@ -54,6 +52,39 @@
 . auto/modules
 . auto/lib/conf
 
+case ".$NGX_PREFIX" in
+    .)
+        NGX_PREFIX=${NGX_PREFIX:-/usr/local/nginx}
+        have=NGX_PREFIX value="\"$NGX_PREFIX/\"" . auto/define
+    ;;
+
+    .!)
+        NGX_PREFIX=
+    ;;
+
+    *)
+        have=NGX_PREFIX value="\"$NGX_PREFIX/\"" . auto/define
+    ;;
+esac
+
+if [ ".$NGX_CONF_PREFIX" != "." ]; then
+    have=NGX_CONF_PREFIX value="\"$NGX_CONF_PREFIX/\"" . auto/define
+fi
+
+have=NGX_SBIN_PATH value="\"$NGX_SBIN_PATH\"" . auto/define
+have=NGX_CONF_PATH value="\"$NGX_CONF_PATH\"" . auto/define
+have=NGX_PID_PATH value="\"$NGX_PID_PATH\"" . auto/define
+have=NGX_LOCK_PATH value="\"$NGX_LOCK_PATH\"" . auto/define
+have=NGX_ERROR_LOG_PATH value="\"$NGX_ERROR_LOG_PATH\"" . auto/define
+
+have=NGX_HTTP_LOG_PATH value="\"$NGX_HTTP_LOG_PATH\"" . auto/define
+have=NGX_HTTP_CLIENT_TEMP_PATH value="\"$NGX_HTTP_CLIENT_TEMP_PATH\""
+. auto/define
+have=NGX_HTTP_PROXY_TEMP_PATH value="\"$NGX_HTTP_PROXY_TEMP_PATH\""
+. auto/define
+have=NGX_HTTP_FASTCGI_TEMP_PATH value="\"$NGX_HTTP_FASTCGI_TEMP_PATH\""
+. auto/define
+
 . auto/make
 . auto/lib/make
 . auto/install
@@ -65,24 +96,6 @@
 # STUB
 . auto/stubs
 
-have=NGX_PREFIX value="\"$NGX_PREFIX/\"" . auto/define
-have=NGX_SBIN_PATH value="\"$NGX_SBIN_PATH\"" . auto/define
-have=NGX_CONF_PREFIX value="\"$NGX_CONF_PREFIX/\"" . auto/define
-have=NGX_CONF_PATH value="\"$NGX_CONF_PATH\"" . auto/define
-have=NGX_PID_PATH value="\"$NGX_PID_PATH\"" . auto/define
-have=NGX_LOCK_PATH value="\"$NGX_LOCK_PATH\"" . auto/define
-if test -n "$NGX_ERROR_LOG_PATH"; then
-    have=NGX_ERROR_LOG_PATH value="\"$NGX_ERROR_LOG_PATH\"" . auto/define
-fi
-
-have=NGX_HTTP_LOG_PATH value="\"$NGX_HTTP_LOG_PATH\"" . auto/define
-have=NGX_HTTP_CLIENT_TEMP_PATH value="\"$NGX_HTTP_CLIENT_TEMP_PATH\""
-. auto/define
-have=NGX_HTTP_PROXY_TEMP_PATH value="\"$NGX_HTTP_PROXY_TEMP_PATH\""
-. auto/define
-have=NGX_HTTP_FASTCGI_TEMP_PATH value="\"$NGX_HTTP_FASTCGI_TEMP_PATH\""
-. auto/define
-
 have=NGX_USER value="\"$NGX_USER\"" . auto/define
 have=NGX_GROUP value="\"$NGX_GROUP\"" . auto/define
 
--- a/src/core/nginx.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/core/nginx.c	Mon Apr 27 00:00:00 2009 +0400
@@ -10,7 +10,8 @@
 
 
 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
-static ngx_int_t ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv);
+static ngx_int_t ngx_get_options(int argc, char *const *argv);
+static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);
 static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
 static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
 static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
@@ -182,11 +183,13 @@
 
 ngx_uint_t          ngx_max_module;
 
+static ngx_uint_t   ngx_show_help;
 static ngx_uint_t   ngx_show_version;
 static ngx_uint_t   ngx_show_configure;
-#if (NGX_WIN32)
+static u_char      *ngx_prefix;
+static u_char      *ngx_conf_file;
+static u_char      *ngx_conf_params;
 static char        *ngx_signal;
-#endif
 
 
 static char **ngx_os_environ;
@@ -200,6 +203,50 @@
     ngx_cycle_t      *cycle, init_cycle;
     ngx_core_conf_t  *ccf;
 
+    if (ngx_get_options(argc, argv) != NGX_OK) {
+        return 1;
+    }
+
+    if (ngx_show_version) {
+        ngx_log_stderr(0, "nginx version: " NGINX_VER);
+
+        if (ngx_show_help) {
+            ngx_log_stderr(0,
+                "Usage: nginx [-?hvVt] [-s signal] [-c filename] "
+                             "[-g directives]" CRLF CRLF
+                "Options:" CRLF
+                "  -?,-h         : this help" CRLF
+                "  -v            : show version and exit" CRLF
+                "  -V            : show version and configure options then exit"
+                                   CRLF
+                "  -t            : test configuration and exit" CRLF
+                "  -s signal     : send signal to a master process: "
+                                   "stop, quit, reopen, reload" CRLF
+#ifdef NGX_PREFIX
+                "  -p prefix     : set prefix path (default: "
+                                   NGX_PREFIX ")" CRLF
+#else
+                "  -p prefix     : set prefix path (default: NONE)" CRLF
+#endif
+                "  -c filename   : set configuration file (default: "
+                                   NGX_CONF_PATH ")" CRLF
+                "  -g directives : set global directives out of configuration "
+                                   "file" CRLF
+                );
+        }
+
+        if (ngx_show_configure) {
+#ifdef NGX_COMPILER
+            ngx_log_stderr(0, "built by " NGX_COMPILER);
+#endif
+            ngx_log_stderr(0, "configure arguments:" NGX_CONFIGURE);
+        }
+
+        if (!ngx_test_config) {
+            return 0;
+        }
+    }
+
 #if (NGX_FREEBSD)
     ngx_debug_init();
 #endif
@@ -214,7 +261,7 @@
 
     ngx_pid = ngx_getpid();
 
-    log = ngx_log_init();
+    log = ngx_log_init(ngx_prefix);
     if (log == NULL) {
         return 1;
     }
@@ -224,7 +271,10 @@
     ngx_ssl_init(log);
 #endif
 
-    /* init_cycle->log is required for signal handlers and ngx_getopt() */
+    /*
+     * init_cycle->log is required for signal handlers and
+     * ngx_process_options()
+     */
 
     ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
     init_cycle.log = log;
@@ -239,31 +289,10 @@
         return 1;
     }
 
-    if (ngx_getopt(&init_cycle, argc, ngx_argv) != NGX_OK) {
+    if (ngx_process_options(&init_cycle) != NGX_OK) {
         return 1;
     }
 
-    if (ngx_show_version) {
-
-        ngx_log_stderr("nginx version: " NGINX_VER);
-
-        if (ngx_show_configure) {
-#ifdef NGX_COMPILER
-            ngx_log_stderr("built by " NGX_COMPILER);
-#endif
-
-            ngx_log_stderr("configure arguments: " NGX_CONFIGURE);
-        }
-
-        if (!ngx_test_config) {
-            return 0;
-        }
-    }
-
-    if (ngx_test_config) {
-        log->log_level = NGX_LOG_INFO;
-    }
-
     if (ngx_os_init(log) != NGX_OK) {
         return 1;
     }
@@ -288,7 +317,7 @@
     cycle = ngx_init_cycle(&init_cycle);
     if (cycle == NULL) {
         if (ngx_test_config) {
-            ngx_log_stderr("the configuration file %s test failed",
+            ngx_log_stderr(0, "configuration file %s test failed",
                            init_cycle.conf_file.data);
         }
 
@@ -296,7 +325,7 @@
     }
 
     if (ngx_test_config) {
-        ngx_log_stderr("the configuration file %s was tested successfully",
+        ngx_log_stderr(0, "configuration file %s test is successful",
                        cycle->conf_file.data);
         return 0;
     }
@@ -311,13 +340,11 @@
         ngx_process = NGX_PROCESS_MASTER;
     }
 
-#if (NGX_WIN32)
-
     if (ngx_signal) {
         return ngx_signal_process(cycle, ngx_signal);
     }
 
-#else
+#if !(NGX_WIN32)
 
     if (ngx_init_signals(cycle->log) != NGX_OK) {
         return 1;
@@ -337,6 +364,17 @@
         return 1;
     }
 
+    if (cycle->log->file->fd != ngx_stderr) {
+
+        if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
+            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
+                          ngx_set_stderr_n " failed");
+            return 1;
+        }
+    }
+
+    ngx_use_stderr = 0;
+
     if (ngx_process == NGX_PROCESS_SINGLE) {
         ngx_single_process_cycle(cycle);
 
@@ -511,6 +549,8 @@
     ngx_core_conf_t   *ccf;
     ngx_listening_t   *ls;
 
+    ngx_memzero(&ctx, sizeof(ngx_exec_ctx_t));
+
     ctx.path = argv[0];
     ctx.name = "new binary process";
     ctx.argv = argv;
@@ -594,87 +634,118 @@
 
 
 static ngx_int_t
-ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv)
+ngx_get_options(int argc, char *const *argv)
 {
-    ngx_int_t  i;
+    u_char     *p;
+    ngx_int_t   i;
 
     for (i = 1; i < argc; i++) {
-        if (argv[i][0] != '-') {
-            ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
-                          "invalid option: \"%s\"", argv[i]);
+
+        p = (u_char *) argv[i];
+
+        if (*p++ != '-') {
+            ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);
             return NGX_ERROR;
         }
 
-        switch (argv[i][1]) {
+        while (*p) {
+
+            switch (*p++) {
 
-        case 'v':
-            ngx_show_version = 1;
-            break;
+            case '?':
+            case 'h':
+                ngx_show_version = 1;
+                ngx_show_help = 1;
+                break;
+
+            case 'v':
+                ngx_show_version = 1;
+                break;
+
+            case 'V':
+                ngx_show_version = 1;
+                ngx_show_configure = 1;
+                break;
 
-        case 'V':
-            ngx_show_version = 1;
-            ngx_show_configure = 1;
-            break;
+            case 't':
+                ngx_test_config = 1;
+                break;
+
+            case 'p':
+                if (*p) {
+                    ngx_prefix = p;
+                    goto next;
+                }
 
-        case 't':
-            ngx_test_config = 1;
-            break;
+                if (argv[++i]) {
+                    ngx_prefix = (u_char *) argv[i];
+                    goto next;
+                }
+
+                ngx_log_stderr(0, "option \"-p\" requires directory name");
+                return NGX_ERROR;
+
+            case 'c':
+                if (*p) {
+                    ngx_conf_file = p;
+                    goto next;
+                }
 
-        case 'c':
-            if (argv[i + 1] == NULL) {
-                ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
-                              "the option \"-c\" requires file name");
+                if (argv[++i]) {
+                    ngx_conf_file = (u_char *) argv[i];
+                    goto next;
+                }
+
+                ngx_log_stderr(0, "option \"-c\" requires file name");
                 return NGX_ERROR;
-            }
+
+            case 'g':
+                if (*p) {
+                    ngx_conf_params = p;
+                    goto next;
+                }
+
+                if (argv[++i]) {
+                    ngx_conf_params = (u_char *) argv[i];
+                    goto next;
+                }
+
+                ngx_log_stderr(0, "option \"-g\" requires parameter");
+                return NGX_ERROR;
 
-            cycle->conf_file.data = (u_char *) argv[++i];
-            cycle->conf_file.len = ngx_strlen(cycle->conf_file.data);
-            break;
+            case 's':
+                if (*p) {
+                    ngx_signal = (char *) p;
+
+                } else if (argv[++i]) {
+                    ngx_signal = argv[i];
+
+                } else {
+                    ngx_log_stderr(0, "option \"-s\" requires parameter");
+                    return NGX_ERROR;
+                }
 
-        case 'g':
-            if (argv[i + 1] == NULL) {
-                ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
-                              "the option \"-g\" requires parameter");
+                if (ngx_strcmp(ngx_signal, "stop") == 0
+                    || ngx_strcmp(ngx_signal, "quit") == 0
+                    || ngx_strcmp(ngx_signal, "reopen") == 0
+                    || ngx_strcmp(ngx_signal, "reload") == 0)
+                {
+                    ngx_process = NGX_PROCESS_SIGNALLER;
+                    goto next;
+                }
+
+                ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);
+                return NGX_ERROR;
+
+            default:
+                ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));
                 return NGX_ERROR;
             }
-
-            cycle->conf_param.data = (u_char *) argv[++i];
-            cycle->conf_param.len = ngx_strlen(cycle->conf_param.data);
-            break;
-
-#if (NGX_WIN32)
-        case 's':
-            if (argv[++i] == NULL) {
-                ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
-                              "the option \"-s\" requires parameter");
-                return NGX_ERROR;
-            }
+        }
 
-            if (ngx_strcmp(argv[i], "stop") == 0
-                || ngx_strcmp(argv[i], "quit") == 0
-                || ngx_strcmp(argv[i], "reopen") == 0
-                || ngx_strcmp(argv[i], "reload") == 0)
-            {
-                ngx_process = NGX_PROCESS_SIGNALLER;
-                ngx_signal = argv[i];
-                break;
-            }
+    next:
 
-            ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
-                          "invalid option: \"-s %s\"", argv[i]);
-            return NGX_ERROR;
-#endif
-
-        default:
-            ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
-                          "invalid option: \"%s\"", argv[i]);
-            return NGX_ERROR;
-        }
-    }
-
-    if (cycle->conf_file.data == NULL) {
-        cycle->conf_file.len = sizeof(NGX_CONF_PATH) - 1;
-        cycle->conf_file.data = (u_char *) NGX_CONF_PATH;
+        continue;
     }
 
     return NGX_OK;
@@ -723,6 +794,106 @@
 }
 
 
+static ngx_int_t
+ngx_process_options(ngx_cycle_t *cycle)
+{
+    u_char  *p;
+    size_t   len;
+
+    if (ngx_prefix) {
+        len = ngx_strlen(ngx_prefix);
+        p = ngx_prefix;
+
+        if (!ngx_path_separator(*p)) {
+            p = ngx_pnalloc(cycle->pool, len + 1);
+            if (p == NULL) {
+                return NGX_ERROR;
+            }
+
+            ngx_memcpy(p, ngx_prefix, len);
+            p[len++] = '/';
+        }
+
+        cycle->conf_prefix.len = len;
+        cycle->conf_prefix.data = p;
+        cycle->prefix.len = len;
+        cycle->prefix.data = p;
+
+    } else {
+
+#ifndef NGX_PREFIX
+
+        p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH);
+        if (p == NULL) {
+            return NGX_ERROR;
+        }
+
+        if (ngx_getcwd(p, NGX_MAX_PATH) == 0) {
+            ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed");
+            return NGX_ERROR;
+        }
+
+        len = ngx_strlen(p);
+
+        p[len++] = '/';
+
+        cycle->conf_prefix.len = len;
+        cycle->conf_prefix.data = p;
+        cycle->prefix.len = len;
+        cycle->prefix.data = p;
+
+#else
+
+#ifdef NGX_CONF_PREFIX
+        cycle->conf_prefix.len = sizeof(NGX_CONF_PREFIX) - 1;
+        cycle->conf_prefix.data = (u_char *) NGX_CONF_PREFIX;
+#else
+        cycle->conf_prefix.len = sizeof(NGX_PREFIX) - 1;
+        cycle->conf_prefix.data = (u_char *) NGX_PREFIX;
+#endif
+        cycle->prefix.len = sizeof(NGX_PREFIX) - 1;
+        cycle->prefix.data = (u_char *) NGX_PREFIX;
+
+#endif
+    }
+
+    if (ngx_conf_file) {
+        cycle->conf_file.len = ngx_strlen(ngx_conf_file);
+        cycle->conf_file.data = ngx_conf_file;
+
+    } else {
+        cycle->conf_file.len = sizeof(NGX_CONF_PATH) - 1;
+        cycle->conf_file.data = (u_char *) NGX_CONF_PATH;
+    }
+
+    if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    for (p = cycle->conf_file.data + cycle->conf_file.len - 1;
+         p > cycle->conf_file.data;
+         p--)
+    {
+        if (ngx_path_separator(*p)) {
+            cycle->conf_prefix.len = p - ngx_cycle->conf_file.data + 1;
+            cycle->conf_prefix.data = ngx_cycle->conf_file.data;
+            break;
+        }
+    }
+
+    if (ngx_conf_params) {
+        cycle->conf_param.len = ngx_strlen(ngx_conf_params);
+        cycle->conf_param.data = ngx_conf_params;
+    }
+
+    if (ngx_test_config) {
+        cycle->log->log_level = NGX_LOG_INFO;
+    }
+
+    return NGX_OK;
+}
+
+
 static void *
 ngx_core_module_create_conf(ngx_cycle_t *cycle)
 {
--- a/src/core/nginx.h	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/core/nginx.h	Mon Apr 27 00:00:00 2009 +0400
@@ -8,8 +8,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version         7052
-#define NGINX_VERSION      "0.7.52"
+#define nginx_version         7053
+#define NGINX_VERSION      "0.7.53"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_conf_file.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/core/ngx_conf_file.c	Mon Apr 27 00:00:00 2009 +0400
@@ -798,10 +798,6 @@
     u_char     *p, *prefix;
     ngx_str_t   old;
 
-    if (name->data[0] == '/') {
-        return NGX_OK;
-    }
-
 #if (NGX_WIN32)
 
     if (name->len > 2
@@ -812,17 +808,23 @@
         return NGX_OK;
     }
 
+#else
+
+    if (name->data[0] == '/') {
+        return NGX_OK;
+    }
+
 #endif
 
     old = *name;
 
     if (conf_prefix) {
-        len = sizeof(NGX_CONF_PREFIX) - 1;
-        prefix = (u_char *) NGX_CONF_PREFIX;
+        len = cycle->conf_prefix.len;
+        prefix = cycle->conf_prefix.data;
 
     } else {
-        len = cycle->root.len;
-        prefix = cycle->root.data;
+        len = cycle->prefix.len;
+        prefix = cycle->prefix.data;
     }
 
     name->len = len + old.len;
@@ -851,7 +853,7 @@
     full.data = NULL;
 #endif
 
-    if (name) {
+    if (name && name->len) {
         full = *name;
 
         if (ngx_conf_full_name(cycle, &full, 0) != NGX_OK) {
@@ -887,12 +889,12 @@
         return NULL;
     }
 
-    if (name) {
+    if (name && name->len) {
         file->fd = NGX_INVALID_FILE;
         file->name = full;
 
     } else {
-        file->fd = ngx_stderr_fileno;
+        file->fd = ngx_stderr;
         file->name.len = 0;
         file->name.data = NULL;
     }
--- a/src/core/ngx_cycle.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/core/ngx_cycle.c	Mon Apr 27 00:00:00 2009 +0400
@@ -34,11 +34,7 @@
 static ngx_connection_t  dumb;
 /* STUB */
 
-#ifdef NGX_ERROR_LOG_PATH
 static ngx_str_t  error_log = ngx_string(NGX_ERROR_LOG_PATH);
-#else
-static ngx_str_t  error_log = ngx_null_string;
-#endif
 
 
 ngx_cycle_t *
@@ -87,9 +83,20 @@
     cycle->pool = pool;
     cycle->log = log;
     cycle->old_cycle = old_cycle;
-    cycle->root.len = sizeof(NGX_PREFIX) - 1;
-    cycle->root.data = (u_char *) NGX_PREFIX;
 
+    cycle->conf_prefix.len = old_cycle->conf_prefix.len;
+    cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
+    if (cycle->conf_prefix.data == NULL) {
+        ngx_destroy_pool(pool);
+        return NULL;
+    }
+
+    cycle->prefix.len = old_cycle->prefix.len;
+    cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
+    if (cycle->prefix.data == NULL) {
+        ngx_destroy_pool(pool);
+        return NULL;
+    }
 
     cycle->conf_file.len = old_cycle->conf_file.len;
     cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
@@ -100,15 +107,12 @@
     ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
                 old_cycle->conf_file.len + 1);
 
-
     cycle->conf_param.len = old_cycle->conf_param.len;
-    cycle->conf_param.data = ngx_pnalloc(pool, old_cycle->conf_param.len);
+    cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
     if (cycle->conf_param.data == NULL) {
         ngx_destroy_pool(pool);
         return NULL;
     }
-    ngx_memcpy(cycle->conf_param.data, old_cycle->conf_param.data,
-               old_cycle->conf_param.len);
 
 
     n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10;
@@ -162,14 +166,12 @@
     }
 
 
-    cycle->new_log = ngx_log_create_errlog(cycle, NULL);
+    cycle->new_log = ngx_log_create_errlog(cycle, &error_log);
     if (cycle->new_log == NULL) {
         ngx_destroy_pool(pool);
         return NULL;
     }
 
-    cycle->new_log->file->name = error_log;
-
 
     n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
 
@@ -270,7 +272,7 @@
     }
 
     if (ngx_test_config) {
-        ngx_log_stderr("the configuration file %s syntax is ok",
+        ngx_log_stderr(0, "the configuration file %s syntax is ok",
                        cycle->conf_file.data);
     }
 
@@ -350,7 +352,7 @@
             i = 0;
         }
 
-        if (file[i].name.data == NULL) {
+        if (file[i].name.len == 0) {
             continue;
         }
 
@@ -467,9 +469,9 @@
 
         if (!shm_zone[i].shm.exists) {
 
-	    if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
-		goto failed;
-	    }
+            if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
+                goto failed;
+            }
         }
 
         if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
@@ -569,36 +571,27 @@
         }
     }
 
-    if (ngx_open_listening_sockets(cycle) != NGX_OK) {
-        goto failed;
-    }
+    if (ngx_process != NGX_PROCESS_SIGNALLER) {
+        if (ngx_open_listening_sockets(cycle) != NGX_OK) {
+            goto failed;
+        }
 
-    if (!ngx_test_config) {
-        ngx_configure_listening_socket(cycle);
+        if (!ngx_test_config) {
+            ngx_configure_listening_socket(cycle);
+        }
     }
 
 
     /* commit the new cycle configuration */
 
-#if !(NGX_WIN32)
-
-    if (!ngx_test_config && cycle->log->file->fd != STDERR_FILENO) {
+    if (!ngx_use_stderr && cycle->log->file->fd != ngx_stderr) {
 
-        ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
-                       "dup2: %p %d \"%s\"",
-                       cycle->log->file,
-                       cycle->log->file->fd, cycle->log->file->name.data);
-
-        if (dup2(cycle->log->file->fd, STDERR_FILENO) == -1) {
-            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
-                          "dup2(STDERR) failed");
-            /* fatal */
-            exit(1);
+        if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
+            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                          ngx_set_stderr_n " failed");
         }
     }
 
-#endif
-
     pool->log = cycle->log;
 
     for (i = 0; ngx_modules[i]; i++) {
@@ -695,7 +688,7 @@
             i = 0;
         }
 
-        if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr_fileno) {
+        if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
             continue;
         }
 
@@ -795,7 +788,7 @@
             i = 0;
         }
 
-        if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr_fileno) {
+        if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
             continue;
         }
 
@@ -907,7 +900,7 @@
 
     file = ngx_pnalloc(cycle->pool, cycle->lock_file.len + zn->shm.name.len);
     if (file == NULL) {
-	return NGX_ERROR;
+        return NGX_ERROR;
     }
 
     (void) ngx_sprintf(file, "%V%V%Z", &cycle->lock_file, &zn->shm.name);
@@ -915,7 +908,7 @@
 #endif
 
     if (ngx_shmtx_create(&sp->mutex, (void *) &sp->lock, file) != NGX_OK) {
-	return NGX_ERROR;
+        return NGX_ERROR;
     }
 
     ngx_slab_init(sp);
@@ -986,6 +979,58 @@
 }
 
 
+ngx_int_t
+ngx_signal_process(ngx_cycle_t *cycle, char *sig)
+{
+    ssize_t           n;
+    ngx_int_t         pid;
+    ngx_file_t        file;
+    ngx_core_conf_t  *ccf;
+    u_char            buf[NGX_INT64_LEN + 2];
+
+    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
+
+    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+    file.name = ccf->pid;
+    file.log = cycle->log;
+
+    file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
+                            NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
+
+    if (file.fd == NGX_INVALID_FILE) {
+        ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
+                      ngx_open_file_n " \"%s\" failed", file.name.data);
+        return 1;
+    }
+
+    n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
+
+    if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                      ngx_close_file_n " \"%s\" failed", file.name.data);
+    }
+
+    if (n == NGX_ERROR) {
+        return 1;
+    }
+
+    while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
+
+    pid = ngx_atoi(buf, ++n);
+
+    if (pid == NGX_ERROR) {
+        ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
+                      "invalid PID number \"%*s\" in \"%s\"",
+                      n, buf, file.name.data);
+        return 1;
+    }
+
+    return ngx_os_signal_process(cycle, sig, pid);
+
+}
+
+
 static ngx_int_t
 ngx_test_lockfile(u_char *file, ngx_log_t *log)
 {
@@ -1040,7 +1085,7 @@
             i = 0;
         }
 
-        if (file[i].name.data == NULL) {
+        if (file[i].name.len == 0) {
             continue;
         }
 
--- a/src/core/ngx_cycle.h	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/core/ngx_cycle.h	Mon Apr 27 00:00:00 2009 +0400
@@ -60,7 +60,8 @@
 
     ngx_str_t                 conf_file;
     ngx_str_t                 conf_param;
-    ngx_str_t                 root;
+    ngx_str_t                 conf_prefix;
+    ngx_str_t                 prefix;
     ngx_str_t                 lock_file;
     ngx_str_t                 hostname;
 };
@@ -116,6 +117,7 @@
 ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle);
 ngx_int_t ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log);
 void ngx_delete_pidfile(ngx_cycle_t *cycle);
+ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig);
 void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user);
 char **ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last);
 ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
--- a/src/core/ngx_log.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/core/ngx_log.c	Mon Apr 27 00:00:00 2009 +0400
@@ -48,12 +48,20 @@
 
 
 static ngx_log_t        ngx_log;
-static ngx_open_file_t  ngx_stderr;
+static ngx_open_file_t  ngx_log_file;
+ngx_uint_t              ngx_use_stderr = 1;
 
 
-static const char *err_levels[] = {
-    "stderr", "emerg", "alert", "crit", "error",
-    "warn", "notice", "info", "debug"
+static ngx_str_t err_levels[] = {
+    ngx_string("stderr"),
+    ngx_string("emerg"),
+    ngx_string("alert"),
+    ngx_string("crit"),
+    ngx_string("error"),
+    ngx_string("warn"),
+    ngx_string("notice"),
+    ngx_string("info"),
+    ngx_string("debug")
 };
 
 static const char *debug_levels[] = {
@@ -79,7 +87,8 @@
 #if (NGX_HAVE_VARIADIC_MACROS)
     va_list  args;
 #endif
-    u_char   errstr[NGX_MAX_ERROR_STR], *p, *last;
+    u_char  *p, *last, *msg;
+    u_char   errstr[NGX_MAX_ERROR_STR];
 
     if (log->file->fd == NGX_INVALID_FILE) {
         return;
@@ -92,7 +101,7 @@
 
     p = errstr + ngx_cached_err_log_time.len;
 
-    p = ngx_snprintf(p, last - p, " [%s] ", err_levels[level]);
+    p = ngx_snprintf(p, last - p, " [%V] ", &err_levels[level]);
 
     /* pid#tid */
     p = ngx_snprintf(p, last - p, "%P#" NGX_TID_T_FMT ": ",
@@ -102,6 +111,8 @@
         p = ngx_snprintf(p, last - p, "*%uA ", log->connection);
     }
 
+    msg = p;
+
 #if (NGX_HAVE_VARIADIC_MACROS)
 
     va_start(args, fmt);
@@ -151,6 +162,19 @@
     ngx_linefeed(p);
 
     (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
+
+    if (!ngx_use_stderr
+        || level > NGX_LOG_WARN
+        || log->file->fd == ngx_stderr)
+    {
+        return;
+    }
+
+    msg -= (err_levels[level].len + 4);
+
+    (void) ngx_sprintf(msg, "[%V]: ", &err_levels[level]);
+
+    (void) ngx_write_fd(ngx_stderr, msg, p - msg);
 }
 
 
@@ -183,17 +207,26 @@
 #endif
 
 
-void
-ngx_log_abort(ngx_err_t err, const char *text, void *param)
+void ngx_cdecl
+ngx_log_abort(ngx_err_t err, const char *fmt, ...)
 {
-    ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, text, param);
+    u_char   *p;
+    va_list   args;
+    u_char    errstr[NGX_MAX_CONF_ERRSTR];
+
+    va_start(args, fmt);
+    p = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args);
+    va_end(args);
+
+    ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
+                  "%*s", p - errstr, errstr);
 }
 
 
 void ngx_cdecl
-ngx_log_stderr(const char *fmt, ...)
+ngx_log_stderr(ngx_err_t err, const char *fmt, ...)
 {
-    u_char   *p;
+    u_char   *p, *last;
     va_list   args;
     u_char    errstr[NGX_MAX_ERROR_STR];
 
@@ -205,57 +238,129 @@
         p = errstr + NGX_MAX_ERROR_STR - NGX_LINEFEED_SIZE;
     }
 
+    if (err) {
+
+        last = errstr + NGX_MAX_ERROR_STR;
+
+        if (p > last - 50) {
+
+            /* leave a space for an error code */
+
+            p = last - 50;
+            *p++ = '.';
+            *p++ = '.';
+            *p++ = '.';
+        }
+
+#if (NGX_WIN32)
+        p = ngx_snprintf(p, last - p, ((unsigned) err < 0x80000000)
+                                           ? " (%d: " : " (%Xd: ", err);
+#else
+        p = ngx_snprintf(p, last - p, " (%d: ", err);
+#endif
+
+        p = ngx_strerror_r(err, p, last - p);
+
+        if (p < last) {
+            *p++ = ')';
+        }
+    }
+
     ngx_linefeed(p);
 
-    (void) ngx_write_fd(ngx_stderr_fileno, errstr, p - errstr);
+    (void) ngx_write_fd(ngx_stderr, errstr, p - errstr);
 }
 
 
 ngx_log_t *
-ngx_log_init(void)
+ngx_log_init(u_char *prefix)
 {
-    ngx_log.file = &ngx_stderr;
+    u_char  *p, *name;
+    size_t   nlen, plen;
+
+    ngx_log.file = &ngx_log_file;
     ngx_log.log_level = NGX_LOG_NOTICE;
 
+    name = (u_char *) NGX_ERROR_LOG_PATH;
+
+    /*
+     * we use ngx_strlen() here since BCC warns about
+     * condition is always false and unreachable code
+     */
+
+    nlen = ngx_strlen(name);
+
+    if (nlen == 0) {
+        ngx_log_file.fd = ngx_stderr;
+        return &ngx_log;
+    }
+
+    p = NULL;
+
 #if (NGX_WIN32)
+    if (name[1] != ':') {
+#else
+    if (name[0] != '/') {
+#endif
+        plen = 0;
 
-    ngx_stderr_fileno = GetStdHandle(STD_ERROR_HANDLE);
+        if (prefix) {
+            plen = ngx_strlen(prefix);
+
+#ifdef NGX_PREFIX
+        } else {
+            prefix = (u_char *) NGX_PREFIX;
+            plen = ngx_strlen(prefix);
+#endif
+        }
 
-    ngx_stderr.fd = ngx_open_file((u_char *) NGX_ERROR_LOG_PATH,
-                                  NGX_FILE_APPEND,
-                                  NGX_FILE_CREATE_OR_OPEN,
-                                  NGX_FILE_DEFAULT_ACCESS);
+        if (plen) {
+            name = malloc(plen + nlen + 2);
+            if (name == NULL) {
+                return NULL;
+            }
+
+            p = ngx_cpymem(name, prefix, plen);
 
-    if (ngx_stderr.fd == NGX_INVALID_FILE) {
-        ngx_event_log(ngx_errno, 
-                      "Could not open error log file: "
-                      ngx_open_file_n " \"" NGX_ERROR_LOG_PATH "\" failed");
-        return NULL;
+            if (!ngx_path_separator(*(p - 1))) {
+                *p++ = '/';
+            }
+
+            ngx_cpystrn(p, (u_char *) NGX_ERROR_LOG_PATH, nlen + 1);
+
+            p = name;
+        }
     }
 
-#else
+    ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,
+                                    NGX_FILE_CREATE_OR_OPEN,
+                                    NGX_FILE_DEFAULT_ACCESS);
 
-    ngx_stderr.fd = STDERR_FILENO;
+    if (ngx_log_file.fd == NGX_INVALID_FILE) {
+        ngx_log_stderr(ngx_errno,
+                       "[alert]: could not open error log file: "
+                       ngx_open_file_n " \"%s\" failed", name);
+#if (NGX_WIN32)
+        ngx_event_log(ngx_errno,
+                       "could not open error log file: "
+                       ngx_open_file_n " \"%s\" failed", name);
+#endif
 
-#endif
+        ngx_log_file.fd = ngx_stderr;
+    }
+
+    if (p) {
+        ngx_free(p);
+    }
 
     return &ngx_log;
 }
 
 
 ngx_log_t *
-ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args)
+ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_str_t *name)
 {
     ngx_log_t  *log;
-    ngx_str_t  *value, *name;
-
-    if (args) {
-        value = args->elts;
-        name = &value[1];
-
-    } else {
-        name = NULL;
-    }
 
     log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t));
     if (log == NULL) {
@@ -282,12 +387,12 @@
     for (i = 2; i < cf->args->nelts; i++) {
 
         for (n = 1; n <= NGX_LOG_DEBUG; n++) {
-            if (ngx_strcmp(value[i].data, err_levels[n]) == 0) {
+            if (ngx_strcmp(value[i].data, err_levels[n].data) == 0) {
 
                 if (log->log_level != 0) {
                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                                       "duplicate log level \"%s\"",
-                                       value[i].data);
+                                       "duplicate log level \"%V\"",
+                                       &value[i]);
                     return NGX_CONF_ERROR;
                 }
 
@@ -300,8 +405,8 @@
             if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) {
                 if (log->log_level & ~NGX_LOG_DEBUG_ALL) {
                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                                       "invalid log level \"%s\"",
-                                       value[i].data);
+                                       "invalid log level \"%V\"",
+                                       &value[i]);
                     return NGX_CONF_ERROR;
                 }
 
@@ -312,7 +417,7 @@
 
         if (log->log_level == 0) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                               "invalid log level \"%s\"", value[i].data);
+                               "invalid log level \"%V\"", &value[i]);
             return NGX_CONF_ERROR;
         }
     }
@@ -336,7 +441,7 @@
     value = cf->args->elts;
 
     if (value[1].len == 6 && ngx_strcmp(value[1].data, "stderr") == 0) {
-        cf->cycle->new_log->file->fd = ngx_stderr.fd;
+        cf->cycle->new_log->file->fd = ngx_stderr;
         cf->cycle->new_log->file->name.len = 0;
         cf->cycle->new_log->file->name.data = NULL;
 
--- a/src/core/ngx_log.h	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/core/ngx_log.h	Mon Apr 27 00:00:00 2009 +0400
@@ -195,14 +195,15 @@
 
 /*********************************/
 
-ngx_log_t *ngx_log_init(void);
-ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args);
+ngx_log_t *ngx_log_init(u_char *prefix);
+ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_str_t *name);
 char *ngx_set_error_log_levels(ngx_conf_t *cf, ngx_log_t *log);
-void ngx_log_abort(ngx_err_t err, const char *text, void *param);
-void ngx_cdecl ngx_log_stderr(const char *fmt, ...);
+void ngx_cdecl ngx_log_abort(ngx_err_t err, const char *fmt, ...);
+void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...);
 
 
 extern ngx_module_t  ngx_errlog_module;
+extern ngx_uint_t    ngx_use_stderr;
 
 
 #endif /* _NGX_LOG_H_INCLUDED_ */
--- a/src/core/ngx_open_file_cache.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/core/ngx_open_file_cache.c	Mon Apr 27 00:00:00 2009 +0400
@@ -130,6 +130,7 @@
     time_t                          now;
     uint32_t                        hash;
     ngx_int_t                       rc;
+    ngx_file_info_t                 fi;
     ngx_pool_cleanup_t             *cln;
     ngx_cached_open_file_t         *file;
     ngx_pool_cleanup_file_t        *clnf;
@@ -140,6 +141,25 @@
 
     if (cache == NULL) {
 
+        if (of->test_only) {
+
+            if (ngx_file_info(name->data, &fi) == -1) {
+                of->err = ngx_errno;
+                of->failed = ngx_file_info_n;
+                return NGX_ERROR;
+            }
+
+            of->uniq = ngx_file_uniq(&fi);
+            of->mtime = ngx_file_mtime(&fi);
+            of->size = ngx_file_size(&fi);
+            of->is_dir = ngx_is_dir(&fi);
+            of->is_file = ngx_is_file(&fi);
+            of->is_link = ngx_is_link(&fi);
+            of->is_exec = ngx_is_exec(&fi);
+
+            return NGX_OK;
+        }
+
         cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t));
         if (cln == NULL) {
             return NGX_ERROR;
@@ -444,6 +464,7 @@
     if (of->fd != NGX_INVALID_FILE) {
 
         if (ngx_file_info(name, &fi) == -1) {
+            of->failed = ngx_file_info_n;
             goto failed;
         }
 
@@ -454,6 +475,7 @@
     } else if (of->test_dir) {
 
         if (ngx_file_info(name, &fi) == -1) {
+            of->failed = ngx_file_info_n;
             goto failed;
         }
 
@@ -471,6 +493,7 @@
     }
 
     if (fd == NGX_INVALID_FILE) {
+        of->failed = ngx_open_file_n;
         goto failed;
     }
 
--- a/src/core/ngx_open_file_cache.h	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/core/ngx_open_file_cache.h	Mon Apr 27 00:00:00 2009 +0400
@@ -21,13 +21,16 @@
     time_t                   mtime;
     off_t                    size;
     off_t                    directio;
+
     ngx_err_t                err;
+    char                    *failed;
 
     time_t                   valid;
 
     ngx_uint_t               min_uses;
 
     unsigned                 test_dir:1;
+    unsigned                 test_only:1;
     unsigned                 log:1;
     unsigned                 errors:1;
     unsigned                 events:1;
--- a/src/http/modules/ngx_http_fastcgi_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/modules/ngx_http_fastcgi_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -330,7 +330,7 @@
       offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_valid),
       NULL },
 
-    { ngx_string("proxy_cache_min_uses"),
+    { ngx_string("fastcgi_cache_min_uses"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_num_slot,
       NGX_HTTP_LOC_CONF_OFFSET,
--- a/src/http/modules/ngx_http_flv_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/modules/ngx_http_flv_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -143,7 +143,7 @@
 
         if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
             ngx_log_error(level, log, of.err,
-                          ngx_open_file_n " \"%s\" failed", path.data);
+                          "%s \"%s\" failed", of.failed, path.data);
         }
 
         return rc;
--- a/src/http/modules/ngx_http_gzip_static_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/modules/ngx_http_gzip_static_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -152,7 +152,7 @@
         }
 
         ngx_log_error(level, log, of.err,
-                      ngx_open_file_n " \"%s\" failed", path.data);
+                      "%s \"%s\" failed", of.failed, path.data);
 
         return NGX_DECLINED;
     }
--- a/src/http/modules/ngx_http_index_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/modules/ngx_http_index_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -83,13 +83,13 @@
 
 
 /*
- * Try to open the first index file before the test of the directory existence
- * because the valid requests should be many more than invalid ones.
- * If open() would fail, then stat() should be more quickly because some data
- * is already cached in the kernel.
- * Besides, Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR).
- * Unix has ENOTDIR error, although it less helpfull - it points only
- * that path contains the usual file in place of the directory.
+ * Try to open/test the first index file before the test of directory
+ * existence because valid requests should be much more than invalid ones.
+ * If the file open()/stat() would fail, then the directory stat() should
+ * be more quickly because some data is already cached in the kernel.
+ * Besides, Win32 may return ERROR_PATH_NOT_FOUND (NGX_ENOTDIR) at once.
+ * Unix has ENOTDIR error, however, it's less helpful than Win32's one:
+ * it only indicates that path contains an usual file in place of directory.
  */
 
 static ngx_int_t
@@ -208,14 +208,15 @@
         of.directio = clcf->directio;
         of.valid = clcf->open_file_cache_valid;
         of.min_uses = clcf->open_file_cache_min_uses;
+        of.test_only = 1;
         of.errors = clcf->open_file_cache_errors;
         of.events = clcf->open_file_cache_events;
 
         if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
             != NGX_OK)
         {
-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err,
-                           ngx_open_file_n " \"%s\" failed", path.data);
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err,
+                           "%s \"%s\" failed", of.failed, path.data);
 
             if (of.err == 0) {
                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -239,8 +240,8 @@
                 continue;
             }
 
-            ngx_log_error(NGX_LOG_ERR, r->connection->log, of.err,
-                          ngx_open_file_n " \"%s\" failed", path.data);
+            ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
+                          "%s \"%s\" failed", of.failed, path.data);
 
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
@@ -291,6 +292,7 @@
     ngx_memzero(&of, sizeof(ngx_open_file_info_t));
 
     of.test_dir = 1;
+    of.test_only = 1;
     of.valid = clcf->open_file_cache_valid;
     of.errors = clcf->open_file_cache_errors;
 
@@ -318,7 +320,7 @@
             }
 
             ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
-                          ngx_open_file_n " \"%s\" failed", dir.data);
+                          "%s \"%s\" failed", of.failed, dir.data);
         }
 
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
--- a/src/http/modules/ngx_http_log_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/modules/ngx_http_log_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -385,6 +385,8 @@
 
         of.valid = clcf->open_file_cache_valid;
         of.min_uses = clcf->open_file_cache_min_uses;
+        of.test_dir = 1;
+        of.test_only = 1;
         of.errors = clcf->open_file_cache_errors;
         of.events = clcf->open_file_cache_events;
 
@@ -439,7 +441,7 @@
         != NGX_OK)
     {
         ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
-                      ngx_open_file_n " \"%s\" failed", log.data);
+                      "%s \"%s\" failed", of.failed, log.data);
         /* simulate successfull logging */
         return len;
     }
--- a/src/http/modules/ngx_http_proxy_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/modules/ngx_http_proxy_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -2192,6 +2192,12 @@
         conf->proxy_values = prev->proxy_values;
     }
 
+#if (NGX_HTTP_SSL)
+    if (conf->upstream.ssl == NULL) {
+        conf->upstream.ssl = prev->upstream.ssl;
+    }
+#endif
+
     ngx_conf_merge_uint_value(conf->headers_hash_max_size,
                               prev->headers_hash_max_size, 512);
 
--- a/src/http/modules/ngx_http_static_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/modules/ngx_http_static_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -128,7 +128,7 @@
 
         if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
             ngx_log_error(level, log, of.err,
-                          ngx_open_file_n " \"%s\" failed", path.data);
+                          "%s \"%s\" failed", of.failed, path.data);
         }
 
         return rc;
--- a/src/http/modules/perl/nginx.pm	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/modules/perl/nginx.pm	Mon Apr 27 00:00:00 2009 +0400
@@ -47,7 +47,7 @@
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '0.7.52';
+our $VERSION = '0.7.53';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/modules/perl/nginx.xs	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/modules/perl/nginx.xs	Mon Apr 27 00:00:00 2009 +0400
@@ -662,7 +662,7 @@
         }
 
         ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
-                      ngx_open_file_n " \"%s\" failed", filename);
+                      "%s \"%s\" failed", of.failed, filename);
         XSRETURN_EMPTY;
     }
 
--- a/src/http/ngx_http_core_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/ngx_http_core_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -1169,6 +1169,7 @@
         of.directio = clcf->directio;
         of.valid = clcf->open_file_cache_valid;
         of.min_uses = clcf->open_file_cache_min_uses;
+        of.test_only = 1;
         of.errors = clcf->open_file_cache_errors;
         of.events = clcf->open_file_cache_events;
 
@@ -1177,7 +1178,7 @@
         {
             if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
                 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
-                              ngx_open_file_n " \"%s\" failed", path.data);
+                              "%s \"%s\" failed", of.failed, path.data);
             }
 
             continue;
@@ -4101,7 +4102,11 @@
 {
     ngx_http_core_loc_conf_t *lcf = conf;
 
-    lcf->err_log = ngx_log_create_errlog(cf->cycle, cf->args);
+    ngx_str_t  *value;
+
+    value = cf->args->elts;
+
+    lcf->err_log = ngx_log_create_errlog(cf->cycle, &value[1]);
     if (lcf->err_log == NULL) {
         return NGX_CONF_ERROR;
     }
--- a/src/http/ngx_http_parse.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/ngx_http_parse.c	Mon Apr 27 00:00:00 2009 +0400
@@ -1337,12 +1337,7 @@
         goto unsafe;
     }
 
-    if (p[0] == '.' && len == 3 && p[1] == '.' && (p[2] == '/'
-#if (NGX_WIN32)
-                                                   || p[2] == '\\'
-#endif
-        ))
-    {
+    if (p[0] == '.' && len == 3 && p[1] == '.' && (ngx_path_separator(p[2]))) {
         goto unsafe;
     }
 
@@ -1367,30 +1362,22 @@
             continue;
         }
 
-        if ((ch == '/'
-#if (NGX_WIN32)
-             || ch == '\\'
-#endif
-            ) && len > 2)
-        {
+        if (ngx_path_separator(ch) && len > 2) {
+
             /* detect "/../" */
 
-            if (p[0] == '.' && p[1] == '.' && p[2] == '/') {
+            if (p[0] == '.' && p[1] == '.' && ngx_path_separator(p[2])) {
                 goto unsafe;
             }
 
 #if (NGX_WIN32)
 
-            if (p[2] == '\\') {
-                goto unsafe;
-            }
-
             if (len > 3) {
 
                 /* detect "/.../" */
 
                 if (p[0] == '.' && p[1] == '.' && p[2] == '.'
-                    && (p[3] == '/' || p[3] == '\\'))
+                    && ngx_path_separator(p[3]))
                 {
                     goto unsafe;
                 }
--- a/src/http/ngx_http_request.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/ngx_http_request.c	Mon Apr 27 00:00:00 2009 +0400
@@ -1587,15 +1587,9 @@
             continue;
         }
 
-        if (ch == '/' || ch == '\0') {
+        if (ngx_path_separator(ch) || ch == '\0') {
             return -1;
         }
-
-#if (NGX_WIN32)
-        if (ch == '\\') {
-            return -1;
-        }
-#endif
     }
 
     if (dot) {
--- a/src/http/ngx_http_script.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/ngx_http_script.c	Mon Apr 27 00:00:00 2009 +0400
@@ -1213,7 +1213,7 @@
     }
 
     code->code = (ngx_http_script_code_pt) ngx_http_script_full_name_len_code;
-    code->prefix = sc->conf_prefix;
+    code->conf_prefix = sc->conf_prefix;
 
     code = ngx_http_script_add_code(*sc->values,
                                     sizeof(ngx_http_script_full_name_code_t),
@@ -1223,7 +1223,7 @@
     }
 
     code->code = ngx_http_script_full_name_code;
-    code->prefix = sc->conf_prefix;
+    code->conf_prefix = sc->conf_prefix;
 
     return NGX_OK;
 }
@@ -1238,7 +1238,8 @@
 
     e->ip += sizeof(ngx_http_script_full_name_code_t);
 
-    return code->prefix ? sizeof(NGX_CONF_PREFIX) : ngx_cycle->root.len;
+    return code->conf_prefix ? ngx_cycle->conf_prefix.len:
+                               ngx_cycle->prefix.len;
 }
 
 
@@ -1254,7 +1255,7 @@
     value.data = e->buf.data;
     value.len = e->pos - e->buf.data;
 
-    if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->prefix)
+    if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &value, code->conf_prefix)
         != NGX_OK)
     {
         e->ip = ngx_http_script_exit;
@@ -1413,6 +1414,7 @@
     of.directio = clcf->directio;
     of.valid = clcf->open_file_cache_valid;
     of.min_uses = clcf->open_file_cache_min_uses;
+    of.test_only = 1;
     of.errors = clcf->open_file_cache_errors;
     of.events = clcf->open_file_cache_events;
 
@@ -1421,7 +1423,7 @@
     {
         if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) {
             ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
-                          ngx_file_info_n " \"%s\" failed", value->data);
+                          "%s \"%s\" failed", of.failed, value->data);
         }
 
         switch (code->op) {
--- a/src/http/ngx_http_script.h	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/ngx_http_script.h	Mon Apr 27 00:00:00 2009 +0400
@@ -153,7 +153,7 @@
 
 typedef struct {
     ngx_http_script_code_pt     code;
-    uintptr_t                   prefix;
+    uintptr_t                   conf_prefix;
 } ngx_http_script_full_name_code_t;
 
 
--- a/src/http/ngx_http_upstream.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/ngx_http_upstream.c	Mon Apr 27 00:00:00 2009 +0400
@@ -353,7 +353,9 @@
 
     u = r->upstream;
 
-    if (!r->post_action && !u->conf->ignore_client_abort) {
+    u->store = (u->conf->store || u->conf->store_lengths);
+
+    if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
         r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
         r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
     }
@@ -439,8 +441,6 @@
     cln->data = r;
     u->cleanup = &cln->handler;
 
-    u->store = (u->conf->store || u->conf->store_lengths);
-
     if (u->resolved == NULL) {
 
         uscf = u->conf->upstream;
@@ -779,8 +779,10 @@
     u = r->upstream;
 
     if (c->error) {
-        ngx_http_upstream_finalize_request(r, u,
-                                           NGX_HTTP_CLIENT_CLOSED_REQUEST);
+        if (!u->cacheable) {
+            ngx_http_upstream_finalize_request(r, u,
+                                               NGX_HTTP_CLIENT_CLOSED_REQUEST);
+        }
         return;
     }
 
@@ -803,7 +805,7 @@
             ev->error = 1;
         }
 
-        if (!u->cacheable && !u->store && u->peer.connection) {
+        if (!u->cacheable && u->peer.connection) {
             ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
                           "kevent() reported that client closed prematurely "
                           "connection, so upstream connection is closed too");
@@ -869,7 +871,7 @@
     ev->eof = 1;
     c->error = 1;
 
-    if (!u->cacheable && !u->store && u->peer.connection) {
+    if (!u->cacheable && u->peer.connection) {
         ngx_log_error(NGX_LOG_INFO, ev->log, err,
                       "client closed prematurely connection, "
                       "so upstream connection is closed too");
@@ -2486,7 +2488,7 @@
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "http upstream downstream error");
 
-        if (!u->cacheable && u->peer.connection) {
+        if (!u->cacheable && !u->store && u->peer.connection) {
             ngx_http_upstream_finalize_request(r, u, 0);
         }
     }
--- a/src/http/ngx_http_upstream.h	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/http/ngx_http_upstream.h	Mon Apr 27 00:00:00 2009 +0400
@@ -162,7 +162,7 @@
 
 #if (NGX_HTTP_SSL)
     ngx_ssl_t                       *ssl;
-    ngx_flag_t                      ssl_session_reuse;
+    ngx_flag_t                       ssl_session_reuse;
 #endif
 
 } ngx_http_upstream_conf_t;
--- a/src/mail/ngx_mail_auth_http_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/mail/ngx_mail_auth_http_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -139,6 +139,7 @@
 static ngx_str_t   ngx_mail_auth_http_method[] = {
     ngx_string("plain"),
     ngx_string("plain"),
+    ngx_string("plain"),
     ngx_string("apop"),
     ngx_string("cram-md5"),
     ngx_string("none")
--- a/src/mail/ngx_mail_ssl_module.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/mail/ngx_mail_ssl_module.c	Mon Apr 27 00:00:00 2009 +0400
@@ -182,7 +182,7 @@
      */
 
     scf->enable = NGX_CONF_UNSET;
-    scf->starttls = NGX_CONF_UNSET;
+    scf->starttls = NGX_CONF_UNSET_UINT;
     scf->prefer_server_ciphers = NGX_CONF_UNSET;
     scf->builtin_session_cache = NGX_CONF_UNSET;
     scf->session_timeout = NGX_CONF_UNSET;
--- a/src/os/unix/ngx_files.h	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/os/unix/ngx_files.h	Mon Apr 27 00:00:00 2009 +0400
@@ -158,8 +158,10 @@
 
 #define ngx_realpath(p, r)       realpath((char *) p, (char *) r)
 #define ngx_realpath_n           "realpath()"
-#define ngx_getcwd(buf, size)    (getcwd(buf, size) != NULL)
+#define ngx_getcwd(buf, size)    (getcwd((char *) buf, size) != NULL)
 #define ngx_getcwd_n             "getcwd()"
+#define ngx_path_separator(c)    ((c) == '/')
+
 #define NGX_MAX_PATH             PATH_MAX
 
 #define NGX_DIR_MASK_LEN         0
@@ -273,8 +275,12 @@
 
 #endif
 
-
 size_t ngx_fs_bsize(u_char *name);
 
 
+#define ngx_stderr               STDERR_FILENO
+#define ngx_set_stderr(fd)       dup2(fd, STDERR_FILENO)
+#define ngx_set_stderr_n         "dup2(STDERR_FILENO)"
+
+
 #endif /* _NGX_FILES_H_INCLUDED_ */
--- a/src/os/unix/ngx_os.h	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/os/unix/ngx_os.h	Mon Apr 27 00:00:00 2009 +0400
@@ -37,6 +37,7 @@
 ngx_int_t ngx_os_specific_init(ngx_log_t *log);
 void ngx_os_specific_status(ngx_log_t *log);
 ngx_int_t ngx_daemon(ngx_log_t *log);
+ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_int_t pid);
 
 
 ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size);
@@ -53,7 +54,6 @@
 extern ngx_uint_t   ngx_inherited_nonblocking;
 extern ngx_uint_t   ngx_tcp_nodelay_and_tcp_nopush;
 
-#define ngx_stderr_fileno  STDERR_FILENO
 
 #if (NGX_FREEBSD)
 #include <ngx_freebsd.h>
--- a/src/os/unix/ngx_process.c	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/os/unix/ngx_process.c	Mon Apr 27 00:00:00 2009 +0400
@@ -13,6 +13,7 @@
 typedef struct {
      int     signo;
      char   *signame;
+     char   *name;
      void  (*handler)(int signo);
 } ngx_signal_t;
 
@@ -36,39 +37,45 @@
 ngx_signal_t  signals[] = {
     { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
       "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
+      "reload",
       ngx_signal_handler },
 
     { ngx_signal_value(NGX_REOPEN_SIGNAL),
       "SIG" ngx_value(NGX_REOPEN_SIGNAL),
+      "reopen",
       ngx_signal_handler },
 
     { ngx_signal_value(NGX_NOACCEPT_SIGNAL),
       "SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
+      "",
       ngx_signal_handler },
 
     { ngx_signal_value(NGX_TERMINATE_SIGNAL),
       "SIG" ngx_value(NGX_TERMINATE_SIGNAL),
+      "stop",
       ngx_signal_handler },
 
     { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
       "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
+      "quit",
       ngx_signal_handler },
 
     { ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
       "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
+      "",
       ngx_signal_handler },
 
-    { SIGALRM, "SIGALRM", ngx_signal_handler },
+    { SIGALRM, "SIGALRM", "", ngx_signal_handler },
 
-    { SIGINT, "SIGINT", ngx_signal_handler },
+    { SIGINT, "SIGINT", "", ngx_signal_handler },
 
-    { SIGIO, "SIGIO", ngx_signal_handler },
+    { SIGIO, "SIGIO", "", ngx_signal_handler },
 
-    { SIGCHLD, "SIGCHLD", ngx_signal_handler },
+    { SIGCHLD, "SIGCHLD", "", ngx_signal_handler },
 
-    { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN },
+    { SIGPIPE, "SIGPIPE, SIG_IGN", "", SIG_IGN },
 
-    { 0, NULL, NULL }
+    { 0, NULL, "", NULL }
 };
 
 
@@ -540,3 +547,23 @@
         ngx_abort();
     }
 }
+
+
+ngx_int_t
+ngx_os_signal_process(ngx_cycle_t *cycle, char *name, ngx_int_t pid)
+{
+    ngx_signal_t  *sig;
+
+    for (sig = signals; sig->signo != 0; sig++) {
+        if (ngx_strcmp(name, sig->name) == 0) {
+            if (kill(pid, sig->signo) != -1) {
+                return 0;
+            }
+
+            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                          "kill(%P, %d) failed", pid, sig->signo);
+        }
+    }
+
+    return 1;
+}
--- a/src/os/unix/ngx_process_cycle.h	Mon Apr 20 00:00:00 2009 +0400
+++ b/src/os/unix/ngx_process_cycle.h	Mon Apr 27 00:00:00 2009 +0400
@@ -19,9 +19,10 @@
 #define NGX_CMD_REOPEN         5
 
 
-#define NGX_PROCESS_SINGLE   0
-#define NGX_PROCESS_MASTER   1
-#define NGX_PROCESS_WORKER   2
+#define NGX_PROCESS_SINGLE     0
+#define NGX_PROCESS_MASTER     1
+#define NGX_PROCESS_WORKER     2
+#define NGX_PROCESS_SIGNALLER  3
 
 
 void ngx_master_process_cycle(ngx_cycle_t *cycle);