# HG changeset patch # User Igor Sysoev # Date 1240776000 -14400 # Node ID 392c16f2d85815c32add2715607598013ce58014 # Parent 0c98173187ac5eefad45ed8309e75e98f54210c1 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. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -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. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -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. diff --git a/auto/cc/gcc b/auto/cc/gcc --- a/auto/cc/gcc +++ b/auto/cc/gcc @@ -158,9 +158,10 @@ case "$NGX_GCC_VER" in 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" ;; diff --git a/auto/install b/auto/install --- a/auto/install +++ b/auto/install @@ -15,6 +15,63 @@ END 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} \ diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf --- a/auto/lib/openssl/conf +++ b/auto/lib/openssl/conf @@ -17,8 +17,8 @@ if [ $OPENSSL != NONE ]; then 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 @@ else 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" ;; *) diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -129,9 +129,12 @@ NGX_CPP_TEST=NO 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 @@ do 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 @@ do done +NGX_CONFIGURE="$opt" + + if [ $help = yes ]; then cat << END @@ -409,141 +416,21 @@ if [ ".$NGX_PLATFORM" = ".win32" ]; then 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 ./*) diff --git a/auto/os/linux b/auto/os/linux --- a/auto/os/linux +++ b/auto/os/linux @@ -140,4 +140,4 @@ ngx_feature_test="struct crypt_data cd; 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" diff --git a/auto/os/win32 b/auto/os/win32 --- a/auto/os/win32 +++ b/auto/os/win32 @@ -8,7 +8,7 @@ CORE_INCS="$WIN32_INCS" 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" diff --git a/auto/stubs b/auto/stubs --- a/auto/stubs +++ b/auto/stubs @@ -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 diff --git a/configure b/configure --- a/configure +++ b/configure @@ -3,8 +3,6 @@ # Copyright (C) Igor Sysoev -NGX_CONFIGURE=`echo $@ | sed 's/"/\\\\"/g'` - . auto/options . auto/init . auto/sources @@ -54,6 +52,39 @@ fi . 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 @@ fi # 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 diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -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_module_t ngx_core_module = { 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 @@ main(int argc, char *const *argv) 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 @@ main(int argc, char *const *argv) ngx_pid = ngx_getpid(); - log = ngx_log_init(); + log = ngx_log_init(ngx_prefix); if (log == NULL) { return 1; } @@ -224,7 +271,10 @@ main(int argc, char *const *argv) 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 @@ main(int argc, char *const *argv) 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 @@ main(int argc, char *const *argv) 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 @@ main(int argc, char *const *argv) } 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 @@ main(int argc, char *const *argv) 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 @@ main(int argc, char *const *argv) 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_exec_new_binary(ngx_cycle_t *cycle, 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 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, 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 @@ ngx_save_argv(ngx_cycle_t *cycle, int ar } +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) { diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -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" diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -798,10 +798,6 @@ ngx_conf_full_name(ngx_cycle_t *cycle, n 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 @@ ngx_conf_full_name(ngx_cycle_t *cycle, n 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 @@ ngx_conf_open_file(ngx_cycle_t *cycle, n 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 @@ ngx_conf_open_file(ngx_cycle_t *cycle, n 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; } diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -34,11 +34,7 @@ ngx_tls_key_t ngx_core_tls_key; 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 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) 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_init_cycle(ngx_cycle_t *old_cycle) 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 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } - 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 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } 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 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) i = 0; } - if (file[i].name.data == NULL) { + if (file[i].name.len == 0) { continue; } @@ -467,9 +469,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) 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 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } } - 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 @@ old_shm_zone_done: 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 @@ failed: 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 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, n 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 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, n #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_delete_pidfile(ngx_cycle_t *cycle) } +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 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx i = 0; } - if (file[i].name.data == NULL) { + if (file[i].name.len == 0) { continue; } diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -60,7 +60,8 @@ struct ngx_cycle_s { 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 @@ typedef struct { 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); diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -48,12 +48,20 @@ ngx_module_t ngx_errlog_module = { 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 @@ ngx_log_error_core(ngx_uint_t level, ngx #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 @@ ngx_log_error_core(ngx_uint_t level, ngx 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 @@ ngx_log_error_core(ngx_uint_t level, ngx 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_log_error_core(ngx_uint_t level, ngx 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 @@ ngx_log_debug_core(ngx_log_t *log, ngx_e #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 @@ ngx_log_stderr(const char *fmt, ...) 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 @@ ngx_set_error_log_levels(ngx_conf_t *cf, 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 @@ ngx_set_error_log_levels(ngx_conf_t *cf, 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 @@ ngx_set_error_log_levels(ngx_conf_t *cf, 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 @@ ngx_set_error_log(ngx_conf_t *cf, ngx_co 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; diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -195,14 +195,15 @@ void ngx_cdecl ngx_log_debug_core(ngx_lo /*********************************/ -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_ */ diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c --- a/src/core/ngx_open_file_cache.c +++ b/src/core/ngx_open_file_cache.c @@ -130,6 +130,7 @@ ngx_open_cached_file(ngx_open_file_cache 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 @@ ngx_open_cached_file(ngx_open_file_cache 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 @@ ngx_open_and_stat_file(u_char *name, ngx 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 @@ ngx_open_and_stat_file(u_char *name, ngx } else if (of->test_dir) { if (ngx_file_info(name, &fi) == -1) { + of->failed = ngx_file_info_n; goto failed; } @@ -471,6 +493,7 @@ ngx_open_and_stat_file(u_char *name, ngx } if (fd == NGX_INVALID_FILE) { + of->failed = ngx_open_file_n; goto failed; } diff --git a/src/core/ngx_open_file_cache.h b/src/core/ngx_open_file_cache.h --- a/src/core/ngx_open_file_cache.h +++ b/src/core/ngx_open_file_cache.h @@ -21,13 +21,16 @@ typedef struct { 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; diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -330,7 +330,7 @@ static ngx_command_t ngx_http_fastcgi_c 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, diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c --- a/src/http/modules/ngx_http_flv_module.c +++ b/src/http/modules/ngx_http_flv_module.c @@ -143,7 +143,7 @@ ngx_http_flv_handler(ngx_http_request_t 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; diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c --- a/src/http/modules/ngx_http_gzip_static_module.c +++ b/src/http/modules/ngx_http_gzip_static_module.c @@ -152,7 +152,7 @@ ngx_http_gzip_static_handler(ngx_http_re } 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; } diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -83,13 +83,13 @@ ngx_module_t ngx_http_index_module = { /* - * 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 @@ ngx_http_index_handler(ngx_http_request_ 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 @@ ngx_http_index_handler(ngx_http_request_ 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_http_index_test_dir(ngx_http_request 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_http_index_test_dir(ngx_http_request } 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; diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c --- a/src/http/modules/ngx_http_log_module.c +++ b/src/http/modules/ngx_http_log_module.c @@ -385,6 +385,8 @@ ngx_http_log_script_write(ngx_http_reque 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_http_log_script_write(ngx_http_reque != 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; } diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -2192,6 +2192,12 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t 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); diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -128,7 +128,7 @@ ngx_http_static_handler(ngx_http_request 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; diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.7.52'; +our $VERSION = '0.7.53'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -662,7 +662,7 @@ sendfile(r, filename, offset = -1, bytes } 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; } diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1169,6 +1169,7 @@ ngx_http_core_try_files_phase(ngx_http_r 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 @@ ngx_http_core_try_files_phase(ngx_http_r { 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_error_log(ngx_conf_t *cf, { 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; } diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -1337,12 +1337,7 @@ ngx_http_parse_unsafe_uri(ngx_http_reque 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 @@ ngx_http_parse_unsafe_uri(ngx_http_reque 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; } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1587,15 +1587,9 @@ ngx_http_validate_host(u_char *host, siz continue; } - if (ch == '/' || ch == '\0') { + if (ngx_path_separator(ch) || ch == '\0') { return -1; } - -#if (NGX_WIN32) - if (ch == '\\') { - return -1; - } -#endif } if (dot) { diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -1213,7 +1213,7 @@ ngx_http_script_add_full_name_code(ngx_h } 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 @@ ngx_http_script_add_full_name_code(ngx_h } 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 @@ ngx_http_script_full_name_len_code(ngx_h 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 @@ ngx_http_script_full_name_code(ngx_http_ 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 @@ ngx_http_script_file_code(ngx_http_scrip 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 @@ ngx_http_script_file_code(ngx_http_scrip { 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) { diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h --- a/src/http/ngx_http_script.h +++ b/src/http/ngx_http_script.h @@ -153,7 +153,7 @@ typedef struct { typedef struct { ngx_http_script_code_pt code; - uintptr_t prefix; + uintptr_t conf_prefix; } ngx_http_script_full_name_code_t; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -353,7 +353,9 @@ ngx_http_upstream_init(ngx_http_request_ 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 @@ ngx_http_upstream_init(ngx_http_request_ 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 @@ ngx_http_upstream_check_broken_connectio 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 @@ ngx_http_upstream_check_broken_connectio 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 @@ ngx_http_upstream_check_broken_connectio 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_http_upstream_process_request(ngx_ht 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); } } diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -162,7 +162,7 @@ typedef struct { #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; diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c +++ b/src/mail/ngx_mail_auth_http_module.c @@ -139,6 +139,7 @@ ngx_module_t ngx_mail_auth_http_module 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") diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -182,7 +182,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) */ 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; diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -158,8 +158,10 @@ ngx_int_t ngx_set_file_time(u_char *name #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 @@ ngx_int_t ngx_directio_off(ngx_fd_t fd); #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_ */ diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h --- a/src/os/unix/ngx_os.h +++ b/src/os/unix/ngx_os.h @@ -37,6 +37,7 @@ void ngx_os_status(ngx_log_t *log); 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_int_t ngx_max_sockets; 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 diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -13,6 +13,7 @@ typedef struct { int signo; char *signame; + char *name; void (*handler)(int signo); } ngx_signal_t; @@ -36,39 +37,45 @@ ngx_process_t ngx_processes[NGX_MAX_P 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_debug_point(void) 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; +} diff --git a/src/os/unix/ngx_process_cycle.h b/src/os/unix/ngx_process_cycle.h --- a/src/os/unix/ngx_process_cycle.h +++ b/src/os/unix/ngx_process_cycle.h @@ -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);