diff --git a/include/tmp/directory.hpp b/include/tmp/directory.hpp index a91b4fe..6fa1b1b 100644 --- a/include/tmp/directory.hpp +++ b/include/tmp/directory.hpp @@ -44,7 +44,7 @@ class directory final : public path { /// for temporary files. If a prefix is provided to the constructor, the /// directory is created in the path /prefix/. The prefix can be /// a path consisting of multiple segments. - explicit directory(std::string_view prefix = "") : path(prefix, mkdtemp) {} + explicit directory(std::string_view prefix = "") : path(prefix, callback) {} /// Concatenates this directory path with a given @p source std::filesystem::path operator/(std::string_view source) const { @@ -58,6 +58,14 @@ class directory final : public path { directory& operator=(directory&&) noexcept = default; ///< move-assignable directory(const directory&) = delete; ///< not copy-constructible auto operator=(const directory&) = delete; ///< not copy-assignable + +protected: + static void callback(char* path) { + if (mkdtemp(path) == nullptr) { + auto ec = std::error_code(errno, std::system_category()); + throw error("Cannot create temporary directory", ec); + } + } }; } // namespace tmp diff --git a/include/tmp/file.hpp b/include/tmp/file.hpp index d5dccb3..900819f 100644 --- a/include/tmp/file.hpp +++ b/include/tmp/file.hpp @@ -79,6 +79,14 @@ class file final : public path { file(const file&) = delete; ///< not copy-constructible auto operator=(const file&) = delete; ///< not copy-assignable +protected: + static void callback(char* path) { + if (mkstemp(path) == -1) { + auto ec = std::error_code(errno, std::system_category()); + throw error("Cannot create temporary file", ec); + } + } + private: bool binary; ///< This file write mode @@ -86,7 +94,7 @@ class file final : public path { /// for temporary files. If a prefix is provided to the constructor, the /// directory is created in the path /prefix/. The prefix can be /// a path consisting of multiple segments. - explicit file(std::string_view prefix, bool binary) : path(prefix, mkstemp), + explicit file(std::string_view prefix, bool binary) : path(prefix, callback), binary(binary) {} /// Returns a stream for this file diff --git a/include/tmp/path.hpp b/include/tmp/path.hpp index b36a441..b0d25c1 100644 --- a/include/tmp/path.hpp +++ b/include/tmp/path.hpp @@ -44,17 +44,18 @@ class path { } protected: + /// Exception type that should be used by subclasses to signal errors + using error = std::filesystem::filesystem_error; + std::filesystem::path underlying; ///< This file path /// Creates a unique temporary path using the given constructor function - template - explicit path(std::string_view prefix, C constructor) { + explicit path(std::string_view prefix, void(*callback)(char*)) { const auto parent = std::filesystem::temp_directory_path() / prefix; std::filesystem::create_directories(parent); std::string arg = parent / "XXXXXX"; - constructor(arg.data()); - + callback(arg.data()); this->underlying = std::move(arg); }