summaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/cpp/tmp_dir.cpp23
-rw-r--r--src/utils/cpp/tmp_dir.hpp37
2 files changed, 59 insertions, 1 deletions
diff --git a/src/utils/cpp/tmp_dir.cpp b/src/utils/cpp/tmp_dir.cpp
index 88cc0f98..8d6e0724 100644
--- a/src/utils/cpp/tmp_dir.cpp
+++ b/src/utils/cpp/tmp_dir.cpp
@@ -21,7 +21,6 @@
#endif
#include <cstdlib>
-#include <string>
#include <string_view>
#include <tuple>
@@ -41,6 +40,28 @@ auto TmpDir::CreateNestedDirectory(TmpDir::Ptr const& parent) noexcept
return CreateImpl(parent, parent->GetPath());
}
+auto TmpDir::CreateFile(TmpDir::Ptr const& parent,
+ std::string const& file_name) noexcept -> TmpFile::Ptr {
+ // Create a new tmp directory to guarantee uniqueness:
+ auto temp_dir = CreateNestedDirectory(parent);
+ if (temp_dir == nullptr) {
+ return nullptr;
+ }
+
+ try {
+ auto file_path = std::filesystem::weakly_canonical(
+ std::filesystem::absolute(temp_dir->GetPath() / file_name));
+ if (not FileSystemManager::CreateFile(file_path)) {
+ return nullptr;
+ }
+
+ return std::shared_ptr<TmpFile const>{
+ new TmpFile(std::move(temp_dir), std::move(file_path))};
+ } catch (...) {
+ return nullptr;
+ }
+}
+
auto TmpDir::CreateImpl(TmpDir::Ptr parent,
std::filesystem::path const& path) noexcept -> Ptr {
static constexpr std::string_view kDirTemplate = "tmp.XXXXXX";
diff --git a/src/utils/cpp/tmp_dir.hpp b/src/utils/cpp/tmp_dir.hpp
index 28805e3d..4312d97e 100644
--- a/src/utils/cpp/tmp_dir.hpp
+++ b/src/utils/cpp/tmp_dir.hpp
@@ -17,8 +17,11 @@
#include <filesystem>
#include <memory>
+#include <string>
#include <utility>
+class TmpFile;
+
class TmpDir final {
public:
using Ptr = std::shared_ptr<TmpDir const>;
@@ -43,6 +46,14 @@ class TmpDir final {
[[nodiscard]] static auto CreateNestedDirectory(
TmpDir::Ptr const& parent) noexcept -> Ptr;
+ /// \brief Create a new unique temporary file. To guarantee uniqueness,
+ /// every file gets created in a new temporary directory. This file remains
+ /// valid even if the parent directory goes out of scope.
+ [[nodiscard]] static auto CreateFile(
+ TmpDir::Ptr const& parent,
+ std::string const& file_name = "file") noexcept
+ -> std::shared_ptr<TmpFile const>;
+
private:
explicit TmpDir(TmpDir::Ptr parent, std::filesystem::path path) noexcept
: parent_{std::move(parent)}, tmp_dir_{std::move(path)} {}
@@ -55,4 +66,30 @@ class TmpDir final {
std::filesystem::path tmp_dir_;
};
+class TmpFile final {
+ friend class TmpDir;
+
+ public:
+ using Ptr = std::shared_ptr<TmpFile const>;
+
+ TmpFile(TmpFile const&) = delete;
+ auto operator=(TmpFile const&) -> TmpFile& = delete;
+ TmpFile(TmpFile&& other) = delete;
+ auto operator=(TmpFile&&) -> TmpFile& = delete;
+ ~TmpFile() noexcept = default;
+
+ [[nodiscard]] auto GetPath() const& noexcept
+ -> std::filesystem::path const& {
+ return file_path_;
+ }
+
+ private:
+ explicit TmpFile(TmpDir::Ptr parent,
+ std::filesystem::path file_path) noexcept
+ : parent_{std::move(parent)}, file_path_{std::move(file_path)} {}
+
+ TmpDir::Ptr parent_;
+ std::filesystem::path file_path_;
+};
+
#endif // INCLUDED_SRC_OTHER_TOOLS_TMP_DIR_HPP