aboutsummaryrefslogtreecommitdiff
path: root/src/Storage.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-04-20 13:11:59 +0200
committerdec05eba <dec05eba@protonmail.com>2021-04-20 13:11:59 +0200
commitc1db97f057e8f20aa26a2342da94eeff1d7a7725 (patch)
treeb795e75ba14bb2b9cab0fbc6aad01cd76b892939 /src/Storage.cpp
parent5465c09cd108e37720dbad139de98bdcf5dfe8bf (diff)
Proper atomic rename? also do not generate mipmap for manga
Diffstat (limited to 'src/Storage.cpp')
-rw-r--r--src/Storage.cpp62
1 files changed, 18 insertions, 44 deletions
diff --git a/src/Storage.cpp b/src/Storage.cpp
index 1e9f206..6a98267 100644
--- a/src/Storage.cpp
+++ b/src/Storage.cpp
@@ -1,5 +1,4 @@
#include "../include/Storage.hpp"
-#include "../include/env.hpp"
#include "../include/StringUtils.hpp"
#include <stdio.h>
#include <assert.h>
@@ -10,13 +9,11 @@
#include <rapidjson/stringbuffer.h>
#include <unordered_set>
-#if OS_FAMILY == OS_FAMILY_POSIX
#include <pwd.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
-#endif
static int makedir(const char *path) {
return mkdir(path, S_IRWXU);
@@ -25,7 +22,6 @@ static int makedir(const char *path) {
namespace QuickMedia {
Path get_home_dir()
{
- #if OS_FAMILY == OS_FAMILY_POSIX
const char *homeDir = getenv("HOME");
if(!homeDir)
{
@@ -37,26 +33,6 @@ namespace QuickMedia {
abort();
}
return homeDir;
- #elif OS_FAMILY == OS_FAMILY_WINDOWS
- BOOL ret;
- HANDLE hToken;
- std::wstring homeDir;
- DWORD homeDirLen = MAX_PATH;
- homeDir.resize(homeDirLen);
-
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken))
- throw std::runtime_error("Failed to open process token");
-
- if (!GetUserProfileDirectory(hToken, &homeDir[0], &homeDirLen))
- {
- CloseHandle(hToken);
- throw std::runtime_error("Failed to get home directory");
- }
-
- CloseHandle(hToken);
- homeDir.resize(wcslen(homeDir.c_str()));
- return boost::filesystem::path(homeDir);
- #endif
}
Path get_storage_dir() {
@@ -167,7 +143,7 @@ namespace QuickMedia {
int res = file_overwrite(tmp_path, data.c_str(), data.size());
if(res != 0)
return res;
- return rename(tmp_path.data.c_str(), path.data.c_str());
+ return rename_atomic(tmp_path.data.c_str(), path.data.c_str());
}
void for_files_in_dir(const Path &path, FileIteratorCallback callback) {
@@ -230,20 +206,8 @@ namespace QuickMedia {
}
bool save_json_to_file_atomic(const Path &path, const Json::Value &json) {
- Path tmp_path = path;
- tmp_path.append(".tmp");
-
Json::StreamWriterBuilder json_builder;
- if(file_overwrite(tmp_path, Json::writeString(json_builder, json)) != 0)
- return false;
-
- // Rename is atomic under posix!
- if(rename(tmp_path.data.c_str(), path.data.c_str()) != 0) {
- perror("save_json_to_file_atomic rename");
- return false;
- }
-
- return true;
+ return file_overwrite_atomic(path, Json::writeString(json_builder, json)) == 0;
}
bool save_json_to_file_atomic(const Path &path, const rapidjson::Value &json) {
@@ -254,17 +218,27 @@ namespace QuickMedia {
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
json.Accept(writer);
- Json::StreamWriterBuilder json_builder;
if(file_overwrite(tmp_path, buffer.GetString(), buffer.GetSize()) != 0)
return false;
- // Rename is atomic under posix!
- if(rename(tmp_path.data.c_str(), path.data.c_str()) != 0) {
- perror("save_json_to_file_atomic rename");
- return false;
+ return rename_atomic(tmp_path.data.c_str(), path.data.c_str()) == 0;
+ }
+
+ int rename_atomic(const char *oldpath, const char *newpath) {
+ int fd = open(oldpath, O_RDONLY);
+ if(fd == -1) {
+ perror(oldpath);
+ return -1;
}
- return true;
+ if(fsync(fd) == -1) {
+ perror(oldpath);
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+ return rename(oldpath, newpath);
}
bool is_program_executable_by_name(const char *name) {