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