Coverage Report

Created: 2026-07-30 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
};