diff options
author | Guillaume Maudoux <guillaume.maudoux@tweag.io> | 2022-10-16 20:39:19 +0200 |
---|---|---|
committer | Guillaume Maudoux <guillaume.maudoux@tweag.io> | 2022-10-16 20:39:19 +0200 |
commit | 3f9f6ae12712b366c038f21de99c8ede6c805be9 (patch) | |
tree | f2510a23941efd48c102580fc945107c5cb32e12 /src/libutil | |
parent | 96f2dd99d39da61706895b05ed864558679fac79 (diff) | |
parent | 3093bd3a855b8fa1f572fd5a33c1971adf5e3e08 (diff) |
Merge remote-tracking branch 'origin/master' into coerce-string
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/archive.cc | 7 | ||||
-rw-r--r-- | src/libutil/archive.hh | 1 | ||||
-rw-r--r-- | src/libutil/args.cc | 6 | ||||
-rw-r--r-- | src/libutil/util.cc | 38 | ||||
-rw-r--r-- | src/libutil/util.hh | 8 |
5 files changed, 53 insertions, 7 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index 30b471af5..4b0636129 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -234,6 +234,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path) else if (s == "contents" && type == tpRegular) { parseContents(sink, source, path); + sink.closeRegularFile(); } else if (s == "executable" && type == tpRegular) { @@ -324,6 +325,12 @@ struct RestoreSink : ParseSink if (!fd) throw SysError("creating file '%1%'", p); } + void closeRegularFile() override + { + /* Call close explicitly to make sure the error is checked */ + fd.close(); + } + void isExecutable() override { struct stat st; diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh index 79ce08df0..ac4183bf5 100644 --- a/src/libutil/archive.hh +++ b/src/libutil/archive.hh @@ -60,6 +60,7 @@ struct ParseSink virtual void createDirectory(const Path & path) { }; virtual void createRegularFile(const Path & path) { }; + virtual void closeRegularFile() { }; virtual void isExecutable() { }; virtual void preallocateContents(uint64_t size) { }; virtual void receiveContents(std::string_view data) { }; diff --git a/src/libutil/args.cc b/src/libutil/args.cc index 44b63f0f6..753980fd4 100644 --- a/src/libutil/args.cc +++ b/src/libutil/args.cc @@ -216,7 +216,7 @@ nlohmann::json Args::toJSON() if (flag->shortName) j["shortName"] = std::string(1, flag->shortName); if (flag->description != "") - j["description"] = flag->description; + j["description"] = trim(flag->description); j["category"] = flag->category; if (flag->handler.arity != ArityAny) j["arity"] = flag->handler.arity; @@ -237,7 +237,7 @@ nlohmann::json Args::toJSON() } auto res = nlohmann::json::object(); - res["description"] = description(); + res["description"] = trim(description()); res["flags"] = std::move(flags); res["args"] = std::move(args); auto s = doc(); @@ -379,7 +379,7 @@ nlohmann::json MultiCommand::toJSON() auto j = command->toJSON(); auto cat = nlohmann::json::object(); cat["id"] = command->category(); - cat["description"] = categories[command->category()]; + cat["description"] = trim(categories[command->category()]); j["category"] = std::move(cat); cmds[name] = std::move(j); } diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 96ac11ea2..623b74bdd 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -353,7 +353,7 @@ void readFile(const Path & path, Sink & sink) } -void writeFile(const Path & path, std::string_view s, mode_t mode) +void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync) { AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode); if (!fd) @@ -364,10 +364,16 @@ void writeFile(const Path & path, std::string_view s, mode_t mode) e.addTrace({}, "writing file '%1%'", path); throw; } + if (sync) + fd.fsync(); + // Explicitly close to make sure exceptions are propagated. + fd.close(); + if (sync) + syncParent(path); } -void writeFile(const Path & path, Source & source, mode_t mode) +void writeFile(const Path & path, Source & source, mode_t mode, bool sync) { AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode); if (!fd) @@ -386,6 +392,20 @@ void writeFile(const Path & path, Source & source, mode_t mode) e.addTrace({}, "writing file '%1%'", path); throw; } + if (sync) + fd.fsync(); + // Explicitly close to make sure exceptions are propagated. + fd.close(); + if (sync) + syncParent(path); +} + +void syncParent(const Path & path) +{ + AutoCloseFD fd = open(dirOf(path).c_str(), O_RDONLY, 0); + if (!fd) + throw SysError("opening file '%1%'", path); + fd.fsync(); } std::string readLine(int fd) @@ -841,6 +861,20 @@ void AutoCloseFD::close() } } +void AutoCloseFD::fsync() +{ + if (fd != -1) { + int result; +#if __APPLE__ + result = ::fcntl(fd, F_FULLFSYNC); +#else + result = ::fsync(fd); +#endif + if (result == -1) + throw SysError("fsync file descriptor %1%", fd); + } +} + AutoCloseFD::operator bool() const { diff --git a/src/libutil/util.hh b/src/libutil/util.hh index cd83f250f..e5c678682 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -115,9 +115,12 @@ std::string readFile(const Path & path); void readFile(const Path & path, Sink & sink); /* Write a string to a file. */ -void writeFile(const Path & path, std::string_view s, mode_t mode = 0666); +void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false); -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); + +/* Flush a file's parent directory to disk */ +void syncParent(const Path & path); /* Read a line from a file descriptor. */ std::string readLine(int fd); @@ -231,6 +234,7 @@ public: explicit operator bool() const; int release(); void close(); + void fsync(); }; |