nginx-0.1.11-RELEASE import

    *) Feature: the worker_priority directive.

    *) Change: both tcp_nopush and tcp_nodelay directives affect the
       transferred response.

    *) Bugfix: nginx did not call initgroups().
       Thanks to Andrew Sitnikov and Andrei Nigmatulin.

    *) Change: now the ngx_http_autoindex_module shows the file size in the
       bytes.

    *) Bugfix: the ngx_http_autoindex_module returned the 500 error if the
       broken symlink was in a directory.

    *) Bugfix: the files bigger than 4G could not be transferred using
       sendfile.

    *) Bugfix: if the backend was resolved to several backends and there
       was an error while the response waiting then process may got caught
       in an endless loop.

    *) Bugfix: the worker process may exit with the "unknown cycle" message
       when the /dev/poll method was used.

    *) Bugfix: "close() channel failed" errors.

    *) Bugfix: the autodetection of the "nobody" and "nogroup" groups.

    *) Bugfix: the send_lowat directive did not work on Linux.

    *) Bugfix: the segmentation fault occurred if there was no events
       section in configuration.

    *) Bugfix: nginx could not be built on OpenBSD.

    *) Bugfix: the double slashes in "://" in the URI were converted to
       ":/".
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 887fc79..26406b3 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -16,6 +16,7 @@
 static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
 static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
 static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 
 
 static ngx_conf_enum_t  ngx_debug_points[] = {
@@ -80,6 +81,13 @@
       0,
       NULL },
 
+    { ngx_string("worker_priority"),
+      NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
+      ngx_set_priority,
+      0,
+      0,
+      NULL },
+
     { ngx_string("pid"),
       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_str_slot,
@@ -447,6 +455,7 @@
      *
      * ccf->pid = NULL;
      * ccf->newpid = NULL;
+     * ccf->priority = 0;
      */
     ccf->daemon = NGX_CONF_UNSET;
     ccf->master = NGX_CONF_UNSET;
@@ -494,6 +503,7 @@
             return NGX_CONF_ERROR;
         }
 
+        ccf->username = NGX_USER;
         ccf->user = pwd->pw_uid;
 
         grp = getgrnam(NGX_GROUP);
@@ -562,6 +572,8 @@
 
     value = (ngx_str_t *) cf->args->elts;
 
+    ccf->username = (char *) value[1].data;
+
     pwd = getpwnam((const char *) value[1].data);
     if (pwd == NULL) {
         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
@@ -586,3 +598,42 @@
 
 #endif
 }
+
+
+static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+    ngx_core_conf_t  *ccf = conf;
+
+    ngx_str_t        *value;
+    ngx_uint_t        n, minus;
+
+    if (ccf->priority != 0) {
+        return "is duplicate";
+    }
+
+    value = cf->args->elts;
+
+    if (value[1].data[0] == '-') {
+        n = 1;
+        minus = 1;
+
+    } else if (value[1].data[0] == '+') {
+        n = 1;
+        minus = 0;
+
+    } else {
+        n = 0;
+        minus = 0;
+    }
+
+    ccf->priority = ngx_atoi(&value[1].data[n], value[1].len - n);
+    if (ccf->priority == NGX_ERROR) {
+        return "invalid number";
+    }
+
+    if (minus) {
+        ccf->priority = -ccf->priority;
+    }
+
+    return NGX_CONF_OK;
+}
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 9b61fc9..3ac28f1 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.1.10"
+#define NGINX_VER          "nginx/0.1.11"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_NEWPID_EXT     ".newbin"
diff --git a/src/core/ngx_buf.h b/src/core/ngx_buf.h
index e2d0719..768400d 100644
--- a/src/core/ngx_buf.h
+++ b/src/core/ngx_buf.h
@@ -109,8 +109,8 @@
         ((b->flush || b->last_buf) && !ngx_buf_in_memory(b) && !b->in_file)
 
 #define ngx_buf_size(b)                                                      \
-        (ngx_buf_in_memory(b) ? (size_t) (b->last - b->pos):                 \
-                                (size_t) (b->file_last - b->file_pos))
+        (ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos):                  \
+                                (b->file_last - b->file_pos))
 
 ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size);
 ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index 7d4463b..b72add7 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -39,6 +39,11 @@
 #endif
 
 
+#ifndef NGX_HAVE_SO_SNDLOWAT
+#define NGX_HAVE_SO_SNDLOWAT     1
+#endif
+
+
 #if !(NGX_WIN32)
 
 #define ngx_signal_helper(n)     SIG##n
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index d91ba85..9592a81 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -50,7 +50,6 @@
     ngx_open_file_t    *file;
     ngx_listening_t    *ls, *nls;
     ngx_core_conf_t    *ccf;
-    ngx_event_conf_t   *ecf;
     ngx_core_module_t  *module;
 
     log = old_cycle->log;
@@ -434,12 +433,6 @@
     }
 
 
-    ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
-    ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
-                  "using the \"%s\" event method", ecf->name);
-
-
     /* close and delete stuff that lefts from an old cycle */
 
     /* close the unneeded listening sockets */
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index 2baf829..face67f 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -17,51 +17,54 @@
 
 
 struct ngx_cycle_s {
-    void           ****conf_ctx;
-    ngx_pool_t        *pool;
+    void                  ****conf_ctx;
+    ngx_pool_t               *pool;
 
-    ngx_log_t         *log;
-    ngx_log_t         *new_log;
+    ngx_log_t                *log;
+    ngx_log_t                *new_log;
 
-    ngx_array_t        listening;
-    ngx_array_t        pathes;
-    ngx_list_t         open_files;
+    ngx_array_t               listening;
+    ngx_array_t               pathes;
+    ngx_list_t                open_files;
 
-    ngx_uint_t         connection_n;
-    ngx_connection_t  *connections;
-    ngx_event_t       *read_events;
-    ngx_event_t       *write_events;
+    ngx_uint_t                connection_n;
+    ngx_connection_t         *connections;
+    ngx_event_t              *read_events;
+    ngx_event_t              *write_events;
 
-    ngx_cycle_t       *old_cycle;
+    ngx_cycle_t              *old_cycle;
 
-    ngx_str_t          conf_file;
-    ngx_str_t          root;
+    ngx_str_t                 conf_file;
+    ngx_str_t                 root;
 };
 
 
 typedef struct {
-     ngx_flag_t  daemon;
-     ngx_flag_t  master;
+     ngx_flag_t               daemon;
+     ngx_flag_t               master;
 
-     ngx_int_t   worker_processes;
-     ngx_int_t   debug_points;
+     ngx_int_t                worker_processes;
+     ngx_int_t                debug_points;
 
-     ngx_uid_t   user;
-     ngx_gid_t   group;
+     int                      priority;
 
-     ngx_str_t   pid;
-     ngx_str_t   newpid;
+     char                    *username;
+     ngx_uid_t                user;
+     ngx_gid_t                group;
+
+     ngx_str_t                pid;
+     ngx_str_t                newpid;
 
 #if (NGX_THREADS)
-     ngx_int_t   worker_threads;
-     size_t      thread_stack_size;
+     ngx_int_t                worker_threads;
+     size_t                   thread_stack_size;
 #endif
 
 } ngx_core_conf_t;
 
 
 typedef struct {
-     ngx_pool_t  *pool;   /* pcre's malloc() pool */
+     ngx_pool_t              *pool;   /* pcre's malloc() pool */
 } ngx_core_tls_t;
 
 
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index 1c367cc..b925e48 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -28,7 +28,8 @@
 ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
 {
     int           rc, last;
-    size_t        size, bsize;
+    off_t         bsize;
+    size_t        size;
     ngx_chain_t  *cl, *out, **last_out;
 
     if (ctx->in == NULL && ctx->busy == NULL) {
@@ -81,6 +82,8 @@
                 ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
                               "zero size buf");
 
+                ngx_debug_point();
+
                 ctx->in = ctx->in->next;
 
                 continue;
@@ -118,18 +121,18 @@
 
                     if (ctx->in->buf->last_buf) {
 
-                        if (bsize < ctx->bufs.size) {
+                        if (bsize < (off_t) ctx->bufs.size) {
 
                            /*
                             * allocate small temp buf for the small last buf
                             * or its small last part
                             */
 
-                            size = bsize;
+                            size = (size_t) bsize;
 
                         } else if (ctx->bufs.num == 1
-                                   && (bsize < ctx->bufs.size
-                                                     + (ctx->bufs.size >> 2)))
+                                   && (bsize < (off_t) (ctx->bufs.size
+                                                     + (ctx->bufs.size >> 2))))
                         {
                             /*
                              * allocate a temp buf that equals
@@ -137,7 +140,7 @@
                              * than 1.25 of bufs.size and a temp buf is single
                              */
 
-                            size = bsize;
+                            size = (size_t) bsize;
                         }
                     }
 
@@ -306,12 +309,12 @@
 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
                                            ngx_uint_t sendfile)
 {
-    size_t   size;
+    off_t    size;
     ssize_t  n;
 
     size = ngx_buf_size(src);
 
-    if (size > (size_t) (dst->end - dst->pos)) {
+    if (size > dst->end - dst->pos) {
         size = dst->end - dst->pos;
     }
 
@@ -324,9 +327,9 @@
 #endif
 
     if (ngx_buf_in_memory(src)) {
-        ngx_memcpy(dst->pos, src->pos, size);
-        src->pos += size;
-        dst->last += size;
+        ngx_memcpy(dst->pos, src->pos, (size_t) size);
+        src->pos += (size_t) size;
+        dst->last += (size_t) size;
 
         if (src->in_file) {
 
@@ -351,7 +354,7 @@
         }
 
     } else {
-        n = ngx_read_file(src->file, dst->pos, size, src->file_pos);
+        n = ngx_read_file(src->file, dst->pos, (size_t) size, src->file_pos);
 
         if (n == NGX_ERROR) {
             return n;
@@ -363,9 +366,9 @@
         }
 #endif
 
-        if ((size_t) n != size) {
+        if (n != size) {
             ngx_log_error(NGX_LOG_ALERT, src->file->log, 0,
-                          ngx_read_file_n " reads only %z of %uz from file",
+                          ngx_read_file_n " reads only %z of %O from file",
                           n, size);
             if (n == 0) {
                 return NGX_ERROR;
@@ -399,10 +402,19 @@
 {
     ngx_chain_writer_ctx_t *ctx = data;
 
+    off_t         size;
     ngx_chain_t  *cl;
 
 
-    for (/* void */; in; in = in->next) {
+    for (size = 0; in; in = in->next) {
+
+#if 1
+        if (ngx_buf_size(in->buf) == 0 && !ngx_buf_special(in->buf)) {
+            ngx_debug_point();
+        }
+#endif
+
+        size += ngx_buf_size(in->buf);
 
         ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
                        "chain writer buf size: %uz", ngx_buf_size(in->buf));
@@ -419,6 +431,23 @@
     ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
                    "chain writer in: %p", ctx->out);
 
+    for (cl = ctx->out; cl; cl = cl->next) {
+
+#if 1
+
+        if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
+            ngx_debug_point();
+        }
+
+#endif
+
+        size += ngx_buf_size(cl->buf);
+    }
+
+    if (size == 0) {
+        return NGX_OK;
+    }
+
     ctx->out = ngx_send_chain(ctx->connection, ctx->out, ctx->limit);
 
     ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 4e5d273..4c21fa6 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -30,7 +30,7 @@
 
 /*
  * supported formats:
- *    %[0][width]O              off_t
+ *    %[0][width][x][X]O        off_t
  *    %[0][width]T              time_t
  *    %[0][width][u][x|X]z      ssize_t/size_t
  *    %[0][width][u][x|X]d      int/u_int