Annotation of embedaddon/nginx/src/os/unix/ngx_files.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * Copyright (C) Igor Sysoev
4: * Copyright (C) Nginx, Inc.
5: */
6:
7:
8: #include <ngx_config.h>
9: #include <ngx_core.h>
10:
11:
12: #if (NGX_HAVE_FILE_AIO)
13:
14: ngx_uint_t ngx_file_aio = 1;
15:
16: #endif
17:
18:
19: ssize_t
20: ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
21: {
22: ssize_t n;
23:
24: ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
25: "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
26:
27: #if (NGX_HAVE_PREAD)
28:
29: n = pread(file->fd, buf, size, offset);
30:
31: if (n == -1) {
32: ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
33: "pread() \"%s\" failed", file->name.data);
34: return NGX_ERROR;
35: }
36:
37: #else
38:
39: if (file->sys_offset != offset) {
40: if (lseek(file->fd, offset, SEEK_SET) == -1) {
41: ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
42: "lseek() \"%s\" failed", file->name.data);
43: return NGX_ERROR;
44: }
45:
46: file->sys_offset = offset;
47: }
48:
49: n = read(file->fd, buf, size);
50:
51: if (n == -1) {
52: ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
53: "read() \"%s\" failed", file->name.data);
54: return NGX_ERROR;
55: }
56:
57: file->sys_offset += n;
58:
59: #endif
60:
61: file->offset += n;
62:
63: return n;
64: }
65:
66:
67: ssize_t
68: ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
69: {
70: ssize_t n, written;
71:
72: ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
73: "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
74:
75: written = 0;
76:
77: #if (NGX_HAVE_PWRITE)
78:
79: for ( ;; ) {
80: n = pwrite(file->fd, buf + written, size, offset);
81:
82: if (n == -1) {
83: ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
84: "pwrite() \"%s\" failed", file->name.data);
85: return NGX_ERROR;
86: }
87:
88: file->offset += n;
89: written += n;
90:
91: if ((size_t) n == size) {
92: return written;
93: }
94:
95: offset += n;
96: size -= n;
97: }
98:
99: #else
100:
101: if (file->sys_offset != offset) {
102: if (lseek(file->fd, offset, SEEK_SET) == -1) {
103: ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
104: "lseek() \"%s\" failed", file->name.data);
105: return NGX_ERROR;
106: }
107:
108: file->sys_offset = offset;
109: }
110:
111: for ( ;; ) {
112: n = write(file->fd, buf + written, size);
113:
114: if (n == -1) {
115: ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
116: "write() \"%s\" failed", file->name.data);
117: return NGX_ERROR;
118: }
119:
120: file->offset += n;
121: written += n;
122:
123: if ((size_t) n == size) {
124: return written;
125: }
126:
127: size -= n;
128: }
129: #endif
130: }
131:
132:
133: ngx_fd_t
134: ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
135: {
136: ngx_fd_t fd;
137:
138: fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR,
139: access ? access : 0600);
140:
141: if (fd != -1 && !persistent) {
142: (void) unlink((const char *) name);
143: }
144:
145: return fd;
146: }
147:
148:
149: #define NGX_IOVS 8
150:
151: ssize_t
152: ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
153: ngx_pool_t *pool)
154: {
155: u_char *prev;
156: size_t size;
157: ssize_t total, n;
158: ngx_array_t vec;
159: struct iovec *iov, iovs[NGX_IOVS];
160:
161: /* use pwrite() if there is the only buf in a chain */
162:
163: if (cl->next == NULL) {
164: return ngx_write_file(file, cl->buf->pos,
165: (size_t) (cl->buf->last - cl->buf->pos),
166: offset);
167: }
168:
169: total = 0;
170:
171: vec.elts = iovs;
172: vec.size = sizeof(struct iovec);
173: vec.nalloc = NGX_IOVS;
174: vec.pool = pool;
175:
176: do {
177: prev = NULL;
178: iov = NULL;
179: size = 0;
180:
181: vec.nelts = 0;
182:
183: /* create the iovec and coalesce the neighbouring bufs */
184:
185: while (cl && vec.nelts < IOV_MAX) {
186: if (prev == cl->buf->pos) {
187: iov->iov_len += cl->buf->last - cl->buf->pos;
188:
189: } else {
190: iov = ngx_array_push(&vec);
191: if (iov == NULL) {
192: return NGX_ERROR;
193: }
194:
195: iov->iov_base = (void *) cl->buf->pos;
196: iov->iov_len = cl->buf->last - cl->buf->pos;
197: }
198:
199: size += cl->buf->last - cl->buf->pos;
200: prev = cl->buf->last;
201: cl = cl->next;
202: }
203:
204: /* use pwrite() if there is the only iovec buffer */
205:
206: if (vec.nelts == 1) {
207: iov = vec.elts;
208:
209: n = ngx_write_file(file, (u_char *) iov[0].iov_base,
210: iov[0].iov_len, offset);
211:
212: if (n == NGX_ERROR) {
213: return n;
214: }
215:
216: return total + n;
217: }
218:
219: if (file->sys_offset != offset) {
220: if (lseek(file->fd, offset, SEEK_SET) == -1) {
221: ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
222: "lseek() \"%s\" failed", file->name.data);
223: return NGX_ERROR;
224: }
225:
226: file->sys_offset = offset;
227: }
228:
229: n = writev(file->fd, vec.elts, vec.nelts);
230:
231: if (n == -1) {
232: ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
233: "writev() \"%s\" failed", file->name.data);
234: return NGX_ERROR;
235: }
236:
237: if ((size_t) n != size) {
238: ngx_log_error(NGX_LOG_CRIT, file->log, 0,
239: "writev() \"%s\" has written only %z of %uz",
240: file->name.data, n, size);
241: return NGX_ERROR;
242: }
243:
244: ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0,
245: "writev: %d, %z", file->fd, n);
246:
247: file->sys_offset += n;
248: file->offset += n;
249: offset += n;
250: total += n;
251:
252: } while (cl);
253:
254: return total;
255: }
256:
257:
258: ngx_int_t
259: ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
260: {
261: struct timeval tv[2];
262:
263: tv[0].tv_sec = ngx_time();
264: tv[0].tv_usec = 0;
265: tv[1].tv_sec = s;
266: tv[1].tv_usec = 0;
267:
268: if (utimes((char *) name, tv) != -1) {
269: return NGX_OK;
270: }
271:
272: return NGX_ERROR;
273: }
274:
275:
276: ngx_int_t
277: ngx_create_file_mapping(ngx_file_mapping_t *fm)
278: {
279: fm->fd = ngx_open_file(fm->name, NGX_FILE_RDWR, NGX_FILE_TRUNCATE,
280: NGX_FILE_DEFAULT_ACCESS);
281: if (fm->fd == NGX_INVALID_FILE) {
282: ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
283: ngx_open_file_n " \"%s\" failed", fm->name);
284: return NGX_ERROR;
285: }
286:
287: if (ftruncate(fm->fd, fm->size) == -1) {
288: ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
289: "ftruncate() \"%s\" failed", fm->name);
290: goto failed;
291: }
292:
293: fm->addr = mmap(NULL, fm->size, PROT_READ|PROT_WRITE, MAP_SHARED,
294: fm->fd, 0);
295: if (fm->addr != MAP_FAILED) {
296: return NGX_OK;
297: }
298:
299: ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
300: "mmap(%uz) \"%s\" failed", fm->size, fm->name);
301:
302: failed:
303:
304: if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
305: ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
306: ngx_close_file_n " \"%s\" failed", fm->name);
307: }
308:
309: return NGX_ERROR;
310: }
311:
312:
313: void
314: ngx_close_file_mapping(ngx_file_mapping_t *fm)
315: {
316: if (munmap(fm->addr, fm->size) == -1) {
317: ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
318: "munmap(%uz) \"%s\" failed", fm->size, fm->name);
319: }
320:
321: if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
322: ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
323: ngx_close_file_n " \"%s\" failed", fm->name);
324: }
325: }
326:
327:
328: ngx_int_t
329: ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
330: {
331: dir->dir = opendir((const char *) name->data);
332:
333: if (dir->dir == NULL) {
334: return NGX_ERROR;
335: }
336:
337: dir->valid_info = 0;
338:
339: return NGX_OK;
340: }
341:
342:
343: ngx_int_t
344: ngx_read_dir(ngx_dir_t *dir)
345: {
346: dir->de = readdir(dir->dir);
347:
348: if (dir->de) {
349: #if (NGX_HAVE_D_TYPE)
350: dir->type = dir->de->d_type;
351: #else
352: dir->type = 0;
353: #endif
354: return NGX_OK;
355: }
356:
357: return NGX_ERROR;
358: }
359:
360:
361: ngx_int_t
362: ngx_open_glob(ngx_glob_t *gl)
363: {
364: int n;
365:
366: n = glob((char *) gl->pattern, 0, NULL, &gl->pglob);
367:
368: if (n == 0) {
369: return NGX_OK;
370: }
371:
372: #ifdef GLOB_NOMATCH
373:
374: if (n == GLOB_NOMATCH && gl->test) {
375: return NGX_OK;
376: }
377:
378: #endif
379:
380: return NGX_ERROR;
381: }
382:
383:
384: ngx_int_t
385: ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
386: {
387: size_t count;
388:
389: #ifdef GLOB_NOMATCH
390: count = (size_t) gl->pglob.gl_pathc;
391: #else
392: count = (size_t) gl->pglob.gl_matchc;
393: #endif
394:
395: if (gl->n < count) {
396:
397: name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
398: name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
399: gl->n++;
400:
401: return NGX_OK;
402: }
403:
404: return NGX_DONE;
405: }
406:
407:
408: void
409: ngx_close_glob(ngx_glob_t *gl)
410: {
411: globfree(&gl->pglob);
412: }
413:
414:
415: ngx_err_t
416: ngx_trylock_fd(ngx_fd_t fd)
417: {
418: struct flock fl;
419:
420: ngx_memzero(&fl, sizeof(struct flock));
421: fl.l_type = F_WRLCK;
422: fl.l_whence = SEEK_SET;
423:
424: if (fcntl(fd, F_SETLK, &fl) == -1) {
425: return ngx_errno;
426: }
427:
428: return 0;
429: }
430:
431:
432: ngx_err_t
433: ngx_lock_fd(ngx_fd_t fd)
434: {
435: struct flock fl;
436:
437: ngx_memzero(&fl, sizeof(struct flock));
438: fl.l_type = F_WRLCK;
439: fl.l_whence = SEEK_SET;
440:
441: if (fcntl(fd, F_SETLKW, &fl) == -1) {
442: return ngx_errno;
443: }
444:
445: return 0;
446: }
447:
448:
449: ngx_err_t
450: ngx_unlock_fd(ngx_fd_t fd)
451: {
452: struct flock fl;
453:
454: ngx_memzero(&fl, sizeof(struct flock));
455: fl.l_type = F_UNLCK;
456: fl.l_whence = SEEK_SET;
457:
458: if (fcntl(fd, F_SETLK, &fl) == -1) {
459: return ngx_errno;
460: }
461:
462: return 0;
463: }
464:
465:
466: #if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD)
467:
468: ngx_int_t
469: ngx_read_ahead(ngx_fd_t fd, size_t n)
470: {
471: int err;
472:
473: err = posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
474:
475: if (err == 0) {
476: return 0;
477: }
478:
479: ngx_set_errno(err);
480: return NGX_FILE_ERROR;
481: }
482:
483: #endif
484:
485:
486: #if (NGX_HAVE_O_DIRECT)
487:
488: ngx_int_t
489: ngx_directio_on(ngx_fd_t fd)
490: {
491: int flags;
492:
493: flags = fcntl(fd, F_GETFL);
494:
495: if (flags == -1) {
496: return NGX_FILE_ERROR;
497: }
498:
499: return fcntl(fd, F_SETFL, flags | O_DIRECT);
500: }
501:
502:
503: ngx_int_t
504: ngx_directio_off(ngx_fd_t fd)
505: {
506: int flags;
507:
508: flags = fcntl(fd, F_GETFL);
509:
510: if (flags == -1) {
511: return NGX_FILE_ERROR;
512: }
513:
514: return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
515: }
516:
517: #endif
518:
519:
520: #if (NGX_HAVE_STATFS)
521:
522: size_t
523: ngx_fs_bsize(u_char *name)
524: {
525: struct statfs fs;
526:
527: if (statfs((char *) name, &fs) == -1) {
528: return 512;
529: }
530:
531: if ((fs.f_bsize % 512) != 0) {
532: return 512;
533: }
534:
535: return (size_t) fs.f_bsize;
536: }
537:
538: #elif (NGX_HAVE_STATVFS)
539:
540: size_t
541: ngx_fs_bsize(u_char *name)
542: {
543: struct statvfs fs;
544:
545: if (statvfs((char *) name, &fs) == -1) {
546: return 512;
547: }
548:
549: if ((fs.f_frsize % 512) != 0) {
550: return 512;
551: }
552:
553: return (size_t) fs.f_frsize;
554: }
555:
556: #else
557:
558: size_t
559: ngx_fs_bsize(u_char *name)
560: {
561: return 512;
562: }
563:
564: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>