mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-25 15:56:15 +02:00
Make app setting file writes durable
The atomic write replaces the old with the new file, but unless we sync the parent directory, that replacement is not permanent yet.
This commit is contained in:
parent
fc4582a61f
commit
9f1827dc24
@ -348,7 +348,17 @@ bool LinkApp::save() {
|
||||
|
||||
if (out.tellp() > 0) {
|
||||
DEBUG("Saving app settings: %s\n", file.c_str());
|
||||
return writeStringToFile(file, out.str());
|
||||
if (writeStringToFile(file, out.str())) {
|
||||
string dir = parentDir(file);
|
||||
if (!syncDir(dir)) {
|
||||
ERROR("Failed to sync dir: %s\n", dir.c_str());
|
||||
// Note: Even if syncDir fails, the app settings have been
|
||||
// written, so have save() return true.
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
DEBUG("Empty app settings: %s\n", file.c_str());
|
||||
return unlink(file.c_str()) == 0 || errno == ENOENT;
|
||||
|
@ -112,6 +112,31 @@ bool writeStringToFile(string const& filename, string const& data) {
|
||||
return ok;
|
||||
}
|
||||
|
||||
constexpr int dirOpenFlags =
|
||||
#ifdef O_DIRECTORY
|
||||
O_DIRECTORY | O_RDONLY; // Linux specific
|
||||
#else
|
||||
O_RDONLY;
|
||||
#endif
|
||||
|
||||
bool syncDir(string const& dirname)
|
||||
{
|
||||
int fd = open(dirname.c_str(), dirOpenFlags);
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = fsync(fd) == 0;
|
||||
|
||||
while (close(fd)) {
|
||||
if (errno != EINTR) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
string parentDir(string const& dir) {
|
||||
// Note that size() is unsigned, so for short strings the '- 2' wraps
|
||||
// around and as a result the entire string is searched, which is fine.
|
||||
|
@ -57,6 +57,12 @@ std::string readFileAsString(std::string const& filename);
|
||||
*/
|
||||
bool writeStringToFile(std::string const& filename, std::string const& data);
|
||||
|
||||
/**
|
||||
* Tells the file system to commit the given directory to disk.
|
||||
* @return True iff the sync was successful.
|
||||
*/
|
||||
bool syncDir(std::string const& dirname);
|
||||
|
||||
std::string strreplace(std::string orig, const std::string &search, const std::string &replace);
|
||||
std::string cmdclean(std::string cmdline);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user