Fixes #261 ("Memory Mapping Empty Files Fails"):

Detail that empty mappings will lead to error, and add get_size method to file_mapping to be able to detect empty mappings.
This commit is contained in:
Ion Gaztañaga
2025-11-13 23:33:46 +01:00
parent eb74eed5c7
commit cb612879cd
4 changed files with 52 additions and 1 deletions

View File

@@ -6780,6 +6780,7 @@ thank them:
* Minor documentation fixes
* Fixed bugs:
* [@https://github.com/boostorg/interprocess/pull/245 GitHub #245 (['"Fix UBSan runtime error (load of 'boost::interprocess::mode_t')"])].
* [@https://github.com/boostorg/interprocess/issues/261 GitHub #261 (['"Memory Mapping Empty Files Fails"])].
* [@https://github.com/boostorg/interprocess/pull/269 GitHub #269 (['"Minor documentation fixes and template parameter renames"])].
* [@https://github.com/boostorg/interprocess/issues/272 GitHub #272 (['"Regression boost 1.87: offset_ptr conversion from void no longer works"])].
* [@https://github.com/boostorg/interprocess/pull/275 GitHub #275 (['"Allow injection of custom atexit procedure"])].

View File

@@ -109,6 +109,10 @@ class file_mapping
//!used in the constructor.
const char *get_name() const BOOST_NOEXCEPT;
//!Returns true if the size of the file memory object
//!can be obtained and writes the size in the passed reference.
bool get_size(offset_t &size) const BOOST_NOEXCEPT;
//!Removes the file named "filename" even if it's been memory mapped.
//!Returns true on success.
//!The function might fail in some operating systems if the file is
@@ -147,6 +151,9 @@ inline file_mapping::~file_mapping()
inline const char *file_mapping::get_name() const BOOST_NOEXCEPT
{ return m_filename.getn(); }
inline bool file_mapping::get_size(offset_t &size) const BOOST_NOEXCEPT
{ return ipcdetail::get_file_size((file_handle_t)m_handle, size); }
inline void file_mapping::swap(file_mapping &other) BOOST_NOEXCEPT
{
(simple_swap)(m_handle, other.m_handle);

View File

@@ -102,6 +102,13 @@ class mapped_region
//!offset "offset", and the mapping's size will be "size". The mapping
//!can be opened for read only, read-write or copy-on-write.
//!
//!The "mapping" object must be an non-empty mappable type (file, shared memory...)
//!or the function might fail. Check `shared_memory_object/file_mapping::get_size() != 0`
//!before trying to map the empty object and obtain an error.
//!
//!The "size" parameter must be bigger than zero or the function will fail
//!
//!
//!If an address is specified, both the offset and the address must be
//!multiples of the page size.
//!

View File

@@ -30,6 +30,42 @@ int main ()
{
BOOST_INTERPROCESS_TRY{
const std::size_t FileSize = 99999*2;
{
{
std::ofstream file(get_filename().c_str(), std::ios::binary | std::ios::trunc);
}
{
//Create an empty file mapping
file_mapping mapping(get_filename().c_str(), read_write);
//Obtain zero file size
offset_t filesize = 5;
if(!mapping.get_size(filesize) || filesize != 0)
return 1;
//Check mapping of empty file does not work
bool thrown = false;
BOOST_INTERPROCESS_TRY{
mapped_region region (mapping, read_write);
}
BOOST_INTERPROCESS_CATCH(...){
thrown = true;
} BOOST_INTERPROCESS_CATCH_END
if(!thrown)
return file_mapping().swap(mapping), file_mapping::remove(get_filename().c_str()), 1;
thrown = false;
BOOST_INTERPROCESS_TRY{
mapped_region region (mapping, read_only);
}
BOOST_INTERPROCESS_CATCH(...){
thrown = true;
} BOOST_INTERPROCESS_CATCH_END
if(!thrown)
return file_mapping().swap(mapping), file_mapping::remove(get_filename().c_str()), 1;
}
file_mapping::remove(get_filename().c_str());
}
{
//Create file with given size
std::ofstream file(get_filename().c_str(), std::ios::binary | std::ios::trunc);
@@ -166,7 +202,7 @@ int main ()
}
BOOST_INTERPROCESS_CATCH(std::exception &exc){
file_mapping::remove(get_filename().c_str());
std::cout << "Unhandled exception: " << exc.what() << std::endl;
std::cout << "Unexpected Exception: " << exc.what() << std::endl;
BOOST_INTERPROCESS_RETHROW
} BOOST_INTERPROCESS_CATCH_END
file_mapping::remove(get_filename().c_str());