[nginx] Truncation detection in sendfilev() on Solaris.

Maxim Dounin mdounin at mdounin.ru
Tue Mar 15 15:28:31 UTC 2016


details:   http://hg.nginx.org/nginx/rev/646985c55393
branches:  
changeset: 6438:646985c55393
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Tue Mar 15 18:26:59 2016 +0300
description:
Truncation detection in sendfilev() on Solaris.

While sendfilev() is documented to return -1 with EINVAL set
if the file was truncated, at least Solaris 11 silently returns 0,
and this results in CPU hog.  Added a test to complain appropriately
if 0 is returned.

diffstat:

 src/os/unix/ngx_solaris_sendfilev_chain.c |  23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diffs (54 lines):

diff --git a/src/os/unix/ngx_solaris_sendfilev_chain.c b/src/os/unix/ngx_solaris_sendfilev_chain.c
--- a/src/os/unix/ngx_solaris_sendfilev_chain.c
+++ b/src/os/unix/ngx_solaris_sendfilev_chain.c
@@ -48,6 +48,7 @@ ngx_solaris_sendfilev_chain(ngx_connecti
     ssize_t         n;
     ngx_int_t       eintr;
     ngx_err_t       err;
+    ngx_buf_t      *file;
     ngx_uint_t      nsfv;
     sendfilevec_t  *sfv, sfvs[NGX_SENDFILEVECS];
     ngx_event_t    *wev;
@@ -77,6 +78,7 @@ ngx_solaris_sendfilev_chain(ngx_connecti
         fd = SFV_FD_SELF;
         prev = NULL;
         fprev = 0;
+        file = NULL;
         sfv = NULL;
         eintr = 0;
         sent = 0;
@@ -153,6 +155,7 @@ ngx_solaris_sendfilev_chain(ngx_connecti
                     sfv->sfv_len = (size_t) size;
                 }
 
+                file = cl->buf;
                 fprev = cl->buf->file_pos + size;
                 send += size;
             }
@@ -179,6 +182,26 @@ ngx_solaris_sendfilev_chain(ngx_connecti
 
             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
                           "sendfilev() sent only %uz bytes", sent);
+
+        } else if (n == 0 && sent == 0) {
+
+            /*
+             * sendfilev() is documented to return -1 with errno
+             * set to EINVAL if svf_len is greater than the file size,
+             * but at least Solaris 11 returns 0 instead
+             */
+
+            if (file) {
+                ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                        "sendfilev() reported that \"%s\" was truncated at %O",
+                        file->file->name.data, file->file_pos);
+
+            } else {
+                ngx_log_error(NGX_LOG_ALERT, c->log, 0,
+                              "sendfilev() returned 0 with memory buffers");
+            }
+
+            return NGX_CHAIN_ERROR;
         }
 
         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,



More information about the nginx-devel mailing list