Skip to content

Commit

Permalink
Fix writeFile silently continuing on errors.
Browse files Browse the repository at this point in the history
For example, if the disk is full, it would write `metadata.json`
as an empty file, and then later fail with a JSON parse error
on the same file.

Also implement good error messages using C, which `<iostream>` cannot do.
For example, the above case would probably produce
`metadata.json: No space left on device`.
  • Loading branch information
nh2 committed Jan 12, 2025
1 parent 52f68f6 commit 473d106
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions Converter/modules/unsuck/unsuck.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,13 +516,35 @@ inline string readFile(string path) {
}

inline void writeFile(string path, string text) {
// Use C API to get proper error messages, e.g. disk being full.

ofstream out;
out.open(path);

out << text;
FILE * f = ::fopen(path.c_str(), "wb"); // convenience over open() just for string flags
if (f == NULL) {
// Using `system_error` gets us around buffer size management with `strerror_r()`
throw std::runtime_error("Failed to open " + path + " for writing: " + std::system_error(errno, std::system_category()).what());
}
int fd = ::fileno(f);
if (fd < 0) {
throw std::runtime_error("Failed to obtain FD for " + path + ": " + std::system_error(errno, std::system_category()).what());
}
const char * buf = text.data();
for (size_t bytes_written = 0; bytes_written < text.size(); ) {
::ssize_t res = ::write(fd, &buf[bytes_written], text.size() - bytes_written);
if (res < 0) {
if (errno == EINTR) {
continue;
}
if (::fclose(f) != 0) {
throw std::runtime_error("Failed to close after write to " + path + ": " + std::system_error(errno, std::system_category()).what());
}
throw std::runtime_error("Failed to write to " + path + ": " + std::system_error(errno, std::system_category()).what());
}
bytes_written += res;
}
if (::fclose(f) != 0) {
throw std::runtime_error("Failed to close " + path + ": " + std::system_error(errno, std::system_category()).what());
}

out.close();
}


Expand Down

0 comments on commit 473d106

Please sign in to comment.