From c1db97f057e8f20aa26a2342da94eeff1d7a7725 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 20 Apr 2021 13:11:59 +0200 Subject: Proper atomic rename? also do not generate mipmap for manga --- src/Storage.cpp | 62 +++++++++++++++++---------------------------------------- 1 file changed, 18 insertions(+), 44 deletions(-) (limited to 'src/Storage.cpp') 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 #include @@ -10,13 +9,11 @@ #include #include -#if OS_FAMILY == OS_FAMILY_POSIX #include #include #include #include #include -#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 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) { -- cgit v1.2.3