blob: 0eeb6ae5457a46266845215273dad12fe5056f98 [file] [log] [blame]
William A. Kennington IIIe7743452022-08-12 17:39:44 -07001#include <cstdlib>
William A. Kennington III4f5711c2022-08-12 17:01:53 -07002#include <stdplus/fd/fmt.hpp>
3#include <stdplus/fd/ops.hpp>
William A. Kennington IIIe7743452022-08-12 17:39:44 -07004#include <stdplus/util/cexec.hpp>
5#include <sys/stat.h>
William A. Kennington III4f5711c2022-08-12 17:01:53 -07006
7namespace stdplus
8{
9namespace fd
10{
11
William A. Kennington IIIa4f71f92022-08-18 14:17:00 -070012FormatBuffer::FormatBuffer(Fd& fd, size_t max) : fd(fd), max(max)
William A. Kennington III4f5711c2022-08-12 17:01:53 -070013{
14}
15
16FormatBuffer::~FormatBuffer() noexcept(false)
17{
18 flush();
19}
20
21void FormatBuffer::flush()
22{
23 if (buf.size() > 0)
24 {
William A. Kennington IIIa4f71f92022-08-18 14:17:00 -070025 writeExact(fd, buf);
William A. Kennington III4f5711c2022-08-12 17:01:53 -070026 buf.clear();
27 }
28}
29
30void FormatBuffer::writeIfNeeded()
31{
32 if (buf.size() >= max)
33 {
34 flush();
35 }
36}
37
William A. Kennington IIIe7743452022-08-12 17:39:44 -070038FormatToFile::FormatToFile(std::string_view tmpl) :
39 tmpname(tmpl),
40 fd(CHECK_ERRNO(mkstemp(tmpname.data()),
41 [&](int error) {
42 auto msg = fmt::format("mkstemp({})", tmpname);
43 tmpname.clear();
44 throw std::system_error(error, std::generic_category(),
45 msg);
46 })),
47 buf(fd)
48{
49}
50
51FormatToFile::~FormatToFile()
52{
53 if (!tmpname.empty())
54 {
55 std::error_code ec;
56 std::filesystem::remove(tmpname, ec);
57 }
58}
59
60void FormatToFile::commit(const std::filesystem::path& out, int mode)
61{
62 {
63 buf.flush();
64 auto ifd = std::move(fd);
65 }
66 CHECK_ERRNO(chmod(tmpname.c_str(), mode), [&](int error) {
67 throw std::system_error(error, std::generic_category(),
68 fmt::format("chmod({}, {})", tmpname, mode));
69 });
70 std::filesystem::rename(tmpname, out);
71 tmpname.clear();
72}
73
William A. Kennington III4f5711c2022-08-12 17:01:53 -070074} // namespace fd
75} // namespace stdplus