mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 05:17:35 +00:00
LibGfx: Make sure Bitmap::create_with_anon_fd() always closes if needed
If this is called with ShouldCloseAnonymousFile::Yes, it's entrusted with closing the anon_fd and nobody else will take care of it.
This commit is contained in:
parent
1a157d3f50
commit
f18d89b36d
1 changed files with 20 additions and 13 deletions
|
@ -28,6 +28,7 @@
|
|||
#include <AK/Memory.h>
|
||||
#include <AK/MemoryStream.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/SharedBuffer.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibGfx/BMPLoader.h>
|
||||
|
@ -188,22 +189,28 @@ static bool check_size(const IntSize& size, BitmapFormat format, unsigned actual
|
|||
|
||||
RefPtr<Bitmap> Bitmap::create_with_anon_fd(BitmapFormat format, int anon_fd, const IntSize& size, ShouldCloseAnonymousFile should_close_anon_fd)
|
||||
{
|
||||
if (size_would_overflow(format, size))
|
||||
return nullptr;
|
||||
void* data = nullptr;
|
||||
{
|
||||
// If ShouldCloseAnonymousFile::Yes, it's our responsibility to close 'anon_fd' no matter what.
|
||||
ScopeGuard close_guard = [&] {
|
||||
if (should_close_anon_fd == ShouldCloseAnonymousFile::Yes) {
|
||||
int rc = close(anon_fd);
|
||||
ASSERT(rc == 0);
|
||||
anon_fd = -1;
|
||||
}
|
||||
};
|
||||
|
||||
const auto pitch = minimum_pitch(size.width(), format);
|
||||
const auto data_size_in_bytes = size_in_bytes(pitch, size.height());
|
||||
if (size_would_overflow(format, size))
|
||||
return nullptr;
|
||||
|
||||
auto* data = mmap(nullptr, round_up_to_power_of_two(data_size_in_bytes, PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, anon_fd, 0);
|
||||
if (data == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
return nullptr;
|
||||
}
|
||||
const auto pitch = minimum_pitch(size.width(), format);
|
||||
const auto data_size_in_bytes = size_in_bytes(pitch, size.height());
|
||||
|
||||
if (should_close_anon_fd == ShouldCloseAnonymousFile::Yes) {
|
||||
int rc = close(anon_fd);
|
||||
ASSERT(rc == 0);
|
||||
anon_fd = -1;
|
||||
data = mmap(nullptr, round_up_to_power_of_two(data_size_in_bytes, PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, anon_fd, 0);
|
||||
if (data == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return adopt(*new Bitmap(format, anon_fd, size, data));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue