summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-08-20 13:06:46 +0000
committerJonathan Kolb <jon@b0g.us>2007-08-20 13:06:46 +0000
commit6930148fa7536aaa2060b8153a8bd128a2b4aa01 (patch)
treead454bbfe7e70148072d3fef73d37c8abc235e53
parent55c04d108b8c961e82c7a2907512b80a15cff5d1 (diff)
downloadnginx-6930148fa7536aaa2060b8153a8bd128a2b4aa01.tar.gz
Changes with nginx 0.6.8 20 Aug 2007v0.6.8
*) Change: now nginx tries to set the "worker_priority", "worker_rlimit_nofile", "worker_rlimit_core", and "worker_rlimit_sigpending" without super-user privileges. *) Change: now nginx escapes space and "%" in request to a mail proxy authentication server. *) Change: now nginx escapes "%" in $memcached_key variable. *) Bugfix: nginx used path relative to configuration prefix for non-absolute configuration file path specified in the "-c" key; bug appeared in 0.6.6. *) Bugfix: nginx did not work on FreeBSD/sparc64.
-rw-r--r--CHANGES24
-rw-r--r--CHANGES.ru23
-rw-r--r--src/core/nginx.c4
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_string.c36
-rw-r--r--src/core/ngx_string.h1
-rw-r--r--src/http/modules/ngx_http_geo_module.c9
-rw-r--r--src/http/modules/ngx_http_limit_zone_module.c2
-rw-r--r--src/http/modules/ngx_http_map_module.c2
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_core_module.c22
-rw-r--r--src/http/ngx_http_script.c2
-rw-r--r--src/http/ngx_http_write_filter_module.c5
-rw-r--r--src/mail/ngx_mail_auth_http_module.c36
-rw-r--r--src/mail/ngx_mail_parse.c4
-rw-r--r--src/os/unix/ngx_process_cycle.c62
16 files changed, 143 insertions, 93 deletions
diff --git a/CHANGES b/CHANGES
index e514d7dd8..afb967583 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,11 +1,29 @@
+Changes with nginx 0.6.8 20 Aug 2007
+
+ *) Change: now nginx tries to set the "worker_priority",
+ "worker_rlimit_nofile", "worker_rlimit_core", and
+ "worker_rlimit_sigpending" without super-user privileges.
+
+ *) Change: now nginx escapes space and "%" in request to a mail proxy
+ authentication server.
+
+ *) Change: now nginx escapes "%" in $memcached_key variable.
+
+ *) Bugfix: nginx used path relative to configuration prefix for
+ non-absolute configuration file path specified in the "-c" key; bug
+ appeared in 0.6.6.
+
+ *) Bugfix: nginx did not work on FreeBSD/sparc64.
+
+
Changes with nginx 0.6.7 15 Aug 2007
*) Change: now the paths specified in the "include",
"auth_basic_user_file", "perl_modules", "ssl_certificate",
"ssl_certificate_key", and "ssl_client_certificate" directives are
- relative to directory of nginx configuration file nginx.conf, but no
- to nginx prefix directory.
+ relative to directory of nginx configuration file nginx.conf, but
+ not to nginx prefix directory.
*) Change: the --sysconfdir=PATH option in configure was canceled.
@@ -150,7 +168,7 @@ Changes with nginx 0.6.1 17 Jun 2007
Changes with nginx 0.6.0 14 Jun 2007
*) Feature: the "server_name", "map", and "valid_referers" directives
- supports the "www.example.*" wildcards.
+ support the "www.example.*" wildcards.
Changes with nginx 0.5.25 11 Jun 2007
diff --git a/CHANGES.ru b/CHANGES.ru
index d576fd8bd..529a5eaa1 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,11 +1,30 @@
+Изменения в nginx 0.6.8 20.08.2007
+
+ *) Изменение: теперь nginx пытается установить директивы
+ worker_priority, worker_rlimit_nofile, worker_rlimit_core,
+ worker_rlimit_sigpending без привилегий root'а.
+
+ *) Изменение: теперь nginx экранирует символы пробела и "%" при
+ передаче запроса серверу аутентификации почтового прокси-сервера.
+
+ *) Изменение: теперь nginx экранирует символ "%" в переменной
+ $memcached_key.
+
+ *) Исправление: при указании относительного пути к конфигурационному
+ файлу в качестве параметра ключа -c nginx определял путь
+ относительно конфигурационного префикса; ошибка появилась в 0.6.6.
+
+ *) Исправление: nginx не работал на FreeBSD/sparc64.
+
+
Изменения в nginx 0.6.7 15.08.2007
*) Изменение: теперь пути, указанные в директивах include,
auth_basic_user_file, perl_modules, ssl_certificate,
ssl_certificate_key и ssl_client_certificate, определяются
- относительно каталогу конфигурационного файла nginx.conf, а не
- относительно префиксу.
+ относительно каталога конфигурационного файла nginx.conf, а не
+ относительно префикса.
*) Изменение: параметр --sysconfdir=PATH в configure упразднён.
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 27cb80f85..579ee161b 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -656,10 +656,6 @@ ngx_getopt(ngx_cycle_t *cycle, int argc, char *const *argv)
cycle->conf_file.data = (u_char *) NGX_CONF_PATH;
}
- if (ngx_conf_full_name(cycle, &cycle->conf_file, 1) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
return NGX_OK;
}
diff --git a/src/core/nginx.h b/src/core/nginx.h
index f18e06575..af36f7ec3 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.6.7"
+#define NGINX_VERSION "0.6.8"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index a07dbebeb..508158c8b 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -59,8 +59,9 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
* %P ngx_pid_t
* %M ngx_msec_t
* %r rlim_t
- * %p pointer
- * %V pointer to ngx_str_t
+ * %p void *
+ * %V ngx_str_t *
+ * %v ngx_variable_value_t *
* %s null-terminated string
* %Z '\0'
* %N '\n'
@@ -117,7 +118,8 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
uint64_t ui64;
ngx_msec_t ms;
ngx_uint_t width, sign, hexadecimal, max_width;
- ngx_variable_value_t *v;
+ ngx_str_t *v;
+ ngx_variable_value_t *vv;
static u_char hex[] = "0123456789abcdef";
static u_char HEX[] = "0123456789ABCDEF";
@@ -188,7 +190,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
switch (*fmt) {
case 'V':
- v = va_arg(args, ngx_variable_value_t *);
+ v = va_arg(args, ngx_str_t *);
len = v->len;
len = (buf + len < last) ? len : (size_t) (last - buf);
@@ -198,6 +200,17 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
continue;
+ case 'v':
+ vv = va_arg(args, ngx_variable_value_t *);
+
+ len = vv->len;
+ len = (buf + len < last) ? len : (size_t) (last - buf);
+
+ buf = ngx_cpymem(buf, vv->data, len);
+ fmt++;
+
+ continue;
+
case 's':
p = va_arg(args, u_char *);
@@ -1019,7 +1032,7 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
- /* " ", """, "%", "'", %00-%1F, %7F-%FF */
+ /* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */
static uint32_t html[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
@@ -1039,13 +1052,13 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
- /* " ", """, "'", %00-%1F, %7F-%FF */
+ /* " ", """, "%", "'", %00-%1F, %7F-%FF */
static uint32_t refresh[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x00000085, /* 0000 0000 0000 0000 0000 0000 1000 0101 */
+ 0x000000a5, /* 0000 0000 0000 0000 0000 0000 1010 0101 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
@@ -1059,13 +1072,13 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
- /* " ", %00-%1F */
+ /* " ", "%", %00-%1F */
static uint32_t memcached[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x00000001, /* 0000 0000 0000 0000 0000 0000 0000 0001 */
+ 0x00000021, /* 0000 0000 0000 0000 0000 0000 0010 0001 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
@@ -1079,7 +1092,10 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
};
- static uint32_t *map[] = { uri, args, html, refresh, memcached };
+ /* mail_auth is the same as memcached */
+
+ static uint32_t *map[] =
+ { uri, args, html, refresh, memcached, memcached };
escape = map[type];
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index b4a96c543..42d50a46c 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -155,6 +155,7 @@ u_char *ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n);
#define NGX_ESCAPE_HTML 2
#define NGX_ESCAPE_REFRESH 3
#define NGX_ESCAPE_MEMCACHED 4
+#define NGX_ESCAPE_MAIL_AUTH 5
#define NGX_UNESCAPE_URI 1
diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c
index bb9085e10..6e26b6ea3 100644
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -86,7 +86,7 @@ ngx_http_geo_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
*v = *vv;
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http geo: %V %V", &r->connection->addr_text, v);
+ "http geo: %V %v", &r->connection->addr_text, v);
return NGX_OK;
}
@@ -100,8 +100,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_conf_t save;
ngx_pool_t *pool;
ngx_radix_tree_t *tree;
+ ngx_http_variable_t *var;
ngx_http_geo_conf_ctx_t ctx;
- ngx_http_variable_t *var;
value = cf->args->elts;
@@ -285,9 +285,8 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
ngx_radix32tree_find(ctx->tree, cidrin.addr & cidrin.mask);
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "duplicate parameter \"%V\", value: \"%V\", "
- "old value: \"%V\"",
- &value[0], var, old);
+ "duplicate parameter \"%V\", value: \"%v\", old value: \"%v\"",
+ &value[0], var, old);
rc = ngx_radix32tree_delete(ctx->tree, cidrin.addr, cidrin.mask);
diff --git a/src/http/modules/ngx_http_limit_zone_module.c b/src/http/modules/ngx_http_limit_zone_module.c
index 17643e174..a0be6f107 100644
--- a/src/http/modules/ngx_http_limit_zone_module.c
+++ b/src/http/modules/ngx_http_limit_zone_module.c
@@ -141,7 +141,7 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
if (len > 255) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"the value of the \"%V\" variable "
- "is more than 255 bytes: \"%V\"",
+ "is more than 255 bytes: \"%v\"",
&ctx->var, vv);
return NGX_DECLINED;
}
diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c
index 7b3a363fc..5f7e0c6ce 100644
--- a/src/http/modules/ngx_http_map_module.c
+++ b/src/http/modules/ngx_http_map_module.c
@@ -151,7 +151,7 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http map: \"%V\" \"%V\"", vv, v);
+ "http map: \"%v\" \"%v\"", vv, v);
return NGX_OK;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 227c08c9a..6348e874f 100644
--- 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.6.7';
+our $VERSION = '0.6.8';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index ab9812e9b..13273f678 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -620,6 +620,8 @@ ngx_int_t
ngx_http_core_find_config_phase(ngx_http_request_t *r,
ngx_http_phase_handler_t *ph)
{
+ u_char *p;
+ size_t len;
ngx_int_t rc;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t *cscf;
@@ -680,7 +682,25 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
* r->headers_out.location->key fields
*/
- r->headers_out.location->value = clcf->name;
+ if (r->args.len == 0) {
+ r->headers_out.location->value = clcf->name;
+
+ } else {
+ len = clcf->name.len + 1 + r->args.len;
+ p = ngx_palloc(r->pool, len);
+
+ if (p == NULL) {
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return NGX_OK;
+ }
+
+ r->headers_out.location->value.len = len;
+ r->headers_out.location->value.data = p;
+
+ p = ngx_cpymem(p, clcf->name.data, clcf->name.len);
+ *p++ = '?';
+ ngx_memcpy(p, r->args.data, r->args.len);
+ }
ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
return NGX_OK;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 63959498b..945602178 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -1191,7 +1191,7 @@ ngx_http_script_var_code(ngx_http_script_engine_t *e)
if (value && !value->not_found) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script var: \"%V\"", value);
+ "http script var: \"%v\"", value);
*e->sp = *value;
e->sp++;
diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c
index 944593ae4..b1796645e 100644
--- a/src/http/ngx_http_write_filter_module.c
+++ b/src/http/ngx_http_write_filter_module.c
@@ -249,7 +249,10 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
c->write->delayed = 1;
ngx_add_timer(c->write, (ngx_msec_t) (sent * 1000 / r->limit_rate + 1));
- } else if (c->write->ready && clcf->sendfile_max_chunk) {
+ } else if (c->write->ready
+ && clcf->sendfile_max_chunk
+ && c->sent - sent >= clcf->sendfile_max_chunk - 2 * ngx_pagesize)
+ {
c->write->delayed = 1;
ngx_add_timer(c->write, 1);
}
diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c
index 52031b340..906152ce8 100644
--- a/src/mail/ngx_mail_auth_http_module.c
+++ b/src/mail/ngx_mail_auth_http_module.c
@@ -1251,18 +1251,10 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
static ngx_int_t
ngx_mail_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, ngx_str_t *escaped)
{
- u_char ch, *p;
- ngx_uint_t i, n;
+ u_char *p;
+ uintptr_t n;
- n = 0;
-
- for (i = 0; i < text->len; i++) {
- ch = text->data[i];
-
- if (ch == CR || ch == LF) {
- n++;
- }
- }
+ n = ngx_escape_uri(NULL, text->data, text->len, NGX_ESCAPE_MAIL_AUTH);
if (n == 0) {
*escaped = *text;
@@ -1276,27 +1268,9 @@ ngx_mail_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, ngx_str_t *escaped)
return NGX_ERROR;
}
- escaped->data = p;
-
- for (i = 0; i < text->len; i++) {
- ch = text->data[i];
-
- if (ch == CR) {
- *p++ = '%';
- *p++ = '0';
- *p++ = 'D';
- continue;
- }
+ (void) ngx_escape_uri(p, text->data, text->len, NGX_ESCAPE_MAIL_AUTH);
- if (ch == LF) {
- *p++ = '%';
- *p++ = '0';
- *p++ = 'A';
- continue;
- }
-
- *p++ = ch;
- }
+ escaped->data = p;
return NGX_OK;
}
diff --git a/src/mail/ngx_mail_parse.c b/src/mail/ngx_mail_parse.c
index fa0fda31b..c959b44b2 100644
--- a/src/mail/ngx_mail_parse.c
+++ b/src/mail/ngx_mail_parse.c
@@ -434,6 +434,10 @@ ngx_int_t ngx_imap_parse_command(ngx_mail_session_t *s)
break;
case sw_argument:
+ if (ch == ' ' && s->quoted) {
+ break;
+ }
+
switch (ch) {
case '"':
if (!s->quoted) {
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 90993966d..c7e2fd46d 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -792,49 +792,49 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
- if (geteuid() == 0) {
- if (priority && ccf->priority != 0) {
- if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "setpriority(%d) failed", ccf->priority);
- }
+ if (priority && ccf->priority != 0) {
+ if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "setpriority(%d) failed", ccf->priority);
}
+ }
- if (ccf->rlimit_nofile != NGX_CONF_UNSET) {
- rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile;
- rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile;
+ if (ccf->rlimit_nofile != NGX_CONF_UNSET) {
+ rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile;
+ rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile;
- if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "setrlimit(RLIMIT_NOFILE, %i) failed",
- ccf->rlimit_nofile);
- }
+ if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "setrlimit(RLIMIT_NOFILE, %i) failed",
+ ccf->rlimit_nofile);
}
+ }
- if (ccf->rlimit_core != NGX_CONF_UNSET_SIZE) {
- rlmt.rlim_cur = (rlim_t) ccf->rlimit_core;
- rlmt.rlim_max = (rlim_t) ccf->rlimit_core;
+ if (ccf->rlimit_core != NGX_CONF_UNSET_SIZE) {
+ rlmt.rlim_cur = (rlim_t) ccf->rlimit_core;
+ rlmt.rlim_max = (rlim_t) ccf->rlimit_core;
- if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "setrlimit(RLIMIT_CORE, %i) failed",
- ccf->rlimit_core);
- }
+ if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "setrlimit(RLIMIT_CORE, %i) failed",
+ ccf->rlimit_core);
}
+ }
#ifdef RLIMIT_SIGPENDING
- if (ccf->rlimit_sigpending != NGX_CONF_UNSET) {
- rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending;
- rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending;
-
- if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "setrlimit(RLIMIT_SIGPENDING, %i) failed",
- ccf->rlimit_sigpending);
- }
+ if (ccf->rlimit_sigpending != NGX_CONF_UNSET) {
+ rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending;
+ rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending;
+
+ if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "setrlimit(RLIMIT_SIGPENDING, %i) failed",
+ ccf->rlimit_sigpending);
}
+ }
#endif
+ if (geteuid() == 0) {
if (setgid(ccf->group) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
"setgid(%d) failed", ccf->group);