diff options
author | Igor Sysoev <igor@sysoev.ru> | 2004-12-02 18:40:46 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2004-12-02 18:40:46 +0000 |
commit | 42b12b34fa74c15cfb1746d71cde949f3d5807ef (patch) | |
tree | c44cd3f35d794e6e2be01d516e72737464f76fff /src/os/unix | |
parent | 4e7b11b02bd42ed284a5f006a13b0635fc33d556 (diff) | |
download | nginx-42b12b34fa74c15cfb1746d71cde949f3d5807ef.tar.gz nginx-42b12b34fa74c15cfb1746d71cde949f3d5807ef.zip |
nginx-0.1.11-RELEASE importrelease-0.1.11
*) 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
":/".
Diffstat (limited to 'src/os/unix')
-rw-r--r-- | src/os/unix/ngx_aio_write_chain.c | 6 | ||||
-rw-r--r-- | src/os/unix/ngx_files.h | 2 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_init.c | 3 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_sendfile_chain.c | 50 | ||||
-rw-r--r-- | src/os/unix/ngx_linux_sendfile_chain.c | 106 | ||||
-rw-r--r-- | src/os/unix/ngx_os.h | 3 | ||||
-rw-r--r-- | src/os/unix/ngx_posix_init.c | 7 | ||||
-rw-r--r-- | src/os/unix/ngx_process_cycle.c | 48 | ||||
-rw-r--r-- | src/os/unix/ngx_solaris_sendfilev_chain.c | 57 | ||||
-rw-r--r-- | src/os/unix/ngx_writev_chain.c | 12 |
10 files changed, 215 insertions, 79 deletions
diff --git a/src/os/unix/ngx_aio_write_chain.c b/src/os/unix/ngx_aio_write_chain.c index 4d45f079a..c1109dc12 100644 --- a/src/os/unix/ngx_aio_write_chain.c +++ b/src/os/unix/ngx_aio_write_chain.c @@ -20,6 +20,12 @@ ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in, ngx_err_t err; ngx_chain_t *cl; + /* the maximum limit size is the maximum size_t value - the page size */ + + if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) { + limit = MAX_SIZE_T_VALUE - ngx_pagesize; + } + send = 0; sent = 0; cl = in; diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h index 03de946a3..be9cebe6f 100644 --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -104,7 +104,7 @@ ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir); #else #define ngx_de_namelen(dir) ngx_strlen((dir)->de->d_name) #endif -#define ngx_de_info(name, dir) stat((const char *) name, &(dir)->info) +#define ngx_de_info(name, dir) lstat((const char *) name, &(dir)->info) #define ngx_de_info_n "stat()" #define ngx_de_is_dir(dir) (S_ISDIR((dir)->info.st_mode)) #define ngx_de_is_file(dir) (S_ISREG((dir)->info.st_mode)) diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c index b76dc0cb9..044d9d5c9 100644 --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -204,6 +204,9 @@ ngx_int_t ngx_os_init(ngx_log_t *log) } + ngx_tcp_nodelay_and_tcp_nopush = 1; + + return ngx_posix_init(log); } diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c index f86e1c0d7..187365cb2 100644 --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -37,9 +37,8 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, { int rc; u_char *prev; - off_t fprev, sent, send, sprev, aligned; - size_t hsize, fsize; - ssize_t size; + off_t size, send, prev_send, aligned, sent, fprev; + size_t header_size, file_size; ngx_uint_t eintr, eagain, complete; ngx_err_t err; ngx_buf_t *file; @@ -67,6 +66,12 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, #endif + /* the maximum limit size is the maximum size_t value - the page size */ + + if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) { + limit = MAX_SIZE_T_VALUE - ngx_pagesize; + } + send = 0; eagain = 0; @@ -82,11 +87,11 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, for ( ;; ) { file = NULL; - fsize = 0; - hsize = 0; + file_size = 0; + header_size = 0; eintr = 0; complete = 0; - sprev = send; + prev_send = send; header.nelts = 0; trailer.nelts = 0; @@ -115,7 +120,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } if (prev == cl->buf->pos) { - iov->iov_len += size; + iov->iov_len += (size_t) size; } else { if (!(iov = ngx_array_push(&header))) { @@ -123,11 +128,11 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } iov->iov_base = (void *) cl->buf->pos; - iov->iov_len = size; + iov->iov_len = (size_t) size; } - prev = cl->buf->pos + size; - hsize += size; + prev = cl->buf->pos + (size_t) size; + header_size += (size_t) size; send += size; } @@ -138,7 +143,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, /* coalesce the neighbouring file bufs */ do { - size = (size_t) (cl->buf->file_last - cl->buf->file_pos); + size = cl->buf->file_last - cl->buf->file_pos; if (send + size > limit) { size = limit - send; @@ -151,7 +156,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } } - fsize += size; + file_size += (size_t) size; send += size; fprev = cl->buf->file_pos + size; cl = cl->next; @@ -189,7 +194,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } if (prev == cl->buf->pos) { - iov->iov_len += size; + iov->iov_len += (size_t) size; } else { if (!(iov = ngx_array_push(&trailer))) { @@ -197,10 +202,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } iov->iov_base = (void *) cl->buf->pos; - iov->iov_len = size; + iov->iov_len = (size_t) size; } - prev = cl->buf->pos + size; + prev = cl->buf->pos + (size_t) size; send += size; cl = cl->next; } @@ -245,13 +250,13 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, */ if (ngx_freebsd_sendfile_nbytes_bug == 0) { - hsize = 0; + header_size = 0; } sent = 0; rc = sendfile(file->file->fd, c->fd, file->file_pos, - fsize + hsize, &hdtr, &sent, 0); + file_size + header_size, &hdtr, &sent, 0); if (rc == -1) { err = ngx_errno; @@ -265,8 +270,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, - "sendfile() sent only %O bytes", - sent); + "sendfile() sent only %O bytes", sent); } else { wev->error = 1; @@ -291,13 +295,13 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, "sendfile: %d, @%O %O:%uz", - rc, file->file_pos, sent, fsize + hsize); + rc, file->file_pos, sent, file_size + header_size); } else { rc = writev(c->fd, header.elts, header.nelts); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "writev: %d of %uz", rc, hsize); + "writev: %d of %uz", rc, header_size); if (rc == -1) { err = ngx_errno; @@ -320,7 +324,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, sent = rc > 0 ? rc : 0; } - if (send - sprev == sent) { + if (send - prev_send == sent) { complete = 1; } @@ -353,7 +357,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } if (ngx_buf_in_memory(cl->buf)) { - cl->buf->pos += sent; + cl->buf->pos += (size_t) sent; } if (cl->buf->in_file) { diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c index bcf9d4c76..c09d03675 100644 --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -25,11 +25,10 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) { - int rc; + int rc, tcp_nodelay; u_char *prev; - off_t fprev, send, sprev, aligned; - size_t fsize; - ssize_t size, sent; + off_t size, send, prev_send, aligned, sent, fprev; + size_t file_size; ngx_uint_t eintr, complete; ngx_err_t err; ngx_buf_t *file; @@ -49,6 +48,14 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, return in; } + + /* the maximum limit size is the maximum size_t value - the page size */ + + if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) { + limit = MAX_SIZE_T_VALUE - ngx_pagesize; + } + + send = 0; header.elts = headers; @@ -58,10 +65,10 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, for ( ;; ) { file = NULL; - fsize = 0; + file_size = 0; eintr = 0; complete = 0; - sprev = send; + prev_send = send; header.nelts = 0; @@ -89,7 +96,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } if (prev == cl->buf->pos) { - iov->iov_len += size; + iov->iov_len += (size_t) size; } else { if (!(iov = ngx_array_push(&header))) { @@ -97,10 +104,10 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } iov->iov_base = (void *) cl->buf->pos; - iov->iov_len = size; + iov->iov_len = (size_t) size; } - prev = cl->buf->pos + size; + prev = cl->buf->pos + (size_t) size; send += size; } @@ -111,25 +118,62 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, && cl && cl->buf->in_file) { - if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { - err = ngx_errno; - /* - * there is a tiny chance to be interrupted, however - * we continue a processing without the TCP_CORK - */ + /* the TCP_CORK and TCP_NODELAY are mutually exclusive */ - if (err != NGX_EINTR) { - wev->error = 1; - ngx_connection_error(c, err, ngx_tcp_nopush_n " failed"); - return NGX_CHAIN_ERROR; + if (c->tcp_nodelay) { + + tcp_nodelay = 0; + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + err = ngx_errno; + + /* + * there is a tiny chance to be interrupted, however + * we continue a processing with the TCP_NODELAY + * and without the TCP_CORK + */ + + if (err != NGX_EINTR) { + wev->error = 1; + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + return NGX_CHAIN_ERROR; + } + + } else { + c->tcp_nodelay = 0; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "no tcp_nodelay"); } + } - } else { - c->tcp_nopush = NGX_TCP_NOPUSH_SET; + if (!c->tcp_nodelay) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "tcp_nopush"); + if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { + err = ngx_errno; + + /* + * there is a tiny chance to be interrupted, however + * we continue a processing without the TCP_CORK + */ + + if (err != NGX_EINTR) { + wev->error = 1; + ngx_connection_error(c, err, + ngx_tcp_nopush_n " failed"); + return NGX_CHAIN_ERROR; + } + + } else { + c->tcp_nopush = NGX_TCP_NOPUSH_SET; + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "tcp_nopush"); + } } } @@ -141,7 +185,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, /* coalesce the neighbouring file bufs */ do { - size = (size_t) (cl->buf->file_last - cl->buf->file_pos); + size = cl->buf->file_last - cl->buf->file_pos; if (send + size > limit) { size = limit - send; @@ -154,7 +198,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } } - fsize += size; + file_size += (size_t) size; send += size; fprev = cl->buf->file_pos + size; cl = cl->next; @@ -172,7 +216,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, #else offset = (int32_t) file->file_pos; #endif - rc = sendfile(c->fd, file->file->fd, &offset, fsize); + rc = sendfile(c->fd, file->file->fd, &offset, file_size); if (rc == -1) { err = ngx_errno; @@ -195,8 +239,8 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, sent = rc > 0 ? rc : 0; ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, - "sendfile: %d, @%O %z:%uz", - rc, file->file_pos, sent, fsize); + "sendfile: %d, @%O %O:%uz", + rc, file->file_pos, sent, file_size); } else { rc = writev(c->fd, header.elts, header.nelts); @@ -221,10 +265,10 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, sent = rc > 0 ? rc : 0; - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %z", sent); + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %O", sent); } - if (send - sprev == sent) { + if (send - prev_send == sent) { complete = 1; } @@ -257,7 +301,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, } if (ngx_buf_in_memory(cl->buf)) { - cl->buf->pos += sent; + cl->buf->pos += (size_t) sent; } if (cl->buf->in_file) { diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h index ee91df336..42fc88629 100644 --- a/src/os/unix/ngx_os.h +++ b/src/os/unix/ngx_os.h @@ -50,7 +50,8 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, extern ngx_os_io_t ngx_os_io; extern ngx_int_t ngx_ncpu; extern ngx_int_t ngx_max_sockets; -extern ngx_int_t ngx_inherited_nonblocking; +extern ngx_uint_t ngx_inherited_nonblocking; +extern ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush; #define ngx_stderr_fileno STDERR_FILENO diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c index 56be0cefb..626d821e9 100644 --- a/src/os/unix/ngx_posix_init.c +++ b/src/os/unix/ngx_posix_init.c @@ -8,9 +8,10 @@ #include <ngx_core.h> -ngx_int_t ngx_ncpu; -ngx_int_t ngx_max_sockets; -ngx_int_t ngx_inherited_nonblocking; +ngx_int_t ngx_ncpu; +ngx_int_t ngx_max_sockets; +ngx_uint_t ngx_inherited_nonblocking; +ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush; struct rlimit rlmt; diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 3d1c51bc0..c3b9905b0 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -17,7 +17,7 @@ static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo); static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle); static void ngx_master_exit(ngx_cycle_t *cycle); static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); -static void ngx_worker_process_init(ngx_cycle_t *cycle); +static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority); static void ngx_channel_handler(ngx_event_t *ev); #if (NGX_THREADS) static void ngx_wakeup_worker_threads(ngx_cycle_t *cycle); @@ -564,6 +564,33 @@ static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle) continue; } + + ch.command = NGX_CMD_OPEN_CHANNEL; + ch.pid = ngx_processes[ngx_process_slot].pid; + ch.slot = ngx_process_slot; + ch.fd = ngx_processes[ngx_process_slot].channel[0]; + + for (n = 0; n < ngx_last_process; n++) { + + if (n == ngx_process_slot + || ngx_processes[n].pid == -1 + || ngx_processes[n].channel[0] == -1) + { + continue; + } + + ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0, + "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d", + ch.slot, ch.pid, ch.fd, + n, ngx_processes[n].pid, + ngx_processes[n].channel[0]); + + /* TODO: NGX_AGAIN */ + + ngx_write_channel(ngx_processes[n].channel[0], + &ch, sizeof(ngx_channel_t), cycle->log); + } + live = 1; continue; @@ -611,7 +638,7 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) ngx_err_t err; ngx_core_conf_t *ccf; - ngx_worker_process_init(cycle); + ngx_worker_process_init(cycle, 1); ngx_setproctitle("worker process"); @@ -718,7 +745,7 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) } -static void ngx_worker_process_init(ngx_cycle_t *cycle) +static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority) { sigset_t set; ngx_int_t n; @@ -739,6 +766,13 @@ static void ngx_worker_process_init(ngx_cycle_t *cycle) 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 (setgid(ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setgid(%d) failed", ccf->group); @@ -746,6 +780,12 @@ static void ngx_worker_process_init(ngx_cycle_t *cycle) exit(2); } + if (initgroups(ccf->username, ccf->group) == -1) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "initgroups(%s, %d) failed", + ccf->username, ccf->group); + } + if (setuid(ccf->user) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setuid(%d) failed", ccf->user); @@ -1041,7 +1081,7 @@ static void ngx_garbage_collector_cycle(ngx_cycle_t *cycle, void *data) ngx_path_t **path; ngx_event_t *ev; - ngx_worker_process_init(cycle); + ngx_worker_process_init(cycle, 0); ev = &cycle->read_events[ngx_channel]; diff --git a/src/os/unix/ngx_solaris_sendfilev_chain.c b/src/os/unix/ngx_solaris_sendfilev_chain.c index 21f8b8f7c..4c873aa11 100644 --- a/src/os/unix/ngx_solaris_sendfilev_chain.c +++ b/src/os/unix/ngx_solaris_sendfilev_chain.c @@ -9,6 +9,28 @@ #include <ngx_event.h> +#if (NGX_TEST_BUILD_SOLARIS_SENDFILEV) + +/* Solaris declarations */ + +typedef struct sendfilevec { + int sfv_fd; + u_int sfv_flag; + off_t sfv_off; + size_t sfv_len; +} sendfilevec_t; + +#define SFV_FD_SELF -2 + +static ssize_t sendfilev(int fd, const struct sendfilevec *vec, + int sfvcnt, size_t *xferred) +{ + return -1; +} + +#endif + + #define NGX_SENDFILEVECS 16 @@ -17,8 +39,9 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, { int fd; u_char *prev; - off_t fprev, sprev, send, aligned; - ssize_t size, sent, n; + off_t size, send, prev_send, aligned, fprev; + size_t sent; + ssize_t n; ngx_int_t eintr, complete; ngx_err_t err; sendfilevec_t *sfv, sfvs[NGX_SENDFILEVECS]; @@ -36,6 +59,14 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, return ngx_writev_chain(c, in, limit); } + + /* the maximum limit size is the maximum size_t value - the page size */ + + if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) { + limit = MAX_SIZE_T_VALUE - ngx_pagesize; + } + + send = 0; complete = 0; @@ -51,7 +82,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, sfv = NULL; eintr = 0; sent = 0; - sprev = send; + prev_send = send; vec.nelts = 0; @@ -73,7 +104,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, } if (prev == cl->buf->pos) { - sfv->sfv_len += size; + sfv->sfv_len += (size_t) size; } else { if (!(sfv = ngx_array_push(&vec))) { @@ -83,16 +114,16 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, sfv->sfv_fd = SFV_FD_SELF; sfv->sfv_flag = 0; sfv->sfv_off = (off_t) (uintptr_t) cl->buf->pos; - sfv->sfv_len = size; + sfv->sfv_len = (size_t) size; } - prev = cl->buf->pos + size; + prev = cl->buf->pos + (size_t) size; send += size; } else { prev = NULL; - size = (size_t) (cl->buf->file_last - cl->buf->file_pos); + size = cl->buf->file_last - cl->buf->file_pos; if (send + size > limit) { size = limit - send; @@ -106,7 +137,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, } if (fd == cl->buf->file->fd && fprev == cl->buf->file_pos) { - sfv->sfv_len += size; + sfv->sfv_len += (size_t) size; } else { if (!(sfv = ngx_array_push(&vec))) { @@ -117,7 +148,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, sfv->sfv_fd = fd; sfv->sfv_flag = 0; sfv->sfv_off = cl->buf->file_pos; - sfv->sfv_len = size; + sfv->sfv_len = (size_t) size; } fprev = cl->buf->file_pos + size; @@ -136,7 +167,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, - "sendfilev() sent only %z bytes", sent); + "sendfilev() sent only %uz bytes", sent); } else { wev->error = 1; @@ -148,7 +179,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, "sendfilev: %z %z", n, sent); - if (send - sprev == sent) { + if (send - prev_send == (off_t) sent) { complete = 1; } @@ -166,8 +197,8 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, size = ngx_buf_size(cl->buf); - if (sent >= size) { - sent -= size; + if ((off_t) sent >= size) { + sent = (size_t) ((off_t) sent - size); if (ngx_buf_in_memory(cl->buf)) { cl->buf->pos = cl->buf->last; diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c index 2af64699b..8f1087b26 100644 --- a/src/os/unix/ngx_writev_chain.c +++ b/src/os/unix/ngx_writev_chain.c @@ -16,7 +16,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) { u_char *prev; ssize_t n, size, sent; - off_t send, sprev; + off_t send, prev_send; ngx_uint_t eintr, complete; ngx_err_t err; ngx_array_t vec; @@ -42,6 +42,12 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) #endif + /* the maximum limit size is the maximum size_t value - the page size */ + + if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) { + limit = MAX_SIZE_T_VALUE - ngx_pagesize; + } + send = 0; complete = 0; @@ -54,7 +60,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) prev = NULL; iov = NULL; eintr = 0; - sprev = send; + prev_send = send; vec.nelts = 0; @@ -118,7 +124,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %z", sent); - if (send - sprev == sent) { + if (send - prev_send == sent) { complete = 1; } |