summaryrefslogtreecommitdiff
path: root/buffer.c
diff options
context:
space:
mode:
authorDmitry Antipov <dantipov@cloudlinux.com>2023-01-02 17:06:48 +0300
committerDmitry Antipov <dantipov@cloudlinux.com>2023-01-02 17:12:14 +0300
commit0b79a0024fcc53a322bf63f6e2301173de7dc9de (patch)
tree2020ecb25a6b584fdea23cc0f1496e6944fbecd0 /buffer.c
parent1fe626c4da14fef6cf45b95e48a438e0f93a499e (diff)
downloadlibevent-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.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/buffer.c b/buffer.c
index 825f6a29..da5ed088 100644
--- a/buffer.c
+++ b/buffer.c
@@ -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;
}