nginx-quic/src/os/unix/ngx_files.c

226 lines
5.4 KiB
C
Raw Normal View History

2002-08-23 12:14:30 -04:00
2002-12-19 14:49:51 -03:00
#include <ngx_config.h>
2002-09-02 10:48:24 -04:00
#include <ngx_core.h>
2003-04-11 12:01:14 -04:00
#include <ngx_hunk.h>
#include <ngx_array.h>
2002-09-02 10:48:24 -04:00
#include <ngx_file.h>
2003-04-11 12:01:14 -04:00
#include <ngx_files.h>
2002-08-23 12:14:30 -04:00
2002-09-02 10:48:24 -04:00
ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
2002-08-23 12:14:30 -04:00
{
2002-09-02 10:48:24 -04:00
ssize_t n;
2003-04-14 13:04:58 -04:00
ngx_log_debug(file->log, "read: %d, %x, %d, %qd" _
file->fd _ buf _ size _ offset);
2002-09-02 10:48:24 -04:00
2003-11-13 03:14:05 -03:00
#if (HAVE_PREAD)
2002-09-02 10:48:24 -04:00
n = pread(file->fd, buf, size, offset);
2002-09-07 06:14:25 -04:00
if (n == -1) {
2003-04-11 12:01:14 -04:00
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pread() failed");
2002-09-07 06:14:25 -04:00
return NGX_ERROR;
}
2002-09-02 10:48:24 -04:00
2003-11-13 03:14:05 -03:00
#else
if (file->offset != offset) {
if (lseek(file->fd, offset, SEEK_SET) == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
return NGX_ERROR;
}
}
n = read(file->fd, buf, size);
if (n == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "read() failed");
return NGX_ERROR;
}
#endif
2002-12-21 14:14:50 -03:00
file->offset += n;
2002-09-02 10:48:24 -04:00
return n;
2002-08-23 12:14:30 -04:00
}
2003-04-10 11:08:54 -04:00
ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
{
ssize_t n;
2003-11-13 03:14:05 -03:00
#if (HAVE_PWRITE)
2003-04-10 11:08:54 -04:00
n = pwrite(file->fd, buf, size, offset);
if (n == -1) {
2003-04-11 12:01:14 -04:00
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pwrite() failed");
2003-04-10 11:08:54 -04:00
return NGX_ERROR;
}
2003-04-11 12:01:14 -04:00
if ((size_t) n != size) {
ngx_log_error(NGX_LOG_CRIT, file->log, 0,
2003-04-10 11:08:54 -04:00
"pwrite() has written only %d of %d", n, size);
return NGX_ERROR;
}
2003-11-13 03:14:05 -03:00
#else
if (file->offset != offset) {
if (lseek(file->fd, offset, SEEK_SET) == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
return NGX_ERROR;
}
}
n = write(file->fd, buf, size);
if (n == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "write() failed");
return NGX_ERROR;
}
if ((size_t) n != size) {
ngx_log_error(NGX_LOG_CRIT, file->log, 0,
"write() has written only %d of %d", n, size);
return NGX_ERROR;
}
#endif
2003-04-10 11:08:54 -04:00
file->offset += n;
return n;
}
2003-11-02 19:56:18 -03:00
ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl,
2003-04-11 12:01:14 -04:00
off_t offset, ngx_pool_t *pool)
{
2003-11-02 19:56:18 -03:00
char *prev;
2003-04-11 12:01:14 -04:00
size_t size;
ssize_t n;
struct iovec *iov;
ngx_err_t err;
ngx_array_t io;
/* use pwrite() if there's the only hunk in a chain */
2003-11-02 19:56:18 -03:00
if (cl->next == NULL) {
return ngx_write_file(file, cl->hunk->pos,
cl->hunk->last - cl->hunk->pos, offset);
2003-04-11 12:01:14 -04:00
}
2003-11-02 19:56:18 -03:00
prev = NULL;
iov = NULL;
2003-04-11 12:01:14 -04:00
size = 0;
2003-11-02 19:56:18 -03:00
ngx_init_array(io, pool, 10, sizeof(struct iovec), NGX_ERROR);
/* create the iovec and coalesce the neighbouring hunks */
while (cl) {
if (prev == cl->hunk->pos) {
iov->iov_len += cl->hunk->last - cl->hunk->pos;
} else {
ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR);
iov->iov_base = cl->hunk->pos;
iov->iov_len = cl->hunk->last - cl->hunk->pos;
}
size += cl->hunk->last - cl->hunk->pos;
prev = cl->hunk->last;
cl = cl->next;
}
/* use pwrite() if there's the only iovec buffer */
if (io.nelts == 1) {
iov = io.elts;
return ngx_write_file(file, iov[0].iov_base, iov[0].iov_len, offset);
2003-04-11 12:01:14 -04:00
}
2003-10-22 04:05:29 -03:00
if (file->offset != offset) {
if (lseek(file->fd, offset, SEEK_SET) == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
return NGX_ERROR;
}
2003-04-11 12:01:14 -04:00
}
2003-11-02 19:56:18 -03:00
n = writev(file->fd, io.elts, io.nelts);
2003-04-11 12:01:14 -04:00
if (n == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "writev() failed");
return NGX_ERROR;
}
if ((size_t) n != size) {
ngx_log_error(NGX_LOG_CRIT, file->log, 0,
"writev() has written only %d of %d", n, size);
return NGX_ERROR;
}
file->offset += n;
return n;
}
2002-08-23 12:14:30 -04:00
#if 0
ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
{
if (!file->read->ready) {
ngx_memzero(&file->iocb, sizeof(iocb));
file->iocb.aio_fildes = file->fd;
file->iocb.aio_buf = buf;
file->iocb.aio_nbytes = size;
file->iocb.aio_offset = offset;
#if (USE_AIO_KQUEUE)
file->iocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
file->iocb.aio_sigevent.sigev_notify_kqueue = tid->kq;
file->iocb.aio_sigevent.sigev_value = (union sigval) file;
#endif
#if (USE_AIO_SIGNAL)
file->iocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
file->iocb.aio_sigevent.sigev_signo = NGX_SIGAIO;
#ifndef __FreeBSD__
file->iocb.aio_sigevent.sigev_value.sival_ptr = file;
#endif
#endif
if (aio_read(&file->iocb) == -1) {
ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno,
"aio_read() failed");
return NGX_ERROR;
n = aio_error(&file->iocb);
if (n == EINPROGRESS)
return NGX_AGAIN;
if (n == -1) {
ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno,
"aio_read() failed");
return NGX_ERROR;
}
}
ngx_assert(file->iocb.aio_buf == buf), return NGX_ERROR,
"ngx_aio_read_file: another buffer is passed");
n = aio_return(&file->iocb);
if (n == -1) {
ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno,
"aio_read() failed");
return NGX_ERROR;
}
return n;
}
#endif