libutil: writeFile variant for file descriptors

`writeFile` lose its `sync` boolean flag to make things simpler.

A new `writeFileAndSync` function is created and all call sites are
converted to it.

Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192
Signed-off-by: Raito Bezarius <raito@lix.systems>
This commit is contained in:
Raito Bezarius
2025-06-24 00:28:09 +02:00
committed by eldritch horrors
parent 10509774ed
commit 2d836357dc
3 changed files with 49 additions and 27 deletions
+2 -2
View File
@@ -224,7 +224,7 @@ void LocalStore::initDB(DBState & state)
else if (curSchema == 0) { /* new store */
curSchema = nixSchemaVersion;
openDB(state, true);
writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
writeFileAndSync(schemaPath, fmt("%1%", nixSchemaVersion), 0666);
}
else if (curSchema < nixSchemaVersion) {
@@ -277,7 +277,7 @@ void LocalStore::initDB(DBState & state)
txn.commit();
}
writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
writeFileAndSync(schemaPath, fmt("%1%", nixSchemaVersion), 0666);
lockFile(globalLock.get(), ltRead, always_progresses);
}
+35 -15
View File
@@ -358,28 +358,49 @@ Generator<Bytes> readFileSource(const Path & path)
}(std::move(fd));
}
void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync, bool allowInterrupts)
void writeFile(const Path & path, std::string_view s, mode_t mode, bool allowInterrupts)
{
AutoCloseFD fd{open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode)};
if (!fd)
throw SysError("opening file '%1%'", path);
writeFile(fd, s, mode, allowInterrupts);
/* Close explicitly to propagate the exceptions. */
fd.close();
}
void writeFile(AutoCloseFD & fd, std::string_view s, mode_t mode, bool allowInterrupts)
{
assert(fd);
try {
writeFull(fd.get(), s, allowInterrupts);
} catch (Error & e) {
e.addTrace({}, "writing file '%1%'", path);
e.addTrace({}, "writing file '%1%'", fd.guessOrInventPath());
throw;
}
if (sync)
fd.fsync();
// Explicitly close to make sure exceptions are propagated.
fd.close();
if (sync)
syncParent(path);
}
void writeFileUninterruptible(const Path & path, std::string_view s, mode_t mode, bool sync)
void writeFileUninterruptible(const Path & path, std::string_view s, mode_t mode)
{
writeFile(path, s, mode, sync, false);
writeFile(path, s, mode, false);
}
void writeFileAndSync(const Path & path, std::string_view s, mode_t mode)
{
{
AutoCloseFD fd{open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode)};
if (!fd) {
throw SysError("opening file '%1%'", path);
}
writeFile(fd, s, mode);
fd.fsync();
/* Close explicitly to ensure that exceptions are propagated. */
fd.close();
}
syncParent(path);
}
static AutoCloseFD openForWrite(const Path & path, mode_t mode)
@@ -400,7 +421,7 @@ static void closeForWrite(const Path & path, AutoCloseFD & fd, bool sync)
syncParent(path);
}
void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
void writeFile(const Path & path, Source & source, mode_t mode)
{
AutoCloseFD fd = openForWrite(path, mode);
@@ -417,11 +438,10 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
e.addTrace({}, "writing file '%1%'", path);
throw;
}
closeForWrite(path, fd, sync);
closeForWrite(path, fd, false);
}
kj::Promise<Result<void>>
writeFile(const Path & path, AsyncInputStream & source, mode_t mode, bool sync)
kj::Promise<Result<void>> writeFile(const Path & path, AsyncInputStream & source, mode_t mode)
try {
AutoCloseFD fd = openForWrite(path, mode);
@@ -439,7 +459,7 @@ try {
e.addTrace({}, "writing file '%1%'", path);
throw;
}
closeForWrite(path, fd, sync);
closeForWrite(path, fd, false);
co_return result::success();
} catch (...) {
co_return result::current_exception();
+12 -10
View File
@@ -190,19 +190,21 @@ Generator<Bytes> readFileSource(const Path & path);
* Write a string to a file.
*/
void writeFile(
const Path & path,
std::string_view s,
mode_t mode = 0666,
bool sync = false,
bool allowInterrupts = true
);
void writeFileUninterruptible(
const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false
const Path & path, std::string_view s, mode_t mode = 0666, bool allowInterrupts = true
);
void writeFileUninterruptible(const Path & path, std::string_view s, mode_t mode = 0666);
void writeFile(const Path & path, Source & source, mode_t mode = 0666);
void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
void writeFile(
AutoCloseFD & fd, std::string_view s, mode_t mode = 0666, bool allowInterrupts = true
);
kj::Promise<Result<void>>
writeFile(const Path & path, AsyncInputStream & source, mode_t mode = 0666, bool sync = false);
writeFile(const Path & path, AsyncInputStream & source, mode_t mode = 0666);
/**
* Write a string to a file and flush the file and its parents direcotry to disk.
*/
void writeFileAndSync(const Path & path, std::string_view s, mode_t mode = 0666);
/**
* Flush a file's parent directory to disk