[core] chunk_file_pread() to wrap pread()

master
Glenn Strauss 10 months ago
parent a2aaf45b7a
commit 2d1b16721c
  1. 54
      src/chunk.c
  2. 2
      src/chunk.h
  3. 15
      src/http_chunk.c
  4. 20
      src/mod_deflate.c
  5. 10
      src/network_write.c

@ -168,6 +168,30 @@ static chunk_file_view * chunk_file_view_failed (chunk_file_view *cfv) {
#endif /* HAVE_MMAP */
ssize_t
chunk_file_pread (int fd, void *buf, size_t count, off_t offset)
{
/*(expects open file for FILE_CHUNK)*/
#ifndef HAVE_PREAD
/*(On systems without pread() or equivalent, lseek() is repeated if this
* func is called in a loop, but this func is generally used on small files,
* or reading a small bit at a time. Even in the case of mod_deflate, files
* are not expected to be excessively large.) */
if (-1 == lseek(fd, offset, SEEK_SET))
return -1;
#endif
ssize_t rd;
do {
#ifdef HAVE_PREAD
rd =pread(fd, buf, count, offset);
#else
rd = read(fd, buf, count);
#endif
} while (-1 == rd && errno == EINTR);
return rd;
}
static void chunk_reset_file_chunk(chunk *c) {
if (c->file.is_temp) {
c->file.is_temp = 0;
@ -1499,10 +1523,6 @@ chunkqueue_small_resp_optim (chunkqueue * const restrict cq)
if (filec != cq->last || filec->type != FILE_CHUNK || filec->file.fd < 0)
return;
#ifndef HAVE_PREAD
if (-1 == lseek(filec->file.fd, filec->offset, SEEK_SET)) return;
#endif
/* Note: there should be no size change in chunkqueue,
* so cq->bytes_in and cq->bytes_out should not be modified */
@ -1520,12 +1540,9 @@ chunkqueue_small_resp_optim (chunkqueue * const restrict cq)
off_t offset = 0;
char * const ptr = buffer_extend(c->mem, len);
do {
#ifdef HAVE_PREAD
rd =pread(filec->file.fd, ptr+offset, (size_t)len,filec->offset+offset);
#else
rd = read(filec->file.fd, ptr+offset, (size_t)len);
#endif
} while (rd > 0 ? (offset += rd, len -= rd) : errno == EINTR);
rd = chunk_file_pread(filec->file.fd, ptr+offset, (size_t)len,
filec->offset+offset);
} while (rd > 0 && (offset += rd, len -= rd));
/*(contents of chunkqueue kept valid even if error reading from file)*/
if (__builtin_expect( (0 == len), 1))
chunk_release(filec);
@ -1630,21 +1647,8 @@ chunkqueue_peek_data (chunkqueue * const cq,
#endif
#endif
#ifndef HAVE_PREAD
if (-1 == lseek(c->file.fd, c->offset, SEEK_SET)) {
log_perror(errh, __FILE__, __LINE__, "lseek(\"%s\")",
c->mem->ptr);
return -1;
}
#endif
ssize_t rd;
do {
#ifdef HAVE_PREAD
rd =pread(c->file.fd,data_in+*dlen,(size_t)len,c->offset);
#else
rd = read(c->file.fd,data_in+*dlen,(size_t)len);
#endif
} while (-1 == rd && errno == EINTR);
ssize_t rd = chunk_file_pread(c->file.fd, data_in+*dlen,
(size_t)len, c->offset);
if (rd <= 0) { /* -1 error; 0 EOF (unexpected) */
log_perror(errh, __FILE__, __LINE__, "read(\"%s\")",
c->mem->ptr);

@ -54,6 +54,8 @@ typedef struct chunkqueue {
unsigned int tempdir_idx;
} chunkqueue;
ssize_t chunk_file_pread (int fd, void *buf, size_t count, off_t offset);
__attribute_returns_nonnull__
buffer * chunk_buffer_acquire(void);

@ -71,29 +71,20 @@ static int http_chunk_append_read_fd_range(request_st * const r, const buffer *
if (r->resp_send_chunked)
http_chunk_len_append(cq, (uintmax_t)len);
#ifndef HAVE_PREAD
if (-1 == lseek(fd, offset, SEEK_SET)) return -1;
#endif
buffer * const b = chunkqueue_append_buffer_open_sz(cq, len+2+1);
ssize_t rd;
#ifdef HAVE_PREAD
const off_t foff = offset;
#endif
offset = 0;
do {
#ifdef HAVE_PREAD
rd =pread(fd, b->ptr+offset, (size_t)(len-offset), foff+offset);
#else
rd = read(fd, b->ptr+offset, (size_t)(len-offset));
#endif
} while (rd > 0 ? (offset += rd) != len : errno == EINTR);
rd = chunk_file_pread(fd, b->ptr+offset, (size_t)len, foff+offset);
} while (rd > 0 && (offset += rd, len -= rd));
buffer_commit(b, offset);
if (r->resp_send_chunked)
buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
chunkqueue_append_buffer_commit(cq);
return (rd >= 0) ? 0 : -1;
return (len == 0) ? 0 : -1;
}
__attribute_noinline__

@ -1611,33 +1611,17 @@ static off_t mod_deflate_file_chunk_no_mmap(request_st * const r, handler_ctx *
return -1;
}
#ifndef HAVE_PREAD
if (-1 == lseek(c->file.fd, c->offset, SEEK_SET)) {
log_perror(r->conf.errh, __FILE__, __LINE__, "lseek %s", c->mem->ptr);
return -1;
}
#endif
ssize_t rd = 0;
for (n = 0; n < insz; n += rd) {
#ifndef HAVE_PREAD
rd = read(c->file.fd, p, (size_t)psz);
#else
rd =pread(c->file.fd, p, (size_t)psz, c->offset+n);
#endif
rd = chunk_file_pread(c->file.fd, p, (size_t)psz, c->offset+n);
if (__builtin_expect( (rd > 0), 1)) {
if (0 == mod_deflate_compress(hctx, (unsigned char *)p, rd))
continue;
/*(else error trace printed upon return)*/
}
else if (-1 == rd) {
if (errno == EINTR) {
rd = 0;
continue;
}
else if (-1 == rd)
log_perror(r->conf.errh, __FILE__, __LINE__,
"reading %s failed", c->mem->ptr);
}
else /*(0 == rd)*/
log_error(r->conf.errh, __FILE__, __LINE__,
"file truncated %s", c->mem->ptr);

@ -161,15 +161,7 @@ static int network_write_file_chunk_no_mmap(const int fd, chunkqueue * const cq,
if (c->file.fd < 0 && 0 != chunkqueue_open_file_chunk(cq, errh)) return -1;
#ifndef HAVE_PREAD
if (-1 == lseek(c->file.fd, c->offset, SEEK_SET)) {
log_perror(errh, __FILE__, __LINE__, "lseek");
return -1;
}
toSend = read(c->file.fd, buf, toSend);
#else
toSend =pread(c->file.fd, buf, toSend, c->offset);
#endif
toSend = chunk_file_pread(c->file.fd, buf, toSend, c->offset);
if (toSend <= 0) {
log_perror(errh, __FILE__, __LINE__, "read");/* err or unexpected EOF */
return -1;

Loading…
Cancel
Save