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>