Annotation of embedaddon/nginx/src/os/unix/ngx_files.c, revision 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>