changeset 372:6639b93e81b2 NGINX_0_6_30

nginx 0.6.30 *) Change: now if an "include" directive pattern does not match any file, then nginx does not issue an error. *) Feature: now the time in directives may be specified without spaces, for example, "1h50m". *) Bugfix: memory leaks if the "ssl_verify_client" directive was on. Thanks to Chavelle Vincent. *) Bugfix: the "sub_filter" directive might set text to change into output. *) Bugfix: the "error_page" directive did not take into account arguments in redirected URI. *) Bugfix: now nginx always opens files in binary mode under Cygwin. *) Bugfix: nginx could not be built on OpenBSD; bug appeared in 0.6.15.
author Igor Sysoev <http://sysoev.ru>
date Tue, 29 Apr 2008 00:00:00 +0400
parents b6a2a305fdad
children 56370b6cb317
files CHANGES CHANGES.ru auto/headers auto/options auto/summary src/core/nginx.h src/core/ngx_conf_file.c src/core/ngx_log.h src/core/ngx_output_chain.c src/core/ngx_parse.c src/core/ngx_parse.h src/core/ngx_resolver.c src/core/ngx_resolver.h src/core/ngx_string.c src/core/ngx_string.h src/core/ngx_times.c src/event/ngx_event_openssl.c src/http/modules/ngx_http_sub_filter_module.c src/http/modules/perl/nginx.pm src/http/ngx_http.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_parse_time.c src/http/ngx_http_request.c src/http/ngx_http_special_response.c src/http/ngx_http_upstream.c src/http/ngx_http_upstream_round_robin.c src/mail/ngx_mail.c src/mail/ngx_mail_proxy_module.c src/os/unix/ngx_files.c src/os/unix/ngx_files.h src/os/unix/ngx_posix_config.h src/os/unix/ngx_process.c
diffstat 33 files changed, 390 insertions(+), 193 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,15 +1,37 @@
 
+Changes with nginx 0.6.30                                        29 Apr 2008
+
+    *) Change: now if an "include" directive pattern does not match any 
+       file, then nginx does not issue an error.
+
+    *) Feature: now the time in directives may be specified without spaces, 
+       for example, "1h50m".
+
+    *) Bugfix: memory leaks if the "ssl_verify_client" directive was on. 
+       Thanks to Chavelle Vincent.
+
+    *) Bugfix: the "sub_filter" directive might set text to change into 
+       output.
+
+    *) Bugfix: the "error_page" directive did not take into account 
+       arguments in redirected URI.
+
+    *) Bugfix: now nginx always opens files in binary mode under Cygwin.
+
+    *) Bugfix: nginx could not be built on OpenBSD; bug appeared in 0.6.15.
+
+
 Changes with nginx 0.6.29                                        18 Mar 2008
 
     *) Feature: the ngx_google_perftools_module.
 
-    *) Bugfix: the ngx_http_perl_module could be not built on 64-bit 
+    *) Bugfix: the ngx_http_perl_module could not be built on 64-bit 
        platforms; bug appeared in 0.6.27.
 
 
 Changes with nginx 0.6.28                                        13 Mar 2008
 
-    *) Bugfix: the rtsig method could be not built; bug appeared in 0.6.27.
+    *) Bugfix: the rtsig method could not be built; bug appeared in 0.6.27.
 
 
 Changes with nginx 0.6.27                                        12 Mar 2008
@@ -665,7 +687,8 @@ Changes with nginx 0.5.20               
        Studio.
        Thanks to Andrei Nigmatulin.
 
-    *) Bugfix: the ngx_http_perl_module could not built by Solaris make.
+    *) Bugfix: the ngx_http_perl_module could not be built by Solaris 
+       make.
        Thanks to Andrei Nigmatulin.
 
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,29 @@
 
+Изменения в nginx 0.6.30                                          29.04.2008
+
+    *) Изменение: теперь, если маске, заданной в директиве include, не 
+       соответствует ни один файл, то nginx не выдаёт ошибку.
+
+    *) Добавление: теперь время в директивах можно задавать без пробела, 
+       например, "1h50m".
+
+    *) Исправление: утечек памяти, если директива ssl_verify_client имела 
+       значение on. 
+       Спасибо Chavelle Vincent.
+
+    *) Исправление: директива sub_filter могла вставлять заменяемый текст в 
+       вывод.
+
+    *) Исправление: директива error_page не воспринимала параметры в 
+       перенаправляемом URI.
+
+    *) Исправление: теперь при сборке с Cygwin nginx всегда открывает файлы 
+       в бинарном режиме.
+
+    *) Исправление: nginx не собирался под OpenBSD; ошибка появилась в 
+       0.6.15.
+
+
 Изменения в nginx 0.6.29                                          18.03.2008
 
     *) Добавление: модуль ngx_google_perftools_module.
--- a/auto/headers
+++ b/auto/headers
@@ -7,4 +7,3 @@ ngx_include="inttypes.h";  . auto/includ
 ngx_include="limits.h";    . auto/include
 ngx_include="sys/filio.h"; . auto/include
 ngx_include="crypt.h";     . auto/include
-ngx_include="malloc.h";    . auto/include
--- a/auto/options
+++ b/auto/options
@@ -150,8 +150,8 @@ do
         --without-poll_module)           EVENT_POLL=NONE            ;;
         --with-aio_module)               EVENT_AIO=YES              ;;
 
-        --with-threads=*)                USE_THREADS="$value"       ;;
-        --with-threads)                  USE_THREADS="pthreads"     ;;
+        #--with-threads=*)                USE_THREADS="$value"       ;;
+        #--with-threads)                  USE_THREADS="pthreads"     ;;
 
         --without-http)                  HTTP=NO                    ;;
         --http-log-path=*)               NGX_HTTP_LOG_PATH="$value" ;;
--- a/auto/summary
+++ b/auto/summary
@@ -21,15 +21,15 @@ echo
 echo "Configuration summary"
 
 
-case $USE_THREADS in
-    rfork)         echo "  + using rfork()ed threads" ;;
-    pthreads)      echo "  + using libpthread threads library" ;;
-    libthr)        echo "  + using FreeBSD libthr threads library" ;;
-    libc_r)        echo "  + using FreeBSD libc_r threads library" ;;
-    linuxthreads)  echo "  + using FreeBSD LinuxThreads port library" ;;
-    NO)            echo "  + threads are not used" ;;
-    *)             echo "  + using lib$USE_THREADS threads library" ;;
-esac
+#case $USE_THREADS in
+#    rfork)         echo "  + using rfork()ed threads" ;;
+#    pthreads)      echo "  + using libpthread threads library" ;;
+#    libthr)        echo "  + using FreeBSD libthr threads library" ;;
+#    libc_r)        echo "  + using FreeBSD libc_r threads library" ;;
+#    linuxthreads)  echo "  + using FreeBSD LinuxThreads port library" ;;
+#    NO)            echo "  + threads are not used" ;;
+#    *)             echo "  + using lib$USE_THREADS threads library" ;;
+#esac
 
 if [ $USE_PCRE = DISABLED ]; then
     echo "  + PCRE library is disabled"
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VERSION      "0.6.29"
+#define NGINX_VERSION      "0.6.30"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -645,10 +645,18 @@ ngx_conf_include(ngx_conf_t *cf, ngx_com
         return NGX_CONF_ERROR;
     }
 
+    if (strpbrk((char *) file.data, "*?[") == NULL) {
+
+        ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
+
+        return ngx_conf_parse(cf, &file);
+    }
+
     ngx_memzero(&gl, sizeof(ngx_glob_t));
 
     gl.pattern = file.data;
     gl.log = cf->log;
+    gl.test = 1;
 
     if (ngx_open_glob(&gl) != NGX_OK) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -195,9 +195,6 @@ void ngx_cdecl ngx_log_debug_core(ngx_lo
 
 /*********************************/
 
-#define ngx_log_alloc_log(pool, log)  ngx_palloc(pool, log, sizeof(ngx_log_t))
-#define ngx_log_copy_log(new, old)    ngx_memcpy(new, old, sizeof(ngx_log_t))
-
 ngx_log_t *ngx_log_init(void);
 ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args);
 char *ngx_set_error_log_levels(ngx_conf_t *cf, ngx_log_t *log);
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -433,8 +433,11 @@ ngx_chain_writer(void *data, ngx_chain_t
 {
     ngx_chain_writer_ctx_t *ctx = data;
 
-    off_t         size;
-    ngx_chain_t  *cl;
+    off_t              size;
+    ngx_chain_t       *cl;
+    ngx_connection_t  *c;
+
+    c = ctx->connection;
 
     for (size = 0; in; in = in->next) {
 
@@ -446,7 +449,7 @@ ngx_chain_writer(void *data, ngx_chain_t
 
         size += ngx_buf_size(in->buf);
 
-        ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
+        ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0,
                        "chain writer buf fl:%d s:%uO",
                        in->buf->flush, ngx_buf_size(in->buf));
 
@@ -461,7 +464,7 @@ ngx_chain_writer(void *data, ngx_chain_t
         ctx->last = &cl->next;
     }
 
-    ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
+    ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
                    "chain writer in: %p", ctx->out);
 
     for (cl = ctx->out; cl; cl = cl->next) {
@@ -476,14 +479,13 @@ ngx_chain_writer(void *data, ngx_chain_t
         size += ngx_buf_size(cl->buf);
     }
 
-    if (size == 0 && !ctx->connection->buffered) {
+    if (size == 0 && !c->buffered) {
         return NGX_OK;
     }
 
-    ctx->out = ctx->connection->send_chain(ctx->connection, ctx->out,
-                                           ctx->limit);
+    ctx->out = c->send_chain(c, ctx->out, ctx->limit);
 
-    ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
+    ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
                    "chain writer out: %p", ctx->out);
 
     if (ctx->out == NGX_CHAIN_ERROR) {
@@ -493,7 +495,7 @@ ngx_chain_writer(void *data, ngx_chain_t
     if (ctx->out == NULL) {
         ctx->last = &ctx->out;
 
-        if (!ctx->connection->buffered) {
+        if (!c->buffered) {
             return NGX_OK;
         }
     }
--- a/src/core/ngx_parse.c
+++ b/src/core/ngx_parse.c
@@ -11,15 +11,15 @@
 ssize_t
 ngx_parse_size(ngx_str_t *line)
 {
-    u_char     last;
+    u_char     unit;
     size_t     len;
     ssize_t    size;
     ngx_int_t  scale;
 
     len = line->len;
-    last = line->data[len - 1];
+    unit = line->data[len - 1];
 
-    switch (last) {
+    switch (unit) {
     case 'K':
     case 'k':
         len--;
@@ -50,15 +50,15 @@ ngx_parse_size(ngx_str_t *line)
 off_t
 ngx_parse_offset(ngx_str_t *line)
 {
-    u_char     last;
+    u_char     unit;
     off_t      offset;
     size_t     len;
     ngx_int_t  scale;
 
     len = line->len;
-    last = line->data[len - 1];
+    unit = line->data[len - 1];
 
-    switch (last) {
+    switch (unit) {
     case 'K':
     case 'k':
         len--;
@@ -93,12 +93,11 @@ ngx_parse_offset(ngx_str_t *line)
 
 
 ngx_int_t
-ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
+ngx_parse_time(ngx_str_t *line, ngx_uint_t sec)
 {
-    size_t       len;
-    u_char      *start, last;
+    u_char      *p, *last;
     ngx_int_t    value, total, scale;
-    ngx_uint_t   max, i;
+    ngx_uint_t   max, valid;
     enum {
         st_start = 0,
         st_year,
@@ -112,39 +111,30 @@ ngx_parse_time(ngx_str_t *line, ngx_int_
         st_last
     } step;
 
-
-    start = line->data;
-    len = 0;
+    valid = 0;
+    value = 0;
     total = 0;
     step = sec ? st_start : st_month;
+    scale = sec ? 1 : 1000;
 
-    for (i = 0; /* void */ ; i++) {
+    p = line->data;
+    last = p + line->len;
 
-        if (i < line->len) {
-            if (line->data[i] != ' ') {
-                len++;
-                continue;
-            }
+    while (p < last) {
 
-            if (line->data[i] == ' ' && len == 0) {
-                start = &line->data[i + 1];
-                continue;
-            }
+        if (*p >= '0' && *p <= '9') {
+            value = value * 10 + (*p++ - '0');
+            valid = 1;
+            continue;
         }
 
-        if (len == 0) {
-            break;
-        }
+        switch (*p++) {
 
-        last = line->data[i - 1];
-
-        switch (last) {
         case 'y':
             if (step > st_start) {
                 return NGX_ERROR;
             }
             step = st_year;
-            len--;
             max = 68;
             scale = 60 * 60 * 24 * 365;
             break;
@@ -154,7 +144,6 @@ ngx_parse_time(ngx_str_t *line, ngx_int_
                 return NGX_ERROR;
             }
             step = st_month;
-            len--;
             max = 828;
             scale = 60 * 60 * 24 * 30;
             break;
@@ -164,7 +153,6 @@ ngx_parse_time(ngx_str_t *line, ngx_int_
                 return NGX_ERROR;
             }
             step = st_week;
-            len--;
             max = 3550;
             scale = 60 * 60 * 24 * 7;
             break;
@@ -174,7 +162,6 @@ ngx_parse_time(ngx_str_t *line, ngx_int_
                 return NGX_ERROR;
             }
             step = st_day;
-            len--;
             max = 24855;
             scale = 60 * 60 * 24;
             break;
@@ -184,52 +171,49 @@ ngx_parse_time(ngx_str_t *line, ngx_int_
                 return NGX_ERROR;
             }
             step = st_hour;
-            len--;
             max = 596523;
             scale = 60 * 60;
             break;
 
         case 'm':
+            if (*p == 's') {
+                if (sec || step > st_sec) {
+                    return NGX_ERROR;
+                }
+                p++;
+                step = st_msec;
+                max = 2147483647;
+                scale = 1;
+                break;
+            }
+
             if (step > st_hour) {
                 return NGX_ERROR;
             }
             step = st_min;
-            len--;
             max = 35791394;
             scale = 60;
             break;
 
         case 's':
-            len--;
-
-            if (line->data[i - 2] == 'm') {
-                if (sec || step > st_sec) {
-                    return NGX_ERROR;
-                }
-                step = st_msec;
-                len--;
-                max = 2147483647;
-                scale = 1;
-                break;
-            }
-
             if (step > st_min) {
                 return NGX_ERROR;
             }
-
             step = st_sec;
             max = 2147483647;
             scale = 1;
             break;
 
-        default:
+        case ' ':
+            if (step > st_min) {
+                return NGX_ERROR;
+            }
             step = st_last;
             max = 2147483647;
             scale = 1;
-        }
+            break;
 
-        value = ngx_atoi(start, len);
-        if (value == NGX_ERROR) {
+        default:
             return NGX_ERROR;
         }
 
@@ -238,23 +222,27 @@ ngx_parse_time(ngx_str_t *line, ngx_int_
             max /= 1000;
         }
 
-        if ((u_int) value > max) {
-            return NGX_PARSE_LARGE_TIME;
+        if ((ngx_uint_t) value > max) {
+            return NGX_ERROR;
         }
 
         total += value * scale;
 
-        if ((u_int) total > 2147483647) {
-            return NGX_PARSE_LARGE_TIME;
+        if ((ngx_uint_t) total > 2147483647) {
+            return NGX_ERROR;
         }
 
-        if (i >= line->len) {
-            break;
+        value = 0;
+        scale = sec ? 1 : 1000;
+
+        while (p < last && *p == ' ') {
+            p++;
         }
-
-        len = 0;
-        start = &line->data[i + 1];
     }
 
-    return total;
+    if (valid) {
+        return total + value * scale;
+    }
+
+    return NGX_ERROR;
 }
--- a/src/core/ngx_parse.h
+++ b/src/core/ngx_parse.h
@@ -17,7 +17,7 @@
 
 ssize_t ngx_parse_size(ngx_str_t *line);
 off_t ngx_parse_offset(ngx_str_t *line);
-ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_int_t sec);
+ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_uint_t sec);
 
 
 #endif /* _NGX_PARSE_H_INCLUDED_ */
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -369,6 +369,7 @@ ngx_resolve_name_locked(ngx_resolver_t *
 {
     uint32_t              hash;
     in_addr_t             addr, *addrs;
+    ngx_int_t             rc;
     ngx_uint_t            naddrs;
     ngx_resolver_ctx_t   *next;
     ngx_resolver_node_t  *rn;
@@ -434,10 +435,29 @@ ngx_resolve_name_locked(ngx_resolver_t *
 
             /* NGX_RESOLVE_CNAME */
 
-            ctx->name.len = rn->cnlen;
-            ctx->name.data = rn->u.cname;
-
-            return ngx_resolve_name_locked(r, ctx);
+            if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
+
+                ctx->name.len = rn->cnlen;
+                ctx->name.data = rn->u.cname;
+
+                return ngx_resolve_name_locked(r, ctx);
+            }
+
+            ctx->next = rn->waiting;
+            rn->waiting = NULL;
+
+            /* unlock name mutex */
+
+            do {
+                ctx->state = NGX_RESOLVE_NXDOMAIN;
+                next = ctx->next;
+
+                ctx->handler(ctx);
+
+                ctx = next;
+            } while (ctx);
+
+            return NGX_OK;
         }
 
         if (rn->waiting) {
@@ -453,6 +473,7 @@ ngx_resolve_name_locked(ngx_resolver_t *
         /* lock alloc mutex */
 
         ngx_resolver_free_locked(r, rn->query);
+        rn->query = NULL;
 
         if (rn->cnlen) {
             ngx_resolver_free_locked(r, rn->u.cname);
@@ -479,14 +500,30 @@ ngx_resolve_name_locked(ngx_resolver_t *
 
         rn->node.key = hash;
         rn->nlen = (u_short) ctx->name.len;
+        rn->query = NULL;
 
         ngx_rbtree_insert(&r->name_rbtree, &rn->node);
     }
 
-    if (ngx_resolver_create_name_query(rn, ctx) != NGX_OK) {
+    rc = ngx_resolver_create_name_query(rn, ctx);
+
+    if (rc == NGX_ERROR) {
         goto failed;
     }
 
+    if (rc == NGX_DECLINED) {
+        ngx_rbtree_delete(&r->name_rbtree, &rn->node);
+
+        ngx_resolver_free(r, rn->query);
+        ngx_resolver_free(r, rn->name);
+        ngx_resolver_free(r, rn);
+
+        ctx->state = NGX_RESOLVE_NXDOMAIN;
+        ctx->handler(ctx);
+
+        return NGX_OK;
+    }
+
     if (ngx_resolver_send_query(r, rn) != NGX_OK) {
         goto failed;
     }
@@ -526,6 +563,10 @@ failed:
 
     ngx_rbtree_delete(&r->name_rbtree, &rn->node);
 
+    if (rn->query) {
+        ngx_resolver_free(r, rn->query);
+    }
+
     ngx_resolver_free(r, rn->name);
 
     ngx_resolver_free(r, rn);
@@ -588,6 +629,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
         ngx_queue_remove(&rn->queue);
 
         ngx_resolver_free(r, rn->query);
+        rn->query = NULL;
 
     } else {
         rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t));
@@ -596,6 +638,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx
         }
 
         rn->node.key = ctx->addr;
+        rn->query = NULL;
 
         ngx_rbtree_insert(&r->addr_rbtree, &rn->node);
     }
@@ -646,6 +689,10 @@ failed:
     if (rn) {
         ngx_rbtree_delete(&r->addr_rbtree, &rn->node);
 
+        if (rn->query) {
+            ngx_resolver_free(r, rn->query);
+        }
+
         ngx_resolver_free(r, rn);
     }
 
@@ -925,14 +972,14 @@ ngx_resolver_process_response(ngx_resolv
     nan = (query->nan_hi << 8) + query->nan_lo;
 
     ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0,
-                   "resolver DNS response %d fl:%04Xud %d/%d/%d/%d",
+                   "resolver DNS response %ui fl:%04Xui %ui/%ui/%ui/%ui",
                    ident, flags, nqs, nan,
                    (query->nns_hi << 8) + query->nns_lo,
                    (query->nar_hi << 8) + query->nar_lo);
 
     if (!(flags & 0x8000)) {
         ngx_log_error(r->log_level, r->log, 0,
-                      "invalid DNS response %d fl:%04Xud", ident, flags);
+                      "invalid DNS response %ui fl:%04Xui", ident, flags);
         return;
     }
 
@@ -940,7 +987,7 @@ ngx_resolver_process_response(ngx_resolv
 
     if (code == NGX_RESOLVE_FORMERR || code > NGX_RESOLVE_REFUSED) {
         ngx_log_error(r->log_level, r->log, 0,
-                      "DNS error (%d: %s), query id:%d",
+                      "DNS error (%ui: %s), query id:%ui",
                       code, ngx_resolver_strerror(code), ident);
         return;
     }
@@ -982,11 +1029,11 @@ found:
     qclass = (qs->class_hi << 8) + qs->class_lo;
 
     ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
-                   "resolver DNS response qt:%d cl:%d", qtype, qclass);
+                   "resolver DNS response qt:%ui cl:%ui", qtype, qclass);
 
     if (qclass != 1) {
         ngx_log_error(r->log_level, r->log, 0,
-                      "unknown query class %d in DNS response", qclass);
+                      "unknown query class %ui in DNS response", qclass);
         return;
     }
 
@@ -1007,7 +1054,7 @@ found:
 
     default:
         ngx_log_error(r->log_level, r->log, 0,
-                      "unknown query type %d in DNS response", qtype);
+                      "unknown query type %ui in DNS response", qtype);
         return;
     }
 
@@ -1062,7 +1109,7 @@ ngx_resolver_process_a(ngx_resolver_t *r
 
     if (ident != qident) {
         ngx_log_error(r->log_level, r->log, 0,
-                      "wrong ident %d response for %V, expect %d",
+                      "wrong ident %ui response for %V, expect %ui",
                       ident, &name, qident);
         goto failed;
     }
@@ -1158,6 +1205,13 @@ ngx_resolver_process_a(ngx_resolver_t *r
         } else if (qtype == NGX_RESOLVE_CNAME) {
             cname = &buf[i] + sizeof(ngx_resolver_an_t);
             i += sizeof(ngx_resolver_an_t) + len;
+
+        } else if (qtype == NGX_RESOLVE_DNAME) {
+            i += sizeof(ngx_resolver_an_t) + len;
+
+        } else {
+            ngx_log_error(r->log_level, r->log, 0,
+                          "unexpected qtype %ui", qtype);
         }
     }
 
@@ -1291,8 +1345,8 @@ ngx_resolver_process_a(ngx_resolver_t *r
     }
 
     ngx_log_error(r->log_level, r->log, 0,
-                "no A or CNAME types in DNS responses, unknown query type: %d",
-                qtype);
+               "no A or CNAME types in DNS responses, unknown query type: %ui",
+               qtype);
     return;
 
 short_response:
@@ -1368,9 +1422,9 @@ ngx_resolver_process_ptr(ngx_resolver_t 
 
     if (ident != qident) {
         ngx_log_error(r->log_level, r->log, 0,
-                      "wrong ident %d response for %ud.%ud.%ud.%ud, expect %d",
-                      ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff,
-                      (addr >> 8) & 0xff, addr & 0xff, qident);
+                    "wrong ident %ui response for %ud.%ud.%ud.%ud, expect %ui",
+                    ident, (addr >> 24) & 0xff, (addr >> 16) & 0xff,
+                    (addr >> 8) & 0xff, addr & 0xff, qident);
         goto failed;
     }
 
@@ -1421,7 +1475,7 @@ ngx_resolver_process_ptr(ngx_resolver_t 
     len = (an->len_hi << 8) + an->len_lo;
 
     ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
-                  "resolver qt:%d cl:%d len:%uz", qtype, qclass, len);
+                  "resolver qt:%ui cl:%ui len:%uz", qtype, qclass, len);
 
     i += 2 + sizeof(ngx_resolver_an_t);
 
@@ -1684,6 +1738,10 @@ ngx_resolver_create_name_query(ngx_resol
             len++;
 
         } else {
+            if (len == 0) {
+                return NGX_DECLINED;
+            }
+
             *p = (u_char) len;
             len = 0;
         }
--- a/src/core/ngx_resolver.h
+++ b/src/core/ngx_resolver.h
@@ -17,6 +17,7 @@
 #define NGX_RESOLVE_PTR       12
 #define NGX_RESOLVE_MX        15
 #define NGX_RESOLVE_TXT       16
+#define NGX_RESOLVE_DNAME     39
 
 #define NGX_RESOLVE_FORMERR   1
 #define NGX_RESOLVE_SERVFAIL  2
@@ -28,6 +29,8 @@
 
 #define NGX_NO_RESOLVER       (void *) -1
 
+#define NGX_RESOLVER_MAX_RECURSION    50
+
 
 typedef struct {
     ngx_connection_t         *connection;
@@ -127,6 +130,7 @@ struct ngx_resolver_ctx_s {
     ngx_msec_t                timeout;
 
     ngx_uint_t                quick;  /* unsigned  quick:1; */
+    ngx_uint_t                recursion;
     ngx_event_t              *event;
 };
 
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1430,26 +1430,32 @@ ngx_escape_html(u_char *dst, u_char *src
 
 void
 ngx_sort(void *base, size_t n, size_t size,
-    int (*cmp)(const void *, const void *))
+    ngx_int_t (*cmp)(const void *, const void *))
 {
-    u_char  *p1, *p2;
-    u_char   buf[256];
+    u_char  *p1, *p2, *p;
+
+    p = ngx_alloc(size, ngx_cycle->log);
+    if (p == NULL) {
+        return;
+    }
 
     for (p1 = (u_char *) base + size;
          p1 < (u_char *) base + n * size;
          p1 += size)
     {
-        ngx_memcpy(buf, p1, size);
+        ngx_memcpy(p, p1, size);
 
         for (p2 = p1;
-             p2 > (u_char *) base && cmp(p2 - size, buf) > 0;
+             p2 > (u_char *) base && cmp(p2 - size, p) > 0;
              p2 -= size)
         {
             ngx_memcpy(p2, p2 - size, size);
         }
 
-        ngx_memcpy(p2, buf, size);
+        ngx_memcpy(p2, p, size);
     }
+
+    ngx_free(p);
 }
 
 
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -173,7 +173,7 @@ uintptr_t ngx_escape_html(u_char *dst, u
 
 
 void ngx_sort(void *base, size_t n, size_t size,
-    int (*cmp)(const void *, const void *));
+    ngx_int_t (*cmp)(const void *, const void *));
 #define ngx_qsort             qsort
 
 
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -203,14 +203,17 @@ ngx_http_cookie_time(u_char *buf, time_t
 void
 ngx_gmtime(time_t t, ngx_tm_t *tp)
 {
-    ngx_uint_t  n, sec, min, hour, mday, mon, year, wday, yday, days;
+    ngx_int_t   yday;
+    ngx_uint_t  n, sec, min, hour, mday, mon, year, wday, days, leap;
 
     /* the calculation is valid for positive time_t only */
+
     n = (ngx_uint_t) t;
 
     days = n / 86400;
 
     /* Jaunary 1, 1970 was Thursday */
+
     wday = (4 + days) % 7;
 
     n %= 86400;
@@ -219,57 +222,65 @@ ngx_gmtime(time_t t, ngx_tm_t *tp)
     min = n / 60;
     sec = n % 60;
 
-    /* the algorithm based on Gauss's formula */
+    /*
+     * the algorithm based on Gauss' formula,
+     * see src/http/ngx_http_parse_time.c
+     */
 
+    /* days since March 1, 1 BC */
     days = days - (31 + 28) + 719527;
 
-    year = days * 400 / (365 * 400 + 100 - 4 + 1);
+    /*
+     * The "days" should be adjusted to 1 only, however, some March 1st's go
+     * to previous year, so we adjust them to 2.  This causes also shift of the
+     * last Feburary days to next year, but we catch the case when "yday"
+     * becomes negative.
+     */
+
+    year = (days + 2) * 400 / (365 * 400 + 100 - 4 + 1);
+
     yday = days - (365 * year + year / 4 - year / 100 + year / 400);
 
-    mon = (yday + 31) * 12 / 367;
-    mday = yday - (mon * 367 / 12 - 31);
+    if (yday < 0) {
+        leap = (year % 4 == 0) && (year % 100 || (year % 400 == 0));
+        yday = 365 + leap + yday;
+        year--;
+    }
 
-    mon += 2;
+    /*
+     * The empirical formula that maps "yday" to month.
+     * There are at least 10 variants, some of them are:
+     *     mon = (yday + 31) * 15 / 459
+     *     mon = (yday + 31) * 17 / 520
+     *     mon = (yday + 31) * 20 / 612
+     */
+
+    mon = (yday + 31) * 10 / 306;
+
+    /* the Gauss' formula that evaluates days before the month */
+
+    mday = yday - (367 * mon / 12 - 30) + 1;
 
     if (yday >= 306) {
 
+        year++;
+        mon -= 10;
+
         /*
          * there is no "yday" in Win32 SYSTEMTIME
          *
          * yday -= 306;
          */
 
-        year++;
-        mon -= 12;
-
-        if (mday == 0) {
-            /* Jaunary 31 */
-            mon = 1;
-            mday = 31;
+    } else {
 
-        } else if (mon == 2) {
-
-            if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) {
-                if (mday > 29) {
-                    mon = 3;
-                    mday -= 29;
-                }
+        mon += 2;
 
-            } else if (mday > 28) {
-                mon = 3;
-                mday -= 28;
-            }
-        }
-/*
- *  there is no "yday" in Win32 SYSTEMTIME
- *
- *  } else {
- *      yday += 31 + 28;
- *
- *      if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) {
- *          yday++;
- *      }
- */
+        /*
+         * there is no "yday" in Win32 SYSTEMTIME
+         *
+         * yday += 31 + 28 + leap;
+         */
     }
 
     tp->ngx_tm_sec = (ngx_tm_sec_t) sec;
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -285,10 +285,11 @@ ngx_ssl_client_certificate(ngx_conf_t *c
 static int
 ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
 {
+#if (NGX_DEBUG)
     char              *subject, *issuer;
     int                err, depth;
     X509              *cert;
-    X509_NAME         *name;
+    X509_NAME         *sname, *iname;
     ngx_connection_t  *c;
     ngx_ssl_conn_t    *ssl_conn;
 
@@ -301,17 +302,26 @@ ngx_http_ssl_verify_callback(int ok, X50
     err = X509_STORE_CTX_get_error(x509_store);
     depth = X509_STORE_CTX_get_error_depth(x509_store);
 
-    name = X509_get_subject_name(cert);
-    subject = name ? X509_NAME_oneline(name, NULL, 0) : "(none)";
-
-    name = X509_get_issuer_name(cert);
-    issuer = name ? X509_NAME_oneline(name, NULL, 0) : "(none)";
+    sname = X509_get_subject_name(cert);
+    subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)";
+
+    iname = X509_get_issuer_name(cert);
+    issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)";
 
     ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
                    "verify:%d, error:%d, depth:%d, "
                    "subject:\"%s\",issuer: \"%s\"",
                    ok, err, depth, subject, issuer);
 
+    if (sname) {
+        OPENSSL_free(subject);
+    }
+
+    if (iname) {
+        OPENSSL_free(issuer);
+    }
+#endif
+
     return 1;
 }
 
@@ -1778,6 +1788,7 @@ ngx_ssl_get_subject_dn(ngx_connection_t 
 
     name = X509_get_subject_name(cert);
     if (name == NULL) {
+        X509_free(cert);
         return NGX_ERROR;
     }
 
@@ -1789,12 +1800,14 @@ ngx_ssl_get_subject_dn(ngx_connection_t 
     s->data = ngx_palloc(pool, len);
     if (s->data == NULL) {
         OPENSSL_free(p);
+        X509_free(cert);
         return NGX_ERROR;
     }
 
     ngx_memcpy(s->data, p, len);
 
     OPENSSL_free(p);
+    X509_free(cert);
 
     return NGX_OK;
 }
@@ -1817,6 +1830,7 @@ ngx_ssl_get_issuer_dn(ngx_connection_t *
 
     name = X509_get_issuer_name(cert);
     if (name == NULL) {
+        X509_free(cert);
         return NGX_ERROR;
     }
 
@@ -1828,12 +1842,14 @@ ngx_ssl_get_issuer_dn(ngx_connection_t *
     s->data = ngx_palloc(pool, len);
     if (s->data == NULL) {
         OPENSSL_free(p);
+        X509_free(cert);
         return NGX_ERROR;
     }
 
     ngx_memcpy(s->data, p, len);
 
     OPENSSL_free(p);
+    X509_free(cert);
 
     return NGX_OK;
 }
@@ -1855,6 +1871,7 @@ ngx_ssl_get_serial_number(ngx_connection
 
     bio = BIO_new(BIO_s_mem());
     if (bio == NULL) {
+        X509_free(cert);
         return NGX_ERROR;
     }
 
@@ -1865,11 +1882,13 @@ ngx_ssl_get_serial_number(ngx_connection
     s->data = ngx_palloc(pool, len);
     if (s->data == NULL) {
         BIO_free(bio);
+        X509_free(cert);
         return NGX_ERROR;
     }
 
     BIO_read(bio, s->data, len);
     BIO_free(bio);
+    X509_free(cert);
 
     return NGX_OK;
 }
--- a/src/http/modules/ngx_http_sub_filter_module.c
+++ b/src/http/modules/ngx_http_sub_filter_module.c
@@ -590,7 +590,7 @@ ngx_http_sub_parse(ngx_http_request_t *r
 
                 ctx->state = sub_start_state;
                 ctx->pos = p + 1;
-                ctx->looked = looked;
+                ctx->looked = 0;
                 ctx->copy_end = copy_end;
 
                 if (ctx->copy_start == NULL && copy_end) {
--- 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.29';
+our $VERSION = '0.6.30';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -19,7 +19,7 @@ static ngx_int_t ngx_http_add_names(ngx_
 static char *ngx_http_merge_locations(ngx_conf_t *cf,
     ngx_array_t *locations, void **loc_conf, ngx_http_module_t *module,
     ngx_uint_t ctx_index);
-static int ngx_http_cmp_conf_in_addrs(const void *one, const void *two);
+static ngx_int_t ngx_http_cmp_conf_in_addrs(const void *one, const void *two);
 static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one,
     const void *two);
 
@@ -1089,7 +1089,7 @@ ngx_http_merge_locations(ngx_conf_t *cf,
 }
 
 
-static int
+static ngx_int_t
 ngx_http_cmp_conf_in_addrs(const void *one, const void *two)
 {
     ngx_http_conf_in_addr_t  *first, *second;
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -45,7 +45,8 @@ static char *ngx_http_core_server(ngx_co
     void *dummy);
 static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
     void *dummy);
-static int ngx_http_core_cmp_locations(const void *first, const void *second);
+static ngx_int_t ngx_http_core_cmp_locations(const void *first,
+    const void *second);
 
 static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
@@ -2297,7 +2298,7 @@ ngx_http_core_location(ngx_conf_t *cf, n
 }
 
 
-static int
+static ngx_int_t
 ngx_http_core_cmp_locations(const void *one, const void *two)
 {
     ngx_int_t                  rc;
@@ -2361,7 +2362,7 @@ ngx_http_core_cmp_locations(const void *
         return 1;
     }
 
-    return (int) rc;
+    return rc;
 }
 
 
@@ -3470,6 +3471,7 @@ ngx_http_core_error_page(ngx_conf_t *cf,
 {
     ngx_http_core_loc_conf_t *lcf = conf;
 
+    u_char                     *args;
     ngx_int_t                   overwrite;
     ngx_str_t                  *value, uri;
     ngx_uint_t                  i, n, nvar;
@@ -3538,6 +3540,8 @@ ngx_http_core_error_page(ngx_conf_t *cf,
         }
     }
 
+    args = (u_char *) ngx_strchr(uri.data, '?');
+
     for (i = 1; i < cf->args->nelts - n; i++) {
         err = ngx_array_push(lcf->error_pages);
         if (err == NULL) {
@@ -3576,7 +3580,19 @@ ngx_http_core_error_page(ngx_conf_t *cf,
             }
         }
 
-        err->uri = uri;
+        if (args) {
+            err->uri.len = args - uri.data;
+            err->uri.data = uri.data;
+            args++;
+            err->args.len = (uri.data + uri.len) - args;
+            err->args.data = args;
+
+        } else {
+            err->uri = uri;
+            err->args.len = 0;
+            err->args.data = NULL;
+        }
+
         err->uri_lengths = uri_lengths;
         err->uri_values = uri_values;
     }
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -225,6 +225,7 @@ typedef struct {
     ngx_int_t                  status;
     ngx_int_t                  overwrite;
     ngx_str_t                  uri;
+    ngx_str_t                  args;
     ngx_array_t               *uri_lengths;
     ngx_array_t               *uri_values;
 } ngx_http_err_page_t;
--- a/src/http/ngx_http_parse_time.c
+++ b/src/http/ngx_http_parse_time.c
@@ -240,7 +240,7 @@ ngx_http_parse_time(u_char *value, size_
 
     /*
      * shift new year to March 1 and start months from 1 (not 0),
-     * it is needed for Gauss's formula
+     * it is needed for Gauss' formula
      */
 
     if (--month <= 0) {
@@ -248,11 +248,20 @@ ngx_http_parse_time(u_char *value, size_
         year -= 1;
     }
 
-    /* Gauss's formula for Grigorian days from March 1, 1 BC */
+    /* Gauss' formula for Grigorian days since March 1, 1 BC */
+
+    return (
+            /* days in years including leap years since March 1, 1 BC */
+
+            365 * year + year / 4 - year / 100 + year / 400
 
-    return (365 * year + year / 4 - year / 100 + year / 400
-            + 367 * month / 12 - 31
-            + day
+            /* days before the month */
+
+            + 367 * month / 12 - 30
+
+            /* days before the day */
+
+            + day - 1
 
             /*
              * 719527 days were between March 1, 1 BC and March 1, 1970,
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1419,6 +1419,7 @@ ngx_http_process_request(ngx_http_reques
 
     if (c->ssl) {
         long                      rc;
+        X509                     *cert;
         ngx_http_ssl_srv_conf_t  *sscf;
 
         sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
@@ -1438,9 +1439,9 @@ ngx_http_process_request(ngx_http_reques
                 return;
             }
 
-            if (SSL_get_peer_certificate(c->ssl->connection)
-                == NULL)
-            {
+            cert = SSL_get_peer_certificate(c->ssl->connection);
+
+            if (cert == NULL) {
                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
                               "client sent no required SSL certificate");
 
@@ -1450,6 +1451,8 @@ ngx_http_process_request(ngx_http_reques
                 ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
                 return;
             }
+
+            X509_free(cert);
         }
     }
 
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -441,8 +441,6 @@ ngx_http_send_error_page(ngx_http_reques
 
     r->zero_in_uri = 0;
 
-    args = NULL;
-
     if (err_page->uri_lengths) {
         if (ngx_http_script_run(r, &u, err_page->uri_lengths->elts, 0,
                                 err_page->uri_values->elts)
@@ -453,6 +451,7 @@ ngx_http_send_error_page(ngx_http_reques
 
         p = u.data;
         uri = &u;
+        args = NULL;
 
         if (*p == '/') {
 
@@ -488,6 +487,7 @@ ngx_http_send_error_page(ngx_http_reques
 
     } else {
         uri = &err_page->uri;
+        args = &err_page->args;
     }
 
     if (uri->data[0] == '/') {
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -333,7 +333,6 @@ ngx_http_upstream_init(ngx_http_request_
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
-    u->output.sendfile = c->sendfile;
     u->output.pool = r->pool;
     u->output.bufs.num = 1;
     u->output.bufs.size = clcf->client_body_buffer_size;
@@ -422,13 +421,14 @@ ngx_http_upstream_init(ngx_http_request_
         ctx->data = r;
         ctx->timeout = clcf->resolver_timeout;
 
+        u->resolved->ctx = ctx;
+
         if (ngx_resolve_name(ctx) != NGX_OK) {
+            u->resolved->ctx = NULL;
             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
             return;
         }
 
-        u->resolved->ctx = ctx;
-
         return;
     }
 
@@ -702,6 +702,7 @@ ngx_http_upstream_connect(ngx_http_reque
     c->read->handler = ngx_http_upstream_process_header;
 
     c->sendfile &= r->connection->sendfile;
+    u->output.sendfile = c->sendfile;
 
     c->pool = r->pool;
     c->read->log = c->write->log = c->log = r->connection->log;
@@ -2612,6 +2613,10 @@ ngx_http_upstream_copy_content_type(ngx_
 
         while (*++p == ' ') { /* void */ }
 
+        if (*p == '\0') {
+            return NGX_OK;
+        }
+
         if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) {
             continue;
         }
@@ -3200,7 +3205,7 @@ ngx_http_upstream_server(ngx_conf_t *cf,
 
             fail_timeout = ngx_parse_time(&s, 1);
 
-            if (fail_timeout < 0) {
+            if (fail_timeout == NGX_ERROR) {
                 goto invalid;
             }
 
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -9,7 +9,8 @@
 #include <ngx_http.h>
 
 
-static int ngx_http_upstream_cmp_servers(const void *one, const void *two);
+static ngx_int_t ngx_http_upstream_cmp_servers(const void *one,
+    const void *two);
 static ngx_uint_t
 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers);
 
@@ -185,7 +186,7 @@ ngx_http_upstream_init_round_robin(ngx_c
 }
 
 
-static int
+static ngx_int_t
 ngx_http_upstream_cmp_servers(const void *one, const void *two)
 {
     ngx_http_upstream_rr_peer_t  *first, *second;
--- a/src/mail/ngx_mail.c
+++ b/src/mail/ngx_mail.c
@@ -11,7 +11,7 @@
 
 
 static char *ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static int ngx_mail_cmp_conf_in_addrs(const void *one, const void *two);
+static ngx_int_t ngx_mail_cmp_conf_in_addrs(const void *one, const void *two);
 
 
 ngx_uint_t  ngx_mail_max_module;
@@ -388,7 +388,7 @@ ngx_mail_block(ngx_conf_t *cf, ngx_comma
 }
 
 
-static int
+static ngx_int_t
 ngx_mail_cmp_conf_in_addrs(const void *one, const void *two)
 {
     ngx_mail_conf_in_addr_t  *first, *second;
--- a/src/mail/ngx_mail_proxy_module.c
+++ b/src/mail/ngx_mail_proxy_module.c
@@ -171,6 +171,8 @@ ngx_mail_proxy_init(ngx_mail_session_t *
         return;
     }
 
+    s->out.len = 0;
+
     switch (s->protocol) {
 
     case NGX_MAIL_POP3_PROTOCOL:
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -257,7 +257,15 @@ ngx_open_dir(ngx_str_t *name, ngx_dir_t 
 ngx_int_t
 ngx_open_glob(ngx_glob_t *gl)
 {
-    if (glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob) == 0) {
+    int  n;
+
+    n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob);
+
+    if (n == 0) {
+        return NGX_OK;
+    }
+
+    if (n == GLOB_NOMATCH && gl->test) {
         return NGX_OK;
     }
 
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -17,8 +17,18 @@
 
 
 
+#ifdef __CYGWIN__
+
+#define ngx_open_file(name, mode, create, access)                            \
+    open((const char *) name, mode|create|O_BINARY, access)
+
+#else
+
 #define ngx_open_file(name, mode, create, access)                            \
     open((const char *) name, mode|create, access)
+
+#endif
+
 #define ngx_open_file_n          "open()"
 
 #define NGX_FILE_RDONLY          O_RDONLY
@@ -144,10 +154,11 @@ ngx_int_t ngx_open_dir(ngx_str_t *name, 
 
 
 typedef struct {
-    size_t      n;
-    glob_t      pglob;
-    u_char     *pattern;
-    ngx_log_t  *log;
+    size_t       n;
+    glob_t       pglob;
+    u_char      *pattern;
+    ngx_log_t   *log;
+    ngx_uint_t   test;
 } ngx_glob_t;
 
 
--- a/src/os/unix/ngx_posix_config.h
+++ b/src/os/unix/ngx_posix_config.h
@@ -70,7 +70,7 @@
 #include <limits.h>             /* IOV_MAX */
 #endif
 
-#if (NGX_HAVE_MALLOC_H)
+#ifdef __CYGWIN__
 #include <malloc.h>             /* memalign() */
 #endif
 
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -452,7 +452,7 @@ ngx_process_get_status(void)
              *
              * When several processes exit at the same time FreeBSD may
              * erroneously call the signal handler for exited process
-             * despite waitpid() may be already called for this process
+             * despite waitpid() may be already called for this process.
              */
 
             if (err == NGX_ECHILD) {
@@ -507,8 +507,9 @@ ngx_process_get_status(void)
 
         if (WEXITSTATUS(status) == 2 && ngx_processes[i].respawn) {
             ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
-                        "%s %P exited with fatal code %d and could not respawn",
-                        process, pid, WEXITSTATUS(status));
+                          "%s %P exited with fatal code %d "
+                          "and can not be respawn",
+                          process, pid, WEXITSTATUS(status));
             ngx_processes[i].respawn = 0;
         }
     }