Add temp file and FD support to TemporaryFileHandle
This commit adds file descriptor and temporary file management to
DuplicatableFileHandle, removing the redundant test-only
TemporaryFileHandle utility.
Changes:
- Add file descriptor constructor and setFd() method
- Add temporary file constructor with string_view content
- Add filePath member and automatic cleanup in destructor
- Add configurable temp-dir meson option (default: /tmp/bmcweb)
- Remove include/file_test_utilities.hpp
- Update all tests to use DuplicatableFileHandle
- Rename stringPath to filePath
These features will be used by the multipart parser to stream
large uploads to temporary files instead of keeping them in memory,
and by the update service to pass file descriptors over D-Bus.
Change-Id: I982f5928d453f9f0c13d91c3525006134ddc87b3
Signed-off-by: Rajeev Ranjan <ranjan.rajeev1609@gmail.com>
diff --git a/include/duplicatable_file_handle.hpp b/include/duplicatable_file_handle.hpp
index f199485..e346096 100644
--- a/include/duplicatable_file_handle.hpp
+++ b/include/duplicatable_file_handle.hpp
@@ -2,13 +2,63 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#include "bmcweb_config.h"
+
+#include "logging.hpp"
+
#include <unistd.h>
#include <boost/beast/core/file_posix.hpp>
+#include <cerrno>
+#include <filesystem>
+#include <string>
+#include <string_view>
+
struct DuplicatableFileHandle
{
boost::beast::file_posix fileHandle;
+ std::string filePath;
+
+ // Construct from a file descriptor
+ explicit DuplicatableFileHandle(int fd)
+ {
+ fileHandle.native_handle(fd);
+ }
+
+ // Creates a temporary file with the contents provided, removes it on
+ // destruction.
+ explicit DuplicatableFileHandle(std::string_view contents)
+ {
+ std::filesystem::path tempDir("/tmp/bmcweb");
+ std::error_code ec;
+ std::filesystem::create_directories(tempDir, ec);
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Failed to create directory {}: {}",
+ tempDir.string(), ec.value());
+ }
+
+ filePath = (tempDir / "XXXXXXXXXXX").string();
+
+ int fd = mkstemp(filePath.data());
+ if (fd < 0)
+ {
+ BMCWEB_LOG_ERROR("Failed to create temporary file: {}", errno);
+ return;
+ }
+ ssize_t written = write(fd, contents.data(), contents.size());
+ if (written < 0 || static_cast<size_t>(written) != contents.size())
+ {
+ BMCWEB_LOG_ERROR("Failed to write to temporary file: {}", errno);
+ }
+ close(fd);
+ }
+
+ void setFd(int fd)
+ {
+ fileHandle.native_handle(fd);
+ }
DuplicatableFileHandle() = default;
DuplicatableFileHandle(DuplicatableFileHandle&&) noexcept = default;
@@ -29,5 +79,12 @@
}
DuplicatableFileHandle& operator=(DuplicatableFileHandle&& other) noexcept =
default;
- ~DuplicatableFileHandle() = default;
+
+ ~DuplicatableFileHandle()
+ {
+ if (!filePath.empty())
+ {
+ std::filesystem::remove(filePath);
+ }
+ }
};