Air-Trap 1.0.0
A multiplayer R-Type clone game engine built with C++23 and ECS architecture
Loading...
Searching...
No Matches
LibraryBackend_Unix.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** R-Type
4** File description:
5** LibraryBackend_Unix.cpp, Unix based dynamic library handling
6*/
7
8/*
9** MIT License
10**
11** Copyright (c) 2025 Robin Toillon
12**
13** Permission is hereby granted, free of charge, to any person obtaining
14** a copy of this software and associated documentation files (the
15** "Software"), to deal in the Software without restriction, including
16** without limitation the rights to use, copy, modify, merge, publish,
17** distribute, sublicense, and/or sell copies of the Software, and to
18** permit persons to whom the Software is furnished to do so, subject to
19** the following conditions:
20**
21** The above copyright notice and this permission notice shall be
22** included in all copies or substantial portions of the Software.
23**
24** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31*/
32
42#include "RType/Assert.hpp"
43#include "LibraryBackend.hpp"
44
45#include <dlfcn.h>
46
47namespace rtp::sys::impl
48{
50 // Public API
52
53 auto LibraryBackend::open(std::string_view path)
54 -> std::expected<void *, rtp::Error>
55 {
56 std::string safeNullTerminatedPath(path);
57 void *handle = dlopen(safeNullTerminatedPath.c_str(),
58 RTLD_LAZY | RTLD_LOCAL);
59 if (!handle) [[unlikely]] {
60 const char *err = dlerror();
61 return std::unexpected{Error::failure(ErrorCode::LibraryLoadFailed,
62 "dlopen error: {}",
63 err ? err : "Unknown dlopen error")};
64 }
65
66 return handle;
67 }
68
69 auto LibraryBackend::close(void *handle) noexcept
70 -> std::expected<void, rtp::Error>
71 {
72 if (dlclose(handle) != 0) [[unlikely]] {
73 const char *err = dlerror();
74 if (err)
75 return std::unexpected{
77 "dlclose error: {}",
78 err ? err : "Unknown dlclose error")};
79 }
80
81 return {};
82 }
83
84 auto LibraryBackend::getSymbol(void *handle, std::string_view name)
85 -> std::expected<void *, rtp::Error>
86 {
87 RTP_ASSERT(handle != nullptr,
88 "LoaderBackend: Handle cannot be null during symbol lookup");
89 RTP_ASSERT(!name.empty(), "LoaderBackend: Symbol name cannot be empty");
90 dlerror();
91
92 std::string safeNullTerminatedName(name);
93 void *symbol = dlsym(handle, safeNullTerminatedName.c_str());
94 const char *err = dlerror();
95 if (err) [[unlikely]]
96 return std::unexpected{Error::failure(ErrorCode::SymbolNotFound,
97 "dlsym error: {}", err)};
98
99 return symbol;
100 }
101}
Assertion and verification macros for runtime checks.
#define RTP_ASSERT(condition, msg,...)
Assertion macro (Debug mode)
Definition Assert.hpp:113
Declarations for platform-specific dynamic library handling.
static auto failure(ErrorCode code, std::format_string< Args... > fmt, Args &&...args) -> Error
Create a failure-level error.
static auto getSymbol(void *handle, std::string_view name) -> std::expected< void *, rtp::Error >
Get a symbol from the dynamic library.
static auto open(std::string_view path) -> std::expected< void *, rtp::Error >
Open a dynamic library from the given path.
static auto close(void *handle) noexcept -> std::expected< void, rtp::Error >
Close the dynamic library handle.
@ LibraryLoadFailed
Failed to load dynamic library.
@ SymbolNotFound
Symbol not found in dynamic library.