fix tryAtomicRename() with src == dst bug

This commit is contained in:
guoling
2024-12-02 15:15:18 +08:00
parent 8d6377667c
commit 20b68dbc71
4 changed files with 19 additions and 12 deletions
+2 -2
View File
@@ -226,7 +226,7 @@ class MMKV {
void notifyContentChanged();
#if defined(MMKV_ANDROID) && !defined(MMKV_DISABLE_CRYPT)
void checkReSetCryptKey(int fd, int metaFD, std::string *cryptKey);
void checkReSetCryptKey(int fd, int metaFD, const std::string *cryptKey);
#endif
static bool backupOneToDirectory(const std::string &mmapKey, const MMKVPath_t &dstPath, const MMKVPath_t &srcPath, bool compareFullPath);
static size_t backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t &srcDir, bool isInSpecialDir);
@@ -591,5 +591,5 @@ bool MMKV::getVector(MMKVKey_t key, T &result) {
MMKV_NAMESPACE_END
#endif
#endif // __cplusplus
#endif // MMKV_MMKV_H
+7 -7
View File
@@ -39,11 +39,11 @@ using namespace mmkv;
extern unordered_map<string, MMKV *> *g_instanceDic;
extern ThreadLock *g_instanceLock;
MMKV::MMKV(const string &mmapID, int size, MMKVMode mode, string *cryptKey, string *rootPath, size_t expectedCapacity)
MMKV::MMKV(const string &mmapID, int size, MMKVMode mode, const string *cryptKey, const string *rootPath, size_t expectedCapacity)
: m_mmapID((mode & MMKV_BACKUP) ? mmapID : mmapedKVKey(mmapID, rootPath)) // historically Android mistakenly use mmapKey as mmapID
, m_mode(mode)
, m_path(mappedKVPathWithID(m_mmapID, mode, rootPath))
, m_crcPath(crcPathWithID(m_mmapID, mode, rootPath))
, m_crcPath(crcPathWithPath(m_path))
, m_dic(nullptr)
, m_dicCrypt(nullptr)
, m_expectedCapacity(std::max<size_t>(DEFAULT_MMAP_SIZE, roundUp<size_t>(expectedCapacity, DEFAULT_MMAP_SIZE)))
@@ -88,11 +88,11 @@ MMKV::MMKV(const string &mmapID, int size, MMKVMode mode, string *cryptKey, stri
}*/
}
MMKV::MMKV(const string &mmapID, int ashmemFD, int ashmemMetaFD, string *cryptKey)
MMKV::MMKV(const string &mmapID, int ashmemFD, int ashmemMetaFD, const string *cryptKey)
: m_mmapID(mmapID)
, m_mode(MMKV_ASHMEM)
, m_path(mappedKVPathWithID(m_mmapID, MMKV_ASHMEM, nullptr))
, m_crcPath(crcPathWithID(m_mmapID, MMKV_ASHMEM, nullptr))
, m_crcPath(crcPathWithPath(m_path))
, m_dic(nullptr)
, m_dicCrypt(nullptr)
, m_file(new MemoryFile(ashmemFD))
@@ -137,7 +137,7 @@ MMKV::MMKV(const string &mmapID, int ashmemFD, int ashmemMetaFD, string *cryptKe
}*/
}
MMKV *MMKV::mmkvWithID(const string &mmapID, int size, MMKVMode mode, string *cryptKey, string *rootPath, size_t expectedCapacity) {
MMKV *MMKV::mmkvWithID(const string &mmapID, int size, MMKVMode mode, const string *cryptKey, const string *rootPath, size_t expectedCapacity) {
if (mmapID.empty() || !g_instanceLock) {
return nullptr;
}
@@ -162,7 +162,7 @@ MMKV *MMKV::mmkvWithID(const string &mmapID, int size, MMKVMode mode, string *cr
return kv;
}
MMKV *MMKV::mmkvWithAshmemFD(const string &mmapID, int fd, int metaFD, string *cryptKey) {
MMKV *MMKV::mmkvWithAshmemFD(const string &mmapID, int fd, int metaFD, const string *cryptKey) {
if (fd < 0 || !g_instanceLock) {
return nullptr;
@@ -191,7 +191,7 @@ int MMKV::ashmemMetaFD() {
}
# ifndef MMKV_DISABLE_CRYPT
void MMKV::checkReSetCryptKey(int fd, int metaFD, string *cryptKey) {
void MMKV::checkReSetCryptKey(int fd, int metaFD, const string *cryptKey) {
SCOPED_LOCK(m_lock);
checkReSetCryptKey(cryptKey);
+4 -1
View File
@@ -72,6 +72,10 @@ bool tryAtomicRename(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
MMKVWarning("fail on syscall(SYS_renameat2) [%s] to [%s], %d(%s)", srcPath.c_str(), dstPath.c_str(), errno,
strerror(errno));
}
if (renamed && (srcPath != dstPath)) {
::unlink(srcPath.c_str());
}
#endif // SYS_renameat2 && !MMKV_OHOS
if (!renamed) {
@@ -81,7 +85,6 @@ bool tryAtomicRename(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
}
}
::unlink(srcPath.c_str());
return true;
}
+6 -2
View File
@@ -58,6 +58,9 @@ void tryResetFileProtection(const string &path) {
namespace mmkv {
bool tryAtomicRename(const char *src, const char *dst) {
if (!src || !dst) {
return false;
}
bool renamed = false;
// try atomic swap first
@@ -65,6 +68,9 @@ bool tryAtomicRename(const char *src, const char *dst) {
// renameat2() equivalent
if (renamex_np(src, dst, RENAME_SWAP) == 0) {
renamed = true;
if (strcmp(src, dst) != 0) {
::unlink(src);
}
} else if (errno != ENOENT) {
MMKVError("fail to renamex_np %s to %s, %s", src, dst, strerror(errno));
}
@@ -78,8 +84,6 @@ bool tryAtomicRename(const char *src, const char *dst) {
}
}
::unlink(src);
return true;
}