From 0b79a0024fcc53a322bf63f6e2301173de7dc9de Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 2 Jan 2023 17:06:48 +0300 Subject: [PATCH] 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 --- CMakeLists.txt | 1 + buffer.c | 21 +++++++++++++++++++-- configure.ac | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a4b54d46..5cf1ea45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -530,6 +530,7 @@ else() mmap pipe pipe2 + pread sendfile sigaction strsignal 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; } diff --git a/configure.ac b/configure.ac index 7a2c6d06..be538d9e 100644 --- a/configure.ac +++ b/configure.ac @@ -272,7 +272,7 @@ dnl Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE dnl Checks for library functions. -AC_CHECK_FUNCS([accept4 arc4random arc4random_buf arc4random_addrandom eventfd epoll_create1 epoll_pwait2 fcntl getegid geteuid getifaddrs gettimeofday issetugid mach_absolute_time mmap nanosleep pipe pipe2 putenv sendfile setenv setrlimit sigaction signal strsignal strlcpy strsep strtok_r strtoll sysctl timerfd_create umask unsetenv usleep getrandom mmap64]) +AC_CHECK_FUNCS([accept4 arc4random arc4random_buf arc4random_addrandom eventfd epoll_create1 epoll_pwait2 fcntl getegid geteuid getifaddrs gettimeofday issetugid mach_absolute_time mmap nanosleep pipe pipe2 pread putenv sendfile setenv setrlimit sigaction signal strsignal strlcpy strsep strtok_r strtoll sysctl timerfd_create umask unsetenv usleep getrandom mmap64]) AS_IF([test "$bwin32" = "true"], AC_CHECK_FUNCS(_gmtime64_s, , [AC_CHECK_FUNCS(_gmtime64)]) -- 2.50.1