]> granicus.if.org Git - libevent/commitdiff
buffer: use pread() for evbuffer_file_segment_materialize()
authorDmitry Antipov <dantipov@cloudlinux.com>
Mon, 2 Jan 2023 14:06:48 +0000 (17:06 +0300)
committerDmitry Antipov <dantipov@cloudlinux.com>
Mon, 2 Jan 2023 14:12:14 +0000 (17:12 +0300)
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>
CMakeLists.txt
buffer.c
configure.ac

index a4b54d4625f3e97e97c773bbff2341a4c8d67176..5cf1ea454809f7532fc6cf16497090608ddb6c4b 100644 (file)
@@ -530,6 +530,7 @@ else()
         mmap
         pipe
         pipe2
+        pread
         sendfile
         sigaction
         strsignal
index 825f6a29e8af8ed4d6fe597197e7a8b7f1e92563..da5ed08822b481d7f59b4c0cb9aa5d70c1fd84de 100644 (file)
--- 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;
        }
index 7a2c6d06dada61fe6b42a21f7b5fbef2a5ffd3d0..be538d9ee228c6959efe5aa9dc4677b344c59a70 100644 (file)
@@ -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)])