lib: Return a valid MemoryMappedFile for zero-length files

mmap() will fail for a zero-length mapping.  A valid object should still
be returned to signal that the file was opened to the caller but it
should have a nullptr for data and zero for size.

Signed-off-by: Rick Altherr <kc8apf@kc8apf.net>
Signed-off-by: Tim 'mithro' Ansell <mithro@mithis.com>
This commit is contained in:
Rick Altherr 2017-11-20 11:47:32 -08:00 committed by Tim 'mithro' Ansell
parent 2bac32800a
commit 36f429127f
3 changed files with 17 additions and 0 deletions

View File

@ -17,6 +17,16 @@ std::unique_ptr<MemoryMappedFile> MemoryMappedFile::InitWithFile(
struct stat statbuf;
if (fstat(fd, &statbuf) < 0) {
close(fd);
return nullptr;
}
// mmap() will fail with EINVAL if length==0. If this file is
// zero-length, return an object (to indicate the file exists) but
// load it with a nullptr and zero length.
if (statbuf.st_size == 0) {
close(fd);
return std::unique_ptr<MemoryMappedFile>(
new MemoryMappedFile(nullptr, 0));
}
void *file_map = mmap(NULL, statbuf.st_size, PROT_READ,

View File

@ -6,6 +6,13 @@ TEST(MemoryMappedFileTest, NonExistantFile) {
EXPECT_FALSE(prjxray::MemoryMappedFile::InitWithFile("does_not_exist"));
}
TEST(MemoryMappedFileTest, ZeroLengthFileReturnObjectWithZeroLength) {
auto file = prjxray::MemoryMappedFile::InitWithFile("empty_file");
ASSERT_TRUE(file);
EXPECT_EQ(nullptr, file->data());
EXPECT_EQ(static_cast<size_t>(0), file->size());
}
TEST(MemoryMappedFileTest, ExistingFile) {
auto file = prjxray::MemoryMappedFile::InitWithFile("small_file");
ASSERT_TRUE(file);

0
lib/test_data/empty_file Normal file
View File