blob: e346096c933451a50ebeb3b7ad634bae8f6c7752 [file] [log] [blame]
Ed Tanousf2cd7662025-02-08 15:10:24 -08001#pragma once
2
Ed Tanous40e9b922024-09-10 13:50:16 -07003// SPDX-License-Identifier: Apache-2.0
4// SPDX-FileCopyrightText: Copyright OpenBMC Authors
rajeeranjane5ab2df2025-07-21 15:47:55 +05305#include "bmcweb_config.h"
6
7#include "logging.hpp"
8
Ed Tanousd7857202025-01-28 15:32:26 -08009#include <unistd.h>
10
Ed Tanousf51d8632024-05-16 09:14:01 -070011#include <boost/beast/core/file_posix.hpp>
12
rajeeranjane5ab2df2025-07-21 15:47:55 +053013#include <cerrno>
14#include <filesystem>
15#include <string>
16#include <string_view>
17
Ed Tanousf51d8632024-05-16 09:14:01 -070018struct DuplicatableFileHandle
19{
20 boost::beast::file_posix fileHandle;
rajeeranjane5ab2df2025-07-21 15:47:55 +053021 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 Tanousf51d8632024-05-16 09:14:01 -070062
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 Williams504af5a2025-02-03 14:29:03 -050080 DuplicatableFileHandle& operator=(DuplicatableFileHandle&& other) noexcept =
81 default;
rajeeranjane5ab2df2025-07-21 15:47:55 +053082
83 ~DuplicatableFileHandle()
84 {
85 if (!filePath.empty())
86 {
87 std::filesystem::remove(filePath);
88 }
89 }
Ed Tanousf51d8632024-05-16 09:14:01 -070090};