| 130 | } // namespace |
| 131 | |
| 132 | void write_bytes_atomic(const std::filesystem::path& target, const void* bytes, std::size_t size, bool restrict_perms) { |
| 133 | const auto temp = make_temp_sibling(target); |
| 134 | { |
| 135 | std::ofstream out(temp, std::ios::binary | std::ios::trunc); |
| 136 | if (!out) { |
| 137 | throw std::runtime_error("write_bytes_atomic: cannot open temp " + temp.string()); |
| 138 | } |
| 139 | if (size > 0) { |
| 140 | out.write(reinterpret_cast<const char*>(bytes), static_cast<std::streamsize>(size)); |
| 141 | } |
| 142 | out.flush(); |
| 143 | if (!out) { |
| 144 | std::error_code ec_rm; |
| 145 | std::filesystem::remove(temp, ec_rm); |
| 146 | throw std::runtime_error("write_bytes_atomic: write failed for temp " + temp.string()); |
| 147 | } |
| 148 | } |
| 149 | if (restrict_perms) { |
| 150 | std::error_code perm_ec; |
| 151 | std::filesystem::permissions(temp, std::filesystem::perms::owner_read | std::filesystem::perms::owner_write, |
| 152 | std::filesystem::perm_options::replace, perm_ec); |
| 153 | // perm_ec ignored — owner-only is best-effort (no-op on Windows |
| 154 | // where the POSIX permission model doesn't apply). |
| 155 | } |
| 156 | std::error_code rename_ec; |
| 157 | std::filesystem::rename(temp, target, rename_ec); |
| 158 | if (rename_ec) { |
| 159 | std::error_code ec_rm; |
| 160 | std::filesystem::remove(temp, ec_rm); |
| 161 | throw std::runtime_error("write_bytes_atomic: rename to " + target.string() + " failed: " + rename_ec.message()); |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | // ---- make_dirs -------------------------------------------------------------- |
| 166 |
no test coverage detected