0
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
|
4 */
|
|
5
|
|
6
|
|
7 #include <ngx_config.h>
|
|
8 #include <ngx_core.h>
|
|
9
|
|
10
|
110
|
11 ssize_t
|
|
12 ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
|
0
|
13 {
|
110
|
14 ssize_t n;
|
0
|
15
|
|
16 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
|
10
|
17 "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
|
0
|
18
|
18
|
19 #if (NGX_HAVE_PREAD)
|
0
|
20
|
|
21 n = pread(file->fd, buf, size, offset);
|
|
22
|
|
23 if (n == -1) {
|
|
24 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
|
|
25 "pread() failed, file \"%s\"", file->name.data);
|
|
26 return NGX_ERROR;
|
|
27 }
|
|
28
|
|
29 #else
|
|
30
|
|
31 if (file->sys_offset != offset) {
|
|
32 if (lseek(file->fd, offset, SEEK_SET) == -1) {
|
|
33 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
|
|
34 return NGX_ERROR;
|
|
35 }
|
|
36
|
|
37 file->sys_offset = offset;
|
|
38 }
|
|
39
|
|
40 n = read(file->fd, buf, size);
|
|
41
|
|
42 if (n == -1) {
|
|
43 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "read() failed");
|
|
44 return NGX_ERROR;
|
|
45 }
|
|
46
|
|
47 file->sys_offset += n;
|
|
48
|
|
49 #endif
|
|
50
|
|
51 file->offset += n;
|
|
52
|
|
53 return n;
|
|
54 }
|
|
55
|
|
56
|
110
|
57 ssize_t
|
|
58 ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
|
0
|
59 {
|
110
|
60 ssize_t n;
|
0
|
61
|
10
|
62 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
|
|
63 "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
|
|
64
|
18
|
65 #if (NGX_HAVE_PWRITE)
|
0
|
66
|
|
67 n = pwrite(file->fd, buf, size, offset);
|
|
68
|
|
69 if (n == -1) {
|
|
70 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pwrite() failed");
|
|
71 return NGX_ERROR;
|
|
72 }
|
|
73
|
|
74 if ((size_t) n != size) {
|
|
75 ngx_log_error(NGX_LOG_CRIT, file->log, 0,
|
10
|
76 "pwrite() has written only %z of %uz", n, size);
|
0
|
77 return NGX_ERROR;
|
|
78 }
|
|
79
|
|
80 #else
|
|
81
|
|
82 if (file->sys_offset != offset) {
|
|
83 if (lseek(file->fd, offset, SEEK_SET) == -1) {
|
|
84 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
|
|
85 return NGX_ERROR;
|
|
86 }
|
|
87
|
|
88 file->sys_offset = offset;
|
|
89 }
|
|
90
|
|
91 n = write(file->fd, buf, size);
|
|
92
|
|
93 if (n == -1) {
|
|
94 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "write() failed");
|
|
95 return NGX_ERROR;
|
|
96 }
|
|
97
|
|
98 if ((size_t) n != size) {
|
|
99 ngx_log_error(NGX_LOG_CRIT, file->log, 0,
|
10
|
100 "write() has written only %z of %uz", n, size);
|
0
|
101 return NGX_ERROR;
|
|
102 }
|
|
103
|
|
104 file->sys_offset += n;
|
|
105
|
|
106 #endif
|
|
107
|
|
108 file->offset += n;
|
|
109
|
|
110 return n;
|
|
111 }
|
|
112
|
|
113
|
110
|
114 ngx_fd_t
|
276
|
115 ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
|
0
|
116 {
|
|
117 ngx_fd_t fd;
|
|
118
|
276
|
119 fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR,
|
|
120 access ? access : 0600);
|
0
|
121
|
|
122 if (fd != -1 && !persistent) {
|
|
123 unlink((const char *) name);
|
|
124 }
|
|
125
|
|
126 return fd;
|
|
127 }
|
|
128
|
|
129
|
10
|
130 #define NGX_IOVS 8
|
|
131
|
110
|
132 ssize_t
|
|
133 ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
|
|
134 ngx_pool_t *pool)
|
0
|
135 {
|
|
136 u_char *prev;
|
|
137 size_t size;
|
|
138 ssize_t n;
|
10
|
139 ngx_array_t vec;
|
|
140 struct iovec *iov, iovs[NGX_IOVS];
|
0
|
141
|
10
|
142 /* use pwrite() if there is the only buf in a chain */
|
0
|
143
|
|
144 if (cl->next == NULL) {
|
|
145 return ngx_write_file(file, cl->buf->pos,
|
|
146 (size_t) (cl->buf->last - cl->buf->pos),
|
|
147 offset);
|
|
148 }
|
|
149
|
10
|
150 vec.elts = iovs;
|
|
151 vec.size = sizeof(struct iovec);
|
126
|
152 vec.nalloc = NGX_IOVS;
|
10
|
153 vec.pool = pool;
|
0
|
154
|
10
|
155 do {
|
|
156 prev = NULL;
|
|
157 iov = NULL;
|
|
158 size = 0;
|
0
|
159
|
10
|
160 vec.nelts = 0;
|
|
161
|
|
162 /* create the iovec and coalesce the neighbouring bufs */
|
0
|
163
|
10
|
164 while (cl && vec.nelts < IOV_MAX) {
|
|
165 if (prev == cl->buf->pos) {
|
|
166 iov->iov_len += cl->buf->last - cl->buf->pos;
|
0
|
167
|
10
|
168 } else {
|
50
|
169 iov = ngx_array_push(&vec);
|
|
170 if (iov == NULL) {
|
10
|
171 return NGX_ERROR;
|
|
172 }
|
|
173
|
|
174 iov->iov_base = (void *) cl->buf->pos;
|
|
175 iov->iov_len = cl->buf->last - cl->buf->pos;
|
|
176 }
|
|
177
|
|
178 size += cl->buf->last - cl->buf->pos;
|
|
179 prev = cl->buf->last;
|
|
180 cl = cl->next;
|
0
|
181 }
|
|
182
|
10
|
183 /* use pwrite() if there is the only iovec buffer */
|
0
|
184
|
10
|
185 if (vec.nelts == 1) {
|
|
186 iov = vec.elts;
|
|
187 return ngx_write_file(file, (u_char *) iov[0].iov_base,
|
|
188 iov[0].iov_len, offset);
|
|
189 }
|
0
|
190
|
10
|
191 if (file->sys_offset != offset) {
|
|
192 if (lseek(file->fd, offset, SEEK_SET) == -1) {
|
|
193 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
|
|
194 "lseek() failed");
|
|
195 return NGX_ERROR;
|
|
196 }
|
0
|
197
|
10
|
198 file->sys_offset = offset;
|
|
199 }
|
|
200
|
|
201 n = writev(file->fd, vec.elts, vec.nelts);
|
|
202
|
|
203 if (n == -1) {
|
|
204 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
|
|
205 "writev() failed");
|
0
|
206 return NGX_ERROR;
|
|
207 }
|
|
208
|
10
|
209 if ((size_t) n != size) {
|
|
210 ngx_log_error(NGX_LOG_CRIT, file->log, 0,
|
|
211 "writev() has written only %z of %uz", n, size);
|
|
212 return NGX_ERROR;
|
|
213 }
|
0
|
214
|
10
|
215 file->sys_offset += n;
|
|
216 file->offset += n;
|
0
|
217
|
10
|
218 } while (cl);
|
0
|
219
|
|
220 return n;
|
|
221 }
|
|
222
|
|
223
|
110
|
224 ngx_int_t
|
230
|
225 ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
|
|
226 {
|
|
227 struct timeval tv[2];
|
|
228
|
|
229 tv[0].tv_sec = s;
|
|
230 tv[0].tv_usec = 0;
|
|
231 tv[1].tv_sec = s;
|
|
232 tv[1].tv_usec = 0;
|
|
233
|
|
234 if (utimes((char *) name, tv) != -1) {
|
|
235 return NGX_OK;
|
|
236 }
|
|
237
|
|
238 return NGX_ERROR;
|
|
239 }
|
|
240
|
|
241
|
|
242 ngx_int_t
|
110
|
243 ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
|
0
|
244 {
|
|
245 dir->dir = opendir((const char *) name->data);
|
|
246
|
|
247 if (dir->dir == NULL) {
|
|
248 return NGX_ERROR;
|
|
249 }
|
|
250
|
6
|
251 dir->valid_info = 0;
|
0
|
252
|
|
253 return NGX_OK;
|
|
254 }
|
110
|
255
|
|
256
|
238
|
257 ngx_int_t
|
|
258 ngx_open_glob(ngx_glob_t *gl)
|
|
259 {
|
372
|
260 int n;
|
|
261
|
|
262 n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob);
|
|
263
|
|
264 if (n == 0) {
|
|
265 return NGX_OK;
|
|
266 }
|
|
267
|
400
|
268 #ifdef GLOB_NOMATCH
|
|
269
|
372
|
270 if (n == GLOB_NOMATCH && gl->test) {
|
238
|
271 return NGX_OK;
|
|
272 }
|
|
273
|
400
|
274 #endif
|
|
275
|
238
|
276 return NGX_ERROR;
|
|
277 }
|
|
278
|
|
279
|
|
280 ngx_int_t
|
|
281 ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
|
|
282 {
|
400
|
283 if (gl->n < (size_t) gl->pglob.gl_matchc) {
|
238
|
284
|
|
285 name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
|
|
286 name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
|
|
287 gl->n++;
|
|
288
|
|
289 return NGX_OK;
|
|
290 }
|
|
291
|
|
292 return NGX_DONE;
|
|
293 }
|
|
294
|
|
295
|
|
296 void
|
|
297 ngx_close_glob(ngx_glob_t *gl)
|
|
298 {
|
|
299 globfree(&gl->pglob);
|
|
300 }
|
|
301
|
|
302
|
160
|
303 ngx_err_t
|
|
304 ngx_trylock_fd(ngx_fd_t fd)
|
110
|
305 {
|
|
306 struct flock fl;
|
|
307
|
160
|
308 fl.l_start = 0;
|
|
309 fl.l_len = 0;
|
|
310 fl.l_pid = 0;
|
|
311 fl.l_type = F_WRLCK;
|
110
|
312 fl.l_whence = SEEK_SET;
|
160
|
313
|
|
314 if (fcntl(fd, F_SETLK, &fl) == -1) {
|
|
315 return ngx_errno;
|
|
316 }
|
|
317
|
|
318 return 0;
|
|
319 }
|
|
320
|
|
321
|
|
322 ngx_err_t
|
|
323 ngx_lock_fd(ngx_fd_t fd)
|
|
324 {
|
|
325 struct flock fl;
|
|
326
|
|
327 fl.l_start = 0;
|
110
|
328 fl.l_len = 0;
|
|
329 fl.l_pid = 0;
|
|
330 fl.l_type = F_WRLCK;
|
160
|
331 fl.l_whence = SEEK_SET;
|
110
|
332
|
160
|
333 if (fcntl(fd, F_SETLKW, &fl) == -1) {
|
|
334 return ngx_errno;
|
110
|
335 }
|
|
336
|
160
|
337 return 0;
|
110
|
338 }
|
|
339
|
|
340
|
160
|
341 ngx_err_t
|
|
342 ngx_unlock_fd(ngx_fd_t fd)
|
110
|
343 {
|
|
344 struct flock fl;
|
|
345
|
160
|
346 fl.l_start = 0;
|
110
|
347 fl.l_len = 0;
|
|
348 fl.l_pid = 0;
|
|
349 fl.l_type = F_UNLCK;
|
160
|
350 fl.l_whence = SEEK_SET;
|
110
|
351
|
160
|
352 if (fcntl(fd, F_SETLK, &fl) == -1) {
|
|
353 return ngx_errno;
|
110
|
354 }
|
|
355
|
160
|
356 return 0;
|
110
|
357 }
|
390
|
358
|
|
359
|
|
360 #if (NGX_HAVE_O_DIRECT)
|
|
361
|
|
362 ngx_int_t
|
|
363 ngx_directio(ngx_fd_t fd)
|
|
364 {
|
|
365 int flags;
|
|
366
|
|
367 flags = fcntl(fd, F_GETFL);
|
|
368
|
|
369 if (flags == -1) {
|
|
370 return -1;
|
|
371 }
|
|
372
|
|
373 return fcntl(fd, F_SETFL, flags | O_DIRECT);
|
|
374 }
|
|
375
|
|
376 #endif
|