1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9
10
11 ssize_t
12 ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
13 {
14 ssize_t n;
15
16 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
17 "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
18
19 #if (NGX_HAVE_PREAD)
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() \"%s\" failed", 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,
34 "lseek() \"%s\" failed", file->name.data);
35 return NGX_ERROR;
36 }
37
38 file->sys_offset = offset;
39 }
40
41 n = read(file->fd, buf, size);
42
43 if (n == -1) {
44 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
45 "read() \"%s\" failed", file->name.data);
46 return NGX_ERROR;
47 }
48
49 file->sys_offset += n;
50
51 #endif
52
53 file->offset += n;
54
55 return n;
56 }
57
58
59 ssize_t
60 ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
61 {
62 ssize_t n, written;
63
64 ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
65 "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
66
67 written = 0;
68
69 #if (NGX_HAVE_PWRITE)
70
71 for ( ;; ) {
72 n = pwrite(file->fd, buf, size, offset);
73
74 if (n == -1) {
75 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
76 "pwrite() \"%s\" failed", file->name.data);
77 return NGX_ERROR;
78 }
79
80 file->offset += n;
81 written += n;
82
83 if ((size_t) n == size) {
84 return written;
85 }
86
87 offset += n;
88 size -= n;
89 }
90
91 #else
92
93 if (file->sys_offset != offset) {
94 if (lseek(file->fd, offset, SEEK_SET) == -1) {
95 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
96 "lseek() \"%s\" failed", file->name.data);
97 return NGX_ERROR;
98 }
99
100 file->sys_offset = offset;
101 }
102
103 for ( ;; ) {
104 n = write(file->fd, buf, size);
105
106 if (n == -1) {
107 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
108 "write() \"%s\" failed", file->name.data);
109 return NGX_ERROR;
110 }
111
112 file->offset += n;
113 written += n;
114
115 if ((size_t) n == size) {
116 return written;
117 }
118
119 size -= n;
120 }
121 #endif
122 }
123
124
125 ngx_fd_t
126 ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
127 {
128 ngx_fd_t fd;
129
130 fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR,
131 access ? access : 0600);
132
133 if (fd != -1 && !persistent) {
134 unlink((const char *) name);
135 }
136
137 return fd;
138 }
139
140
141 #define NGX_IOVS 8
142
143 ssize_t
144 ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
145 ngx_pool_t *pool)
146 {
147 u_char *prev;
148 size_t size;
149 ssize_t n;
150 ngx_array_t vec;
151 struct iovec *iov, iovs[NGX_IOVS];
152
153 /* use pwrite() if there is the only buf in a chain */
154
155 if (cl->next == NULL) {
156 return ngx_write_file(file, cl->buf->pos,
157 (size_t) (cl->buf->last - cl->buf->pos),
158 offset);
159 }
160
161 vec.elts = iovs;
162 vec.size = sizeof(struct iovec);
163 vec.nalloc = NGX_IOVS;
164 vec.pool = pool;
165
166 do {
167 prev = NULL;
168 iov = NULL;
169 size = 0;
170
171 vec.nelts = 0;
172
173 /* create the iovec and coalesce the neighbouring bufs */
174
175 while (cl && vec.nelts < IOV_MAX) {
176 if (prev == cl->buf->pos) {
177 iov->iov_len += cl->buf->last - cl->buf->pos;
178
179 } else {
180 iov = ngx_array_push(&vec);
181 if (iov == NULL) {
182 return NGX_ERROR;
183 }
184
185 iov->iov_base = (void *) cl->buf->pos;
186 iov->iov_len = cl->buf->last - cl->buf->pos;
187 }
188
189 size += cl->buf->last - cl->buf->pos;
190 prev = cl->buf->last;
191 cl = cl->next;
192 }
193
194 /* use pwrite() if there is the only iovec buffer */
195
196 if (vec.nelts == 1) {
197 iov = vec.elts;
198 return ngx_write_file(file, (u_char *) iov[0].iov_base,
199 iov[0].iov_len, offset);
200 }
201
202 if (file->sys_offset != offset) {
203 if (lseek(file->fd, offset, SEEK_SET) == -1) {
204 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
205 "lseek() \"%s\" failed", file->name.data);
206 return NGX_ERROR;
207 }
208
209 file->sys_offset = offset;
210 }
211
212 n = writev(file->fd, vec.elts, vec.nelts);
213
214 if (n == -1) {
215 ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
216 "writev() \"%s\" failed", file->name.data);
217 return NGX_ERROR;
218 }
219
220 if ((size_t) n != size) {
221 ngx_log_error(NGX_LOG_CRIT, file->log, 0,
222 "writev() \"%s\" has written only %z of %uz",
223 file->name.data, n, size);
224 return NGX_ERROR;
225 }
226
227 file->sys_offset += n;
228 file->offset += n;
229
230 } while (cl);
231
232 return n;
233 }
234
235
236 ngx_int_t
237 ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
238 {
239 struct timeval tv[2];
240
241 tv[0].tv_sec = s;
242 tv[0].tv_usec = 0;
243 tv[1].tv_sec = s;
244 tv[1].tv_usec = 0;
245
246 if (utimes((char *) name, tv) != -1) {
247 return NGX_OK;
248 }
249
250 return NGX_ERROR;
251 }
252
253
254 ngx_int_t
255 ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
256 {
257 dir->dir = opendir((const char *) name->data);
258
259 if (dir->dir == NULL) {
260 return NGX_ERROR;
261 }
262
263 dir->valid_info = 0;
264
265 return NGX_OK;
266 }
267
268
269 ngx_int_t
270 ngx_read_dir(ngx_dir_t *dir)
271 {
272 dir->de = readdir(dir->dir);
273
274 if (dir->de) {
275 #if (NGX_HAVE_D_TYPE)
276 dir->type = dir->de->d_type;
277 #else
278 dir->type = 0;
279 #endif
280 return NGX_OK;
281 }
282
283 return NGX_ERROR;
284 }
285
286
287 ngx_int_t
288 ngx_open_glob(ngx_glob_t *gl)
289 {
290 int n;
291
292 n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob);
293
294 if (n == 0) {
295 return NGX_OK;
296 }
297
298 #ifdef GLOB_NOMATCH
299
300 if (n == GLOB_NOMATCH && gl->test) {
301 return NGX_OK;
302 }
303
304 #endif
305
306 return NGX_ERROR;
307 }
308
309
310 ngx_int_t
311 ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
312 {
313 size_t count;
314
315 #ifdef GLOB_NOMATCH
316 count = (size_t) gl->pglob.gl_pathc;
317 #else
318 count = (size_t) gl->pglob.gl_matchc;
319 #endif
320
321 if (gl->n < count) {
322
323 name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
324 name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
325 gl->n++;
326
327 return NGX_OK;
328 }
329
330 return NGX_DONE;
331 }
332
333
334 void
335 ngx_close_glob(ngx_glob_t *gl)
336 {
337 globfree(&gl->pglob);
338 }
339
340
341 ngx_err_t
342 ngx_trylock_fd(ngx_fd_t fd)
343 {
344 struct flock fl;
345
346 fl.l_start = 0;
347 fl.l_len = 0;
348 fl.l_pid = 0;
349 fl.l_type = F_WRLCK;
350 fl.l_whence = SEEK_SET;
351
352 if (fcntl(fd, F_SETLK, &fl) == -1) {
353 return ngx_errno;
354 }
355
356 return 0;
357 }
358
359
360 ngx_err_t
361 ngx_lock_fd(ngx_fd_t fd)
362 {
363 struct flock fl;
364
365 fl.l_start = 0;
366 fl.l_len = 0;
367 fl.l_pid = 0;
368 fl.l_type = F_WRLCK;
369 fl.l_whence = SEEK_SET;
370
371 if (fcntl(fd, F_SETLKW, &fl) == -1) {
372 return ngx_errno;
373 }
374
375 return 0;
376 }
377
378
379 ngx_err_t
380 ngx_unlock_fd(ngx_fd_t fd)
381 {
382 struct flock fl;
383
384 fl.l_start = 0;
385 fl.l_len = 0;
386 fl.l_pid = 0;
387 fl.l_type = F_UNLCK;
388 fl.l_whence = SEEK_SET;
389
390 if (fcntl(fd, F_SETLK, &fl) == -1) {
391 return ngx_errno;
392 }
393
394 return 0;
395 }
396
397
398 #if (NGX_HAVE_O_DIRECT)
399
400 ngx_int_t
401 ngx_directio_on(ngx_fd_t fd)
402 {
403 int flags;
404
405 flags = fcntl(fd, F_GETFL);
406
407 if (flags == -1) {
408 return NGX_FILE_ERROR;
409 }
410
411 return fcntl(fd, F_SETFL, flags | O_DIRECT);
412 }
413
414
415 ngx_int_t
416 ngx_directio_off(ngx_fd_t fd)
417 {
418 int flags;
419
420 flags = fcntl(fd, F_GETFL);
421
422 if (flags == -1) {
423 return NGX_FILE_ERROR;
424 }
425
426 return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
427 }
428
429 #endif
430
431
432 #if (NGX_HAVE_STATFS)
433
434 size_t
435 ngx_fs_bsize(u_char *name)
436 {
437 struct statfs fs;
438
439 if (statfs((char *) name, &fs) == -1) {
440 return 512;
441 }
442
443 if ((fs.f_bsize % 512) != 0) {
444 return 512;
445 }
446
447 return (size_t) fs.f_bsize;
448 }
449
450 #elif (NGX_HAVE_STATVFS)
451
452 size_t
453 ngx_fs_bsize(u_char *name)
454 {
455 struct statvfs fs;
456
457 if (statvfs((char *) name, &fs) == -1) {
458 return 512;
459 }
460
461 if ((fs.f_frsize % 512) != 0) {
462 return 512;
463 }
464
465 return (size_t) fs.f_frsize;
466 }
467
468 #else
469
470 size_t
471 ngx_fs_bsize(u_char *name)
472 {
473 return 512;
474 }
475
476 #endif
477
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.