diff options
author | Dmitry Antipov <dantipov@cloudlinux.com> | 2023-01-02 17:06:48 +0300 |
---|---|---|
committer | Dmitry Antipov <dantipov@cloudlinux.com> | 2023-01-02 17:12:14 +0300 |
commit | 0b79a0024fcc53a322bf63f6e2301173de7dc9de (patch) | |
tree | 2020ecb25a6b584fdea23cc0f1496e6944fbecd0 /buffer.c | |
parent | 1fe626c4da14fef6cf45b95e48a438e0f93a499e (diff) | |
download | libevent-0b79a0024fcc53a322bf63f6e2301173de7dc9de.tar.gz |
buffer: use pread() for evbuffer_file_segment_materialize()
If pread(2) is available, prefer it over double lseek(2)
and read(2) in evbuffer_file_segment_materialize().
Signed-off-by: Dmitry Antipov <dantipov@cloudlinux.com>
Diffstat (limited to 'buffer.c')
-rw-r--r-- | buffer.c | 21 |
1 files changed, 19 insertions, 2 deletions
@@ -3125,13 +3125,29 @@ evbuffer_file_segment_materialize(struct evbuffer_file_segment *seg) } #endif { - ev_off_t start_pos = lseek(fd, 0, SEEK_CUR), pos; ev_off_t read_so_far = 0; + ev_ssize_t n = 0; char *mem; +#ifndef EVENT__HAVE_PREAD + ev_off_t start_pos = lseek(fd, 0, SEEK_CUR); + ev_off_t pos; int e; - ev_ssize_t n = 0; +#endif /* no pread() */ if (!(mem = mm_malloc(length))) goto err; +#ifdef EVENT__HAVE_PREAD + while (read_so_far < length) { + n = pread(fd, mem + read_so_far, length - read_so_far, + offset + read_so_far); + if (n <= 0) + break; + read_so_far += n; + } + if (n < 0 || (n == 0 && length > read_so_far)) { + mm_free(mem); + goto err; + } +#else /* fallback to seek() and read() */ if (start_pos < 0) { mm_free(mem); goto err; @@ -3157,6 +3173,7 @@ evbuffer_file_segment_materialize(struct evbuffer_file_segment *seg) mm_free(mem); goto err; } +#endif /* pread */ seg->contents = mem; } |