| Ed Tanous | f2cd766 | 2025-02-08 15:10:24 -0800 | [diff] [blame] | 1 | #pragma once |
| 2 | |
| Ed Tanous | 40e9b92 | 2024-09-10 13:50:16 -0700 | [diff] [blame] | 3 | // SPDX-License-Identifier: Apache-2.0 |
| 4 | // SPDX-FileCopyrightText: Copyright OpenBMC Authors |
| rajeeranjan | e5ab2df | 2025-07-21 15:47:55 +0530 | [diff] [blame^] | 5 | #include "bmcweb_config.h" |
| 6 | |
| 7 | #include "logging.hpp" |
| 8 | |
| Ed Tanous | d785720 | 2025-01-28 15:32:26 -0800 | [diff] [blame] | 9 | #include <unistd.h> |
| 10 | |
| Ed Tanous | f51d863 | 2024-05-16 09:14:01 -0700 | [diff] [blame] | 11 | #include <boost/beast/core/file_posix.hpp> |
| 12 | |
| rajeeranjan | e5ab2df | 2025-07-21 15:47:55 +0530 | [diff] [blame^] | 13 | #include <cerrno> |
| 14 | #include <filesystem> |
| 15 | #include <string> |
| 16 | #include <string_view> |
| 17 | |
| Ed Tanous | f51d863 | 2024-05-16 09:14:01 -0700 | [diff] [blame] | 18 | struct DuplicatableFileHandle |
| 19 | { |
| 20 | boost::beast::file_posix fileHandle; |
| rajeeranjan | e5ab2df | 2025-07-21 15:47:55 +0530 | [diff] [blame^] | 21 | std::string filePath; |
| 22 | |
| 23 | // Construct from a file descriptor |
| 24 | explicit DuplicatableFileHandle(int fd) |
| 25 | { |
| 26 | fileHandle.native_handle(fd); |
| 27 | } |
| 28 | |
| 29 | // Creates a temporary file with the contents provided, removes it on |
| 30 | // destruction. |
| 31 | explicit DuplicatableFileHandle(std::string_view contents) |
| 32 | { |
| 33 | std::filesystem::path tempDir("/tmp/bmcweb"); |
| 34 | std::error_code ec; |
| 35 | std::filesystem::create_directories(tempDir, ec); |
| 36 | if (ec) |
| 37 | { |
| 38 | BMCWEB_LOG_ERROR("Failed to create directory {}: {}", |
| 39 | tempDir.string(), ec.value()); |
| 40 | } |
| 41 | |
| 42 | filePath = (tempDir / "XXXXXXXXXXX").string(); |
| 43 | |
| 44 | int fd = mkstemp(filePath.data()); |
| 45 | if (fd < 0) |
| 46 | { |
| 47 | BMCWEB_LOG_ERROR("Failed to create temporary file: {}", errno); |
| 48 | return; |
| 49 | } |
| 50 | ssize_t written = write(fd, contents.data(), contents.size()); |
| 51 | if (written < 0 || static_cast<size_t>(written) != contents.size()) |
| 52 | { |
| 53 | BMCWEB_LOG_ERROR("Failed to write to temporary file: {}", errno); |
| 54 | } |
| 55 | close(fd); |
| 56 | } |
| 57 | |
| 58 | void setFd(int fd) |
| 59 | { |
| 60 | fileHandle.native_handle(fd); |
| 61 | } |
| Ed Tanous | f51d863 | 2024-05-16 09:14:01 -0700 | [diff] [blame] | 62 | |
| 63 | DuplicatableFileHandle() = default; |
| 64 | DuplicatableFileHandle(DuplicatableFileHandle&&) noexcept = default; |
| 65 | // Overload copy constructor, because posix doesn't have dup(), but linux |
| 66 | // does |
| 67 | DuplicatableFileHandle(const DuplicatableFileHandle& other) |
| 68 | { |
| 69 | fileHandle.native_handle(dup(other.fileHandle.native_handle())); |
| 70 | } |
| 71 | DuplicatableFileHandle& operator=(const DuplicatableFileHandle& other) |
| 72 | { |
| 73 | if (this == &other) |
| 74 | { |
| 75 | return *this; |
| 76 | } |
| 77 | fileHandle.native_handle(dup(other.fileHandle.native_handle())); |
| 78 | return *this; |
| 79 | } |
| Patrick Williams | 504af5a | 2025-02-03 14:29:03 -0500 | [diff] [blame] | 80 | DuplicatableFileHandle& operator=(DuplicatableFileHandle&& other) noexcept = |
| 81 | default; |
| rajeeranjan | e5ab2df | 2025-07-21 15:47:55 +0530 | [diff] [blame^] | 82 | |
| 83 | ~DuplicatableFileHandle() |
| 84 | { |
| 85 | if (!filePath.empty()) |
| 86 | { |
| 87 | std::filesystem::remove(filePath); |
| 88 | } |
| 89 | } |
| Ed Tanous | f51d863 | 2024-05-16 09:14:01 -0700 | [diff] [blame] | 90 | }; |