diff options
| author | Lexi Winter <lexi@le-fay.org> | 2025-06-30 07:51:23 +0100 |
|---|---|---|
| committer | Lexi Winter <lexi@le-fay.org> | 2025-06-30 07:51:23 +0100 |
| commit | 034cd404a129103a8dd7747e6bd00ffd5550da93 (patch) | |
| tree | d27946517d4d9333abd26ac50bbd4a436093e2ce /nihil.posix/tempfile.cc | |
| parent | 3e7902f7d790a486d3d9cb978df193f07f3a6ad9 (diff) | |
| download | nihil-034cd404a129103a8dd7747e6bd00ffd5550da93.tar.gz nihil-034cd404a129103a8dd7747e6bd00ffd5550da93.tar.bz2 | |
refactoring
Diffstat (limited to 'nihil.posix/tempfile.cc')
| -rw-r--r-- | nihil.posix/tempfile.cc | 128 |
1 files changed, 0 insertions, 128 deletions
diff --git a/nihil.posix/tempfile.cc b/nihil.posix/tempfile.cc deleted file mode 100644 index b1d3dee..0000000 --- a/nihil.posix/tempfile.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This source code is released into the public domain. - */ - -module; - -#include <algorithm> -#include <coroutine> -#include <expected> -#include <filesystem> -#include <random> -#include <string> - -#include <fcntl.h> -#include <unistd.h> - -module nihil.posix; - -import nihil.flagset; -import :getenv; -import :open; - -namespace nihil { - -temporary_file::temporary_file(nihil::fd &&fd, - std::filesystem::path path) noexcept - : m_fd(std::move(fd)) - , m_path(std::move(path)) -{ -} - -temporary_file::temporary_file(nihil::fd &&fd) noexcept - : m_fd(std::move(fd)) -{ -} - -temporary_file::temporary_file(temporary_file &&other) noexcept - : m_fd(std::move(other.m_fd)) - , m_path(std::move(other.m_path)) -{ -} - -temporary_file::~temporary_file() //NOLINT(bugprone-exception-escape) -{ - if (m_fd) - release(); -} - -auto temporary_file::release(this temporary_file &self) -> void -{ - if (!self.m_fd) - throw std::logic_error( - "release() called on already-released tempfile"); - - if (!self.m_path.empty()) { - auto ec = std::error_code(); // ignore errors - remove(self.path(), ec); - - self.m_path.clear(); - } - - std::ignore = self.m_fd.close(); -} - -auto temporary_file::path(this temporary_file const &self) - -> std::filesystem::path const & -{ - if (self.m_path.empty()) - throw std::logic_error( - "path() called on unlinked temporary_file"); - - return self.m_path; -} - -auto temporary_file::fd(this temporary_file &self) -> nihil::fd & -{ - if (!self.m_fd) - throw std::logic_error("fd() called on empty temporary_file"); - - return self.m_fd; -} - -auto tempfile(tempfile_flags_t flags) -> std::expected<temporary_file, error> -{ - auto rng = std::default_random_engine(std::random_device{}()); - - auto random_name = [&] -> std::string { - auto constexpr length = std::size_t{12}; - auto constexpr randchars = std::string_view( - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"); - - auto dist = std::uniform_int_distribution<>( - 0, randchars.size() - 1); - auto ret = std::string(length, 0); - std::ranges::generate_n(ret.begin(), length, - [&] -> char { - return randchars[dist(rng)]; - }); - return ret; - }; - - auto dir = std::filesystem::path(getenv("TMPDIR").value_or("/tmp")); - - // Keep trying until we don't get EEXIST. - for (;;) { - auto filename = dir / (random_name() + ".tmp"); - auto fd = nihil::open(filename, O_RDWR | O_CREAT | O_EXCL, - 0600); - if (!fd) { - if (fd.error() == std::errc::file_exists) - continue; - return std::unexpected(fd.error()); - } - - if (flags & tempfile_unlink) { - auto ec = std::error_code(); - remove(filename, ec); - return temporary_file(std::move(*fd)); - } else { - return temporary_file(std::move(*fd), - std::move(filename)); - } - } -} - -} // namespace nihil |
