From cde542c37c3e92035102f2cdef2941f1ce12d3c4 Mon Sep 17 00:00:00 2001 From: Ben Larson Date: Sun, 28 Oct 2018 19:35:05 -0600 Subject: [PATCH] libc: read whole file into buffer Fix #3023 --- repos/libports/src/lib/libc/vfs_plugin.cc | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index 4cc50ceb3d..4f35e18631 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -1189,11 +1189,23 @@ void *Libc::Vfs_plugin::mmap(void *addr_in, ::size_t length, int prot, int flags return (void *)-1; } - if (::pread(fd->libc_fd, addr, length, offset) < 0) { - Genode::error("mmap could not obtain file content"); - ::munmap(addr, length); - errno = EACCES; - return (void *)-1; + /* copy variables for complete read */ + size_t read_remain = length; + size_t read_offset = offset; + char *read_addr = (char *)addr; + + while (read_remain > 0) { + ssize_t length_read = ::pread(fd->libc_fd, read_addr, read_remain, read_offset); + if (length_read < 0) { /* error */ + Genode::error("mmap could not obtain file content"); + ::munmap(addr, length); + errno = EACCES; + return (void *)-1; + } else if (length_read == 0) /* EOF */ + break; /* done (length can legally be greater than the file length) */ + read_remain -= length_read; + read_offset += length_read; + read_addr += length_read; } return addr;