|
1 | 1 | #include "platform_util.h" |
2 | 2 |
|
| 3 | +#include <cassert> |
3 | 4 | // clang-format off |
4 | 5 | #if defined(__x86_64__) || defined(_M_X64) |
5 | 6 | # define DD_SDK_CPU_ARCH "x86_64" |
|
25 | 26 | # define DD_SDK_KERNEL "Linux" |
26 | 27 | # include "string_util.h" |
27 | 28 | # include <fstream> |
| 29 | +# include <sys/types.h> |
| 30 | +# include <sys/mman.h> |
| 31 | +# include <fcntl.h> |
| 32 | +# include <errno.h> |
28 | 33 | # endif |
29 | 34 | #elif defined(_MSC_VER) |
30 | 35 | # include <windows.h> |
@@ -98,7 +103,7 @@ std::tuple<std::string, std::string> get_windows_info() { |
98 | 103 | // application manifest, which is the lowest version supported by the |
99 | 104 | // application. Use `RtlGetVersion` to obtain the accurate OS version |
100 | 105 | // regardless of the manifest. |
101 | | - using RtlGetVersion = auto(*)(LPOSVERSIONINFOEXW)->NTSTATUS; |
| 106 | + using RtlGetVersion = auto (*)(LPOSVERSIONINFOEXW)->NTSTATUS; |
102 | 107 |
|
103 | 108 | RtlGetVersion func = |
104 | 109 | (RtlGetVersion)GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); |
@@ -224,5 +229,56 @@ int at_fork_in_child(void (*on_fork)()) { |
224 | 229 | #endif |
225 | 230 | } |
226 | 231 |
|
| 232 | +InMemoryFile::InMemoryFile(void* handle) : handle_(handle) {} |
| 233 | + |
| 234 | +InMemoryFile::InMemoryFile(InMemoryFile&& rhs) { |
| 235 | + std::swap(rhs.handle_, handle_); |
| 236 | +}; |
| 237 | +InMemoryFile& InMemoryFile::operator=(InMemoryFile&& rhs) { |
| 238 | + std::swap(handle_, rhs.handle_); |
| 239 | + return *this; |
| 240 | +} |
| 241 | + |
| 242 | +#if defined(__linux__) || defined(__unix__) |
| 243 | + |
| 244 | +InMemoryFile::~InMemoryFile() { |
| 245 | + /// NOTE(@dmehala): No need to close the fd since it is automatically handled |
| 246 | + /// by `MFD_CLOEXEC`. |
| 247 | + if (handle_ == nullptr) return; |
| 248 | + int* data = static_cast<int*>(handle_); |
| 249 | + delete (data); |
| 250 | +} |
| 251 | + |
| 252 | +bool InMemoryFile::write_then_seal(const std::string& data) { |
| 253 | + int fd = *static_cast<int*>(handle_); |
| 254 | + |
| 255 | + size_t written = write(fd, data.data(), data.size()); |
| 256 | + if (written != data.size()) return false; |
| 257 | + |
| 258 | + return fcntl(fd, F_ADD_SEALS, |
| 259 | + F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) == 0; |
| 260 | +} |
| 261 | + |
| 262 | +Expected<InMemoryFile> InMemoryFile::make(std::string_view name) { |
| 263 | + int fd = memfd_create(name.data(), MFD_CLOEXEC | MFD_ALLOW_SEALING); |
| 264 | + if (fd == -1) { |
| 265 | + std::string err_msg = "failed to create an anonymous file. errno = "; |
| 266 | + err_msg += std::to_string(errno); |
| 267 | + return Error{Error::Code::OTHER, std::move(err_msg)}; |
| 268 | + } |
| 269 | + |
| 270 | + int* handle = new int; |
| 271 | + *handle = fd; |
| 272 | + return InMemoryFile(handle); |
| 273 | +} |
| 274 | + |
| 275 | +#else |
| 276 | +InMemoryFile::~InMemoryFile() {} |
| 277 | +bool InMemoryFile::write_then_seal(const std::string&) { return false; } |
| 278 | +Expected<InMemoryFile> InMemoryFile::make(StringView) { |
| 279 | + return Error{Error::Code::NOT_IMPLEMENTED, "In-memory file not implemented"}; |
| 280 | +} |
| 281 | +#endif |
| 282 | + |
227 | 283 | } // namespace tracing |
228 | 284 | } // namespace datadog |
0 commit comments