Mercurial > hg > nginx-vendor-0-7
comparison 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 |
comparison
equal
deleted
inserted
replaced
9:77eee314ddbd | 10:46833bd150cb |
---|---|
11 ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) | 11 ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) |
12 { | 12 { |
13 ssize_t n; | 13 ssize_t n; |
14 | 14 |
15 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, | 15 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, |
16 "read: %d, %X, %d, " OFF_T_FMT, file->fd, buf, size, offset); | 16 "read: %d, %p, %uz, %O", file->fd, buf, size, offset); |
17 | 17 |
18 #if (NGX_PREAD) | 18 #if (NGX_PREAD) |
19 | 19 |
20 n = pread(file->fd, buf, size, offset); | 20 n = pread(file->fd, buf, size, offset); |
21 | 21 |
55 | 55 |
56 ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) | 56 ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset) |
57 { | 57 { |
58 ssize_t n; | 58 ssize_t n; |
59 | 59 |
60 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, | |
61 "write: %d, %p, %uz, %O", file->fd, buf, size, offset); | |
62 | |
60 #if (NGX_PWRITE) | 63 #if (NGX_PWRITE) |
61 | 64 |
62 n = pwrite(file->fd, buf, size, offset); | 65 n = pwrite(file->fd, buf, size, offset); |
63 | 66 |
64 if (n == -1) { | 67 if (n == -1) { |
66 return NGX_ERROR; | 69 return NGX_ERROR; |
67 } | 70 } |
68 | 71 |
69 if ((size_t) n != size) { | 72 if ((size_t) n != size) { |
70 ngx_log_error(NGX_LOG_CRIT, file->log, 0, | 73 ngx_log_error(NGX_LOG_CRIT, file->log, 0, |
71 "pwrite() has written only %d of %d", n, size); | 74 "pwrite() has written only %z of %uz", n, size); |
72 return NGX_ERROR; | 75 return NGX_ERROR; |
73 } | 76 } |
74 | 77 |
75 #else | 78 #else |
76 | 79 |
90 return NGX_ERROR; | 93 return NGX_ERROR; |
91 } | 94 } |
92 | 95 |
93 if ((size_t) n != size) { | 96 if ((size_t) n != size) { |
94 ngx_log_error(NGX_LOG_CRIT, file->log, 0, | 97 ngx_log_error(NGX_LOG_CRIT, file->log, 0, |
95 "write() has written only %d of %d", n, size); | 98 "write() has written only %z of %uz", n, size); |
96 return NGX_ERROR; | 99 return NGX_ERROR; |
97 } | 100 } |
98 | 101 |
99 file->sys_offset += n; | 102 file->sys_offset += n; |
100 | 103 |
117 } | 120 } |
118 | 121 |
119 return fd; | 122 return fd; |
120 } | 123 } |
121 | 124 |
125 | |
126 #define NGX_IOVS 8 | |
122 | 127 |
123 ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, | 128 ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, |
124 off_t offset, ngx_pool_t *pool) | 129 off_t offset, ngx_pool_t *pool) |
125 { | 130 { |
126 u_char *prev; | 131 u_char *prev; |
127 size_t size; | 132 size_t size; |
128 ssize_t n; | 133 ssize_t n; |
129 struct iovec *iov; | |
130 ngx_err_t err; | 134 ngx_err_t err; |
131 ngx_array_t io; | 135 ngx_array_t vec; |
132 | 136 struct iovec *iov, iovs[NGX_IOVS]; |
133 /* use pwrite() if there's the only buf in a chain */ | 137 |
138 /* use pwrite() if there is the only buf in a chain */ | |
134 | 139 |
135 if (cl->next == NULL) { | 140 if (cl->next == NULL) { |
136 return ngx_write_file(file, cl->buf->pos, | 141 return ngx_write_file(file, cl->buf->pos, |
137 (size_t) (cl->buf->last - cl->buf->pos), | 142 (size_t) (cl->buf->last - cl->buf->pos), |
138 offset); | 143 offset); |
139 } | 144 } |
140 | 145 |
141 prev = NULL; | 146 vec.elts = iovs; |
142 iov = NULL; | 147 vec.size = sizeof(struct iovec); |
143 size = 0; | 148 vec.nalloc = NGX_IOVS; |
144 | 149 vec.pool = pool; |
145 ngx_init_array(io, pool, 10, sizeof(struct iovec), NGX_ERROR); | 150 |
146 | 151 do { |
147 /* create the iovec and coalesce the neighbouring bufs */ | 152 prev = NULL; |
148 | 153 iov = NULL; |
149 while (cl) { | 154 size = 0; |
150 if (prev == cl->buf->pos) { | 155 |
151 iov->iov_len += cl->buf->last - cl->buf->pos; | 156 vec.nelts = 0; |
152 | 157 |
153 } else { | 158 /* create the iovec and coalesce the neighbouring bufs */ |
154 ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR); | 159 |
155 iov->iov_base = (void *) cl->buf->pos; | 160 while (cl && vec.nelts < IOV_MAX) { |
156 iov->iov_len = cl->buf->last - cl->buf->pos; | 161 if (prev == cl->buf->pos) { |
157 } | 162 iov->iov_len += cl->buf->last - cl->buf->pos; |
158 | 163 |
159 size += cl->buf->last - cl->buf->pos; | 164 } else { |
160 prev = cl->buf->last; | 165 if (!(iov = ngx_array_push(&vec))) { |
161 cl = cl->next; | 166 return NGX_ERROR; |
162 } | 167 } |
163 | 168 |
164 /* use pwrite() if there's the only iovec buffer */ | 169 iov->iov_base = (void *) cl->buf->pos; |
165 | 170 iov->iov_len = cl->buf->last - cl->buf->pos; |
166 if (io.nelts == 1) { | 171 } |
167 iov = io.elts; | 172 |
168 return ngx_write_file(file, (u_char *) iov[0].iov_base, iov[0].iov_len, | 173 size += cl->buf->last - cl->buf->pos; |
169 offset); | 174 prev = cl->buf->last; |
170 } | 175 cl = cl->next; |
171 | 176 } |
172 if (file->sys_offset != offset) { | 177 |
173 if (lseek(file->fd, offset, SEEK_SET) == -1) { | 178 /* use pwrite() if there is the only iovec buffer */ |
174 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed"); | 179 |
175 return NGX_ERROR; | 180 if (vec.nelts == 1) { |
176 } | 181 iov = vec.elts; |
177 | 182 return ngx_write_file(file, (u_char *) iov[0].iov_base, |
178 file->sys_offset = offset; | 183 iov[0].iov_len, offset); |
179 } | 184 } |
180 | 185 |
181 n = writev(file->fd, io.elts, io.nelts); | 186 if (file->sys_offset != offset) { |
182 | 187 if (lseek(file->fd, offset, SEEK_SET) == -1) { |
183 if (n == -1) { | 188 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, |
184 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "writev() failed"); | 189 "lseek() failed"); |
185 return NGX_ERROR; | 190 return NGX_ERROR; |
186 } | 191 } |
187 | 192 |
188 if ((size_t) n != size) { | 193 file->sys_offset = offset; |
189 ngx_log_error(NGX_LOG_CRIT, file->log, 0, | 194 } |
190 "writev() has written only %d of %d", n, size); | 195 |
191 return NGX_ERROR; | 196 n = writev(file->fd, vec.elts, vec.nelts); |
192 } | 197 |
193 | 198 if (n == -1) { |
194 file->sys_offset += n; | 199 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, |
195 file->offset += n; | 200 "writev() failed"); |
201 return NGX_ERROR; | |
202 } | |
203 | |
204 if ((size_t) n != size) { | |
205 ngx_log_error(NGX_LOG_CRIT, file->log, 0, | |
206 "writev() has written only %z of %uz", n, size); | |
207 return NGX_ERROR; | |
208 } | |
209 | |
210 file->sys_offset += n; | |
211 file->offset += n; | |
212 | |
213 } while (cl); | |
196 | 214 |
197 return n; | 215 return n; |
198 } | 216 } |
199 | 217 |
200 | 218 |