Serenity Operating System
1/*
2 * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/DeprecatedString.h>
8#include <AK/ScopeGuard.h>
9#include <LibCore/File.h>
10#include <LibCore/MappedFile.h>
11#include <LibCore/System.h>
12#include <fcntl.h>
13#include <sys/mman.h>
14#include <unistd.h>
15
16namespace Core {
17
18ErrorOr<NonnullRefPtr<MappedFile>> MappedFile::map(StringView path)
19{
20 auto fd = TRY(Core::System::open(path, O_RDONLY | O_CLOEXEC, 0));
21 return map_from_fd_and_close(fd, path);
22}
23
24ErrorOr<NonnullRefPtr<MappedFile>> MappedFile::map_from_file(NonnullOwnPtr<Core::File> stream, StringView path)
25{
26 return map_from_fd_and_close(stream->leak_fd(Badge<MappedFile> {}), path);
27}
28
29ErrorOr<NonnullRefPtr<MappedFile>> MappedFile::map_from_fd_and_close(int fd, [[maybe_unused]] StringView path)
30{
31 TRY(Core::System::fcntl(fd, F_SETFD, FD_CLOEXEC));
32
33 ScopeGuard fd_close_guard = [fd] {
34 close(fd);
35 };
36
37 auto stat = TRY(Core::System::fstat(fd));
38 auto size = stat.st_size;
39
40 auto* ptr = TRY(Core::System::mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0, 0, path));
41
42 return adopt_ref(*new MappedFile(ptr, size));
43}
44
45MappedFile::MappedFile(void* ptr, size_t size)
46 : m_data(ptr)
47 , m_size(size)
48{
49}
50
51MappedFile::~MappedFile()
52{
53 auto res = Core::System::munmap(m_data, m_size);
54 if (res.is_error())
55 dbgln("Failed to unmap MappedFile (@ {:p}): {}", m_data, res.error());
56}
57
58}