summaryrefslogtreecommitdiffstats
path: root/usr.sbin/nginx/src/os/unix/ngx_files.c
diff options
context:
space:
mode:
authorrobert <robert@openbsd.org>2011-09-22 23:32:10 +0000
committerrobert <robert@openbsd.org>2011-09-22 23:32:10 +0000
commit40ffe171a7951d3019b3c8b488be87bfad405509 (patch)
tree7634bff211814a539a15e4e34db747e4d7b46006 /usr.sbin/nginx/src/os/unix/ngx_files.c
parentAlways install all manuals on all architectures. (diff)
downloadwireguard-openbsd-40ffe171a7951d3019b3c8b488be87bfad405509.tar.xz
wireguard-openbsd-40ffe171a7951d3019b3c8b488be87bfad405509.zip
import of nginx 1.0.6 with a bundled libpcre needed for pcre to work
properly. this is not yet linked to the build but we would like to work on it in tree to provide an apache replacement for base
Diffstat (limited to 'usr.sbin/nginx/src/os/unix/ngx_files.c')
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_files.c555
1 files changed, 555 insertions, 0 deletions
diff --git a/usr.sbin/nginx/src/os/unix/ngx_files.c b/usr.sbin/nginx/src/os/unix/ngx_files.c
new file mode 100644
index 00000000000..89ab8d6bc05
--- /dev/null
+++ b/usr.sbin/nginx/src/os/unix/ngx_files.c
@@ -0,0 +1,555 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#if (NGX_HAVE_FILE_AIO)
+
+ngx_uint_t ngx_file_aio = 1;
+
+#endif
+
+
+ssize_t
+ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
+{
+ ssize_t n;
+
+ ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
+ "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
+
+#if (NGX_HAVE_PREAD)
+
+ n = pread(file->fd, buf, size, offset);
+
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "pread() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+#else
+
+ if (file->sys_offset != offset) {
+ if (lseek(file->fd, offset, SEEK_SET) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "lseek() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ file->sys_offset = offset;
+ }
+
+ n = read(file->fd, buf, size);
+
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "read() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ file->sys_offset += n;
+
+#endif
+
+ file->offset += n;
+
+ return n;
+}
+
+
+ssize_t
+ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
+{
+ ssize_t n, written;
+
+ ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
+ "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
+
+ written = 0;
+
+#if (NGX_HAVE_PWRITE)
+
+ for ( ;; ) {
+ n = pwrite(file->fd, buf + written, size, offset);
+
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "pwrite() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ file->offset += n;
+ written += n;
+
+ if ((size_t) n == size) {
+ return written;
+ }
+
+ offset += n;
+ size -= n;
+ }
+
+#else
+
+ if (file->sys_offset != offset) {
+ if (lseek(file->fd, offset, SEEK_SET) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "lseek() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ file->sys_offset = offset;
+ }
+
+ for ( ;; ) {
+ n = write(file->fd, buf + written, size);
+
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "write() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ file->offset += n;
+ written += n;
+
+ if ((size_t) n == size) {
+ return written;
+ }
+
+ size -= n;
+ }
+#endif
+}
+
+
+ngx_fd_t
+ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
+{
+ ngx_fd_t fd;
+
+ fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR,
+ access ? access : 0600);
+
+ if (fd != -1 && !persistent) {
+ unlink((const char *) name);
+ }
+
+ return fd;
+}
+
+
+#define NGX_IOVS 8
+
+ssize_t
+ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
+ ngx_pool_t *pool)
+{
+ u_char *prev;
+ size_t size;
+ ssize_t n;
+ ngx_array_t vec;
+ struct iovec *iov, iovs[NGX_IOVS];
+
+ /* use pwrite() if there is the only buf in a chain */
+
+ if (cl->next == NULL) {
+ return ngx_write_file(file, cl->buf->pos,
+ (size_t) (cl->buf->last - cl->buf->pos),
+ offset);
+ }
+
+ vec.elts = iovs;
+ vec.size = sizeof(struct iovec);
+ vec.nalloc = NGX_IOVS;
+ vec.pool = pool;
+
+ do {
+ prev = NULL;
+ iov = NULL;
+ size = 0;
+
+ vec.nelts = 0;
+
+ /* create the iovec and coalesce the neighbouring bufs */
+
+ while (cl && vec.nelts < IOV_MAX) {
+ if (prev == cl->buf->pos) {
+ iov->iov_len += cl->buf->last - cl->buf->pos;
+
+ } else {
+ iov = ngx_array_push(&vec);
+ if (iov == NULL) {
+ return NGX_ERROR;
+ }
+
+ iov->iov_base = (void *) cl->buf->pos;
+ iov->iov_len = cl->buf->last - cl->buf->pos;
+ }
+
+ size += cl->buf->last - cl->buf->pos;
+ prev = cl->buf->last;
+ cl = cl->next;
+ }
+
+ /* use pwrite() if there is the only iovec buffer */
+
+ if (vec.nelts == 1) {
+ iov = vec.elts;
+ return ngx_write_file(file, (u_char *) iov[0].iov_base,
+ iov[0].iov_len, offset);
+ }
+
+ if (file->sys_offset != offset) {
+ if (lseek(file->fd, offset, SEEK_SET) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "lseek() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ file->sys_offset = offset;
+ }
+
+ n = writev(file->fd, vec.elts, vec.nelts);
+
+ if (n == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
+ "writev() \"%s\" failed", file->name.data);
+ return NGX_ERROR;
+ }
+
+ if ((size_t) n != size) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, 0,
+ "writev() \"%s\" has written only %z of %uz",
+ file->name.data, n, size);
+ return NGX_ERROR;
+ }
+
+ file->sys_offset += n;
+ file->offset += n;
+
+ } while (cl);
+
+ return n;
+}
+
+
+ngx_int_t
+ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
+{
+ struct timeval tv[2];
+
+ tv[0].tv_sec = ngx_time();
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = s;
+ tv[1].tv_usec = 0;
+
+ if (utimes((char *) name, tv) != -1) {
+ return NGX_OK;
+ }
+
+ return NGX_ERROR;
+}
+
+
+ngx_int_t
+ngx_create_file_mapping(ngx_file_mapping_t *fm)
+{
+ fm->fd = ngx_open_file(fm->name, NGX_FILE_RDWR, NGX_FILE_TRUNCATE,
+ NGX_FILE_DEFAULT_ACCESS);
+ if (fm->fd == NGX_INVALID_FILE) {
+ ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed", fm->name);
+ return NGX_ERROR;
+ }
+
+ if (ftruncate(fm->fd, fm->size) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+ "ftruncate() \"%s\" failed", fm->name);
+ goto failed;
+ }
+
+ fm->addr = mmap(NULL, fm->size, PROT_READ|PROT_WRITE, MAP_SHARED,
+ fm->fd, 0);
+ if (fm->addr != MAP_FAILED) {
+ return NGX_OK;
+ }
+
+ ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+ "mmap(%uz) \"%s\" failed", fm->size, fm->name);
+
+failed:
+
+ if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", fm->name);
+ }
+
+ return NGX_ERROR;
+}
+
+
+void
+ngx_close_file_mapping(ngx_file_mapping_t *fm)
+{
+ if (munmap(fm->addr, fm->size) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
+ "munmap(%uz) \"%s\" failed", fm->size, fm->name);
+ }
+
+ if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", fm->name);
+ }
+}
+
+
+ngx_int_t
+ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
+{
+ dir->dir = opendir((const char *) name->data);
+
+ if (dir->dir == NULL) {
+ return NGX_ERROR;
+ }
+
+ dir->valid_info = 0;
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_read_dir(ngx_dir_t *dir)
+{
+ dir->de = readdir(dir->dir);
+
+ if (dir->de) {
+#if (NGX_HAVE_D_TYPE)
+ dir->type = dir->de->d_type;
+#else
+ dir->type = 0;
+#endif
+ return NGX_OK;
+ }
+
+ return NGX_ERROR;
+}
+
+
+ngx_int_t
+ngx_open_glob(ngx_glob_t *gl)
+{
+ int n;
+
+ n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob);
+
+ if (n == 0) {
+ return NGX_OK;
+ }
+
+#ifdef GLOB_NOMATCH
+
+ if (n == GLOB_NOMATCH && gl->test) {
+ return NGX_OK;
+ }
+
+#endif
+
+ return NGX_ERROR;
+}
+
+
+ngx_int_t
+ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
+{
+ size_t count;
+
+#ifdef GLOB_NOMATCH
+ count = (size_t) gl->pglob.gl_pathc;
+#else
+ count = (size_t) gl->pglob.gl_matchc;
+#endif
+
+ if (gl->n < count) {
+
+ name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
+ name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
+ gl->n++;
+
+ return NGX_OK;
+ }
+
+ return NGX_DONE;
+}
+
+
+void
+ngx_close_glob(ngx_glob_t *gl)
+{
+ globfree(&gl->pglob);
+}
+
+
+ngx_err_t
+ngx_trylock_fd(ngx_fd_t fd)
+{
+ struct flock fl;
+
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_pid = 0;
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+
+ if (fcntl(fd, F_SETLK, &fl) == -1) {
+ return ngx_errno;
+ }
+
+ return 0;
+}
+
+
+ngx_err_t
+ngx_lock_fd(ngx_fd_t fd)
+{
+ struct flock fl;
+
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_pid = 0;
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+
+ if (fcntl(fd, F_SETLKW, &fl) == -1) {
+ return ngx_errno;
+ }
+
+ return 0;
+}
+
+
+ngx_err_t
+ngx_unlock_fd(ngx_fd_t fd)
+{
+ struct flock fl;
+
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_pid = 0;
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+
+ if (fcntl(fd, F_SETLK, &fl) == -1) {
+ return ngx_errno;
+ }
+
+ return 0;
+}
+
+
+#if (NGX_HAVE_POSIX_FADVISE)
+
+ngx_int_t
+ngx_read_ahead(ngx_fd_t fd, size_t n)
+{
+ int err;
+
+ err = posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
+
+ if (err == 0) {
+ return 0;
+ }
+
+ ngx_set_errno(err);
+ return NGX_FILE_ERROR;
+}
+
+#endif
+
+
+#if (NGX_HAVE_O_DIRECT)
+
+ngx_int_t
+ngx_directio_on(ngx_fd_t fd)
+{
+ int flags;
+
+ flags = fcntl(fd, F_GETFL);
+
+ if (flags == -1) {
+ return NGX_FILE_ERROR;
+ }
+
+ return fcntl(fd, F_SETFL, flags | O_DIRECT);
+}
+
+
+ngx_int_t
+ngx_directio_off(ngx_fd_t fd)
+{
+ int flags;
+
+ flags = fcntl(fd, F_GETFL);
+
+ if (flags == -1) {
+ return NGX_FILE_ERROR;
+ }
+
+ return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
+}
+
+#endif
+
+
+#if (NGX_HAVE_STATFS)
+
+size_t
+ngx_fs_bsize(u_char *name)
+{
+ struct statfs fs;
+
+ if (statfs((char *) name, &fs) == -1) {
+ return 512;
+ }
+
+ if ((fs.f_bsize % 512) != 0) {
+ return 512;
+ }
+
+ return (size_t) fs.f_bsize;
+}
+
+#elif (NGX_HAVE_STATVFS)
+
+size_t
+ngx_fs_bsize(u_char *name)
+{
+ struct statvfs fs;
+
+ if (statvfs((char *) name, &fs) == -1) {
+ return 512;
+ }
+
+ if ((fs.f_frsize % 512) != 0) {
+ return 512;
+ }
+
+ return (size_t) fs.f_frsize;
+}
+
+#else
+
+size_t
+ngx_fs_bsize(u_char *name)
+{
+ return 512;
+}
+
+#endif