/src/bmcweb/include/duplicatable_file_handle.hpp
Line | Count | Source |
1 | | #pragma once |
2 | | |
3 | | // SPDX-License-Identifier: Apache-2.0 |
4 | | // SPDX-FileCopyrightText: Copyright OpenBMC Authors |
5 | | #include "bmcweb_config.h" |
6 | | |
7 | | #include "logging.hpp" |
8 | | |
9 | | #include <unistd.h> |
10 | | |
11 | | #include <boost/beast/core/file_posix.hpp> |
12 | | |
13 | | #include <cerrno> |
14 | | #include <filesystem> |
15 | | #include <string> |
16 | | #include <string_view> |
17 | | |
18 | | struct DuplicatableFileHandle |
19 | | { |
20 | | boost::beast::file_posix fileHandle; |
21 | | std::string filePath; |
22 | | |
23 | | // Construct from a file descriptor |
24 | | explicit DuplicatableFileHandle(int fd) |
25 | 0 | { |
26 | 0 | fileHandle.native_handle(fd); |
27 | 0 | } |
28 | | |
29 | | // Creates a temporary file with the contents provided, removes it on |
30 | | // destruction. |
31 | | explicit DuplicatableFileHandle(std::string_view contents) |
32 | 0 | { |
33 | 0 | std::filesystem::path tempDir("/tmp/bmcweb"); |
34 | 0 | std::error_code ec; |
35 | 0 | std::filesystem::create_directories(tempDir, ec); |
36 | 0 | if (ec) |
37 | 0 | { |
38 | 0 | BMCWEB_LOG_ERROR("Failed to create directory {}: {}", |
39 | 0 | tempDir.string(), ec.value()); |
40 | 0 | } |
41 | 0 |
|
42 | 0 | filePath = (tempDir / "XXXXXXXXXXX").string(); |
43 | 0 |
|
44 | 0 | int fd = mkstemp(filePath.data()); |
45 | 0 | if (fd < 0) |
46 | 0 | { |
47 | 0 | BMCWEB_LOG_ERROR("Failed to create temporary file: {}", errno); |
48 | 0 | return; |
49 | 0 | } |
50 | 0 | ssize_t written = write(fd, contents.data(), contents.size()); |
51 | 0 | if (written < 0 || static_cast<size_t>(written) != contents.size()) |
52 | 0 | { |
53 | 0 | BMCWEB_LOG_ERROR("Failed to write to temporary file: {}", errno); |
54 | 0 | } |
55 | 0 | close(fd); |
56 | 0 | } |
57 | | |
58 | | void setFd(int fd) |
59 | 0 | { |
60 | 0 | fileHandle.native_handle(fd); |
61 | 0 | } |
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 | 0 | { |
69 | 0 | fileHandle.native_handle(dup(other.fileHandle.native_handle())); |
70 | 0 | } |
71 | | DuplicatableFileHandle& operator=(const DuplicatableFileHandle& other) |
72 | 0 | { |
73 | 0 | if (this == &other) |
74 | 0 | { |
75 | 0 | return *this; |
76 | 0 | } |
77 | 0 | fileHandle.native_handle(dup(other.fileHandle.native_handle())); |
78 | 0 | return *this; |
79 | 0 | } |
80 | | DuplicatableFileHandle& operator=(DuplicatableFileHandle&& other) noexcept = |
81 | | default; |
82 | | |
83 | | ~DuplicatableFileHandle() |
84 | 0 | { |
85 | 0 | if (!filePath.empty()) |
86 | 0 | { |
87 | 0 | std::filesystem::remove(filePath); |
88 | 0 | } |
89 | 0 | } |
90 | | }; |