diff src/os/unix/ngx_files.c @ 10:46833bd150cb NGINX_0_1_5

nginx 0.1.5 *) Bugfix: on Solaris and Linux there may be too many "recvmsg() returned not enough data" alerts. *) Bugfix: there were the "writev() failed (22: Invalid argument)" errors on Solaris in proxy mode without sendfile. On other platforms that do not support sendfile at all the process got caught in an endless loop. *) Bugfix: segmentation fault on Solaris in proxy mode and using sendfile. *) Bugfix: segmentation fault on Solaris. *) Bugfix: on-line upgrade did not work on Linux. *) Bugfix: the ngx_http_autoindex_module module did not escape the spaces, the quotes, and the percent signs in the directory listing. *) Change: the decrease of the copy operations. *) Feature: the userid_p3p directive.
author Igor Sysoev <http://sysoev.ru>
date Thu, 11 Nov 2004 00:00:00 +0300
parents 80ba094c6b3e
children 74b1868dd3cd
line wrap: on
line diff
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -13,7 +13,7 @@ ssize_t ngx_read_file(ngx_file_t *file, 
     ssize_t n;
 
     ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
-                   "read: %d, %X, %d, " OFF_T_FMT, file->fd, buf, size, offset);
+                   "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
 
 #if (NGX_PREAD)
 
@@ -57,6 +57,9 @@ ssize_t ngx_write_file(ngx_file_t *file,
 {
     ssize_t n;
 
+    ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
+                   "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
+
 #if (NGX_PWRITE)
 
     n = pwrite(file->fd, buf, size, offset);
@@ -68,7 +71,7 @@ ssize_t ngx_write_file(ngx_file_t *file,
 
     if ((size_t) n != size) {
         ngx_log_error(NGX_LOG_CRIT, file->log, 0,
-                      "pwrite() has written only %d of %d", n, size);
+                      "pwrite() has written only %z of %uz", n, size);
         return NGX_ERROR;
     }
 
@@ -92,7 +95,7 @@ ssize_t ngx_write_file(ngx_file_t *file,
 
     if ((size_t) n != size) {
         ngx_log_error(NGX_LOG_CRIT, file->log, 0,
-                      "write() has written only %d of %d", n, size);
+                      "write() has written only %z of %uz", n, size);
         return NGX_ERROR;
     }
 
@@ -120,17 +123,19 @@ int ngx_open_tempfile(u_char *name, ngx_
 }
 
 
+#define NGX_IOVS  8
+
 ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl,
                                 off_t offset, ngx_pool_t *pool)
 {
     u_char        *prev;
     size_t         size;
     ssize_t        n;
-    struct iovec  *iov;
     ngx_err_t      err;
-    ngx_array_t    io;
+    ngx_array_t    vec;
+    struct iovec  *iov, iovs[NGX_IOVS];
 
-    /* use pwrite() if there's the only buf in a chain */
+    /* use pwrite() if there is the only buf in a chain */
 
     if (cl->next == NULL) {
         return ngx_write_file(file, cl->buf->pos,
@@ -138,61 +143,74 @@ ssize_t ngx_write_chain_to_file(ngx_file
                               offset);
     }
 
-    prev = NULL;
-    iov = NULL;
-    size = 0;
+    vec.elts = iovs;
+    vec.size = sizeof(struct iovec);
+    vec.nalloc = NGX_IOVS; 
+    vec.pool = pool;
 
-    ngx_init_array(io, pool, 10, sizeof(struct iovec), NGX_ERROR);
+    do {
+        prev = NULL;
+        iov = NULL;
+        size = 0;
 
-    /* create the iovec and coalesce the neighbouring bufs */
+        vec.nelts = 0;
+
+        /* create the iovec and coalesce the neighbouring bufs */
 
-    while (cl) {
-        if (prev == cl->buf->pos) {
-            iov->iov_len += cl->buf->last - cl->buf->pos;
+        while (cl && vec.nelts < IOV_MAX) {
+            if (prev == cl->buf->pos) {
+                iov->iov_len += cl->buf->last - cl->buf->pos;
 
-        } else {
-            ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR);
-            iov->iov_base = (void *) cl->buf->pos;
-            iov->iov_len = cl->buf->last - cl->buf->pos;
+            } else {
+                if (!(iov = ngx_array_push(&vec))) {
+                    return NGX_ERROR;
+                }
+
+                iov->iov_base = (void *) cl->buf->pos;
+                iov->iov_len = cl->buf->last - cl->buf->pos;
+            }
+
+            size += cl->buf->last - cl->buf->pos;
+            prev = cl->buf->last;
+            cl = cl->next;
         }
 
-        size += cl->buf->last - cl->buf->pos;
-        prev = cl->buf->last;
-        cl = cl->next;
-    }
+        /* use pwrite() if there is the only iovec buffer */
 
-    /* use pwrite() if there's the only iovec buffer */
+        if (vec.nelts == 1) {
+            iov = vec.elts;
+            return ngx_write_file(file, (u_char *) iov[0].iov_base,
+                                  iov[0].iov_len, offset);
+        }
 
-    if (io.nelts == 1) {
-        iov = io.elts;
-        return ngx_write_file(file, (u_char *) iov[0].iov_base, iov[0].iov_len,
-                              offset);
-    }
+        if (file->sys_offset != offset) {
+            if (lseek(file->fd, offset, SEEK_SET) == -1) {
+                ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+                              "lseek() failed");
+                return NGX_ERROR;
+            }
 
-    if (file->sys_offset != offset) {
-        if (lseek(file->fd, offset, SEEK_SET) == -1) {
-            ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
+            file->sys_offset = offset;
+        }
+
+        n = writev(file->fd, vec.elts, vec.nelts);
+
+        if (n == -1) {
+            ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+                          "writev() failed");
             return NGX_ERROR;
         }
 
-        file->sys_offset = offset;
-    }
-
-    n = writev(file->fd, io.elts, io.nelts);
+        if ((size_t) n != size) {
+            ngx_log_error(NGX_LOG_CRIT, file->log, 0,
+                          "writev() has written only %z of %uz", n, size);
+            return NGX_ERROR;
+        }
 
-    if (n == -1) {
-        ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "writev() failed");
-        return NGX_ERROR;
-    }
+        file->sys_offset += n;
+        file->offset += n;
 
-    if ((size_t) n != size) {
-        ngx_log_error(NGX_LOG_CRIT, file->log, 0,
-                      "writev() has written only %d of %d", n, size);
-        return NGX_ERROR;
-    }
-
-    file->sys_offset += n;
-    file->offset += n;
+    } while (cl);
 
     return n;
 }