123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /*
- * Tencent is pleased to support the open source community by making
- * MMKV available.
- *
- * Copyright (C) 2019 THL A29 Limited, a Tencent company.
- * All rights reserved.
- *
- * Licensed under the BSD 3-Clause License (the "License"); you may not use
- * this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * https://opensource.org/licenses/BSD-3-Clause
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "MemoryFile.h"
- #include "MMKVLog.h"
- #ifdef MMKV_IOS
- using namespace std;
- namespace mmkv {
- void tryResetFileProtection(const string &path) {
- @autoreleasepool {
- NSString *nsPath = [NSString stringWithUTF8String:path.c_str()];
- NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:nsPath error:nullptr];
- NSString *protection = [attr valueForKey:NSFileProtectionKey];
- MMKVInfo("protection on [%@] is %@", nsPath, protection);
- if ([protection isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication] == NO) {
- NSMutableDictionary *newAttr = [NSMutableDictionary dictionaryWithDictionary:attr];
- [newAttr setObject:NSFileProtectionCompleteUntilFirstUserAuthentication forKey:NSFileProtectionKey];
- NSError *err = nil;
- [[NSFileManager defaultManager] setAttributes:newAttr ofItemAtPath:nsPath error:&err];
- if (err != nil) {
- MMKVError("fail to set attribute %@ on [%@]: %@", NSFileProtectionCompleteUntilFirstUserAuthentication,
- nsPath, err);
- }
- }
- }
- }
- } // namespace mmkv
- #endif // MMKV_IOS
- #ifdef MMKV_APPLE
- #include <copyfile.h>
- #include <mach/mach_time.h>
- namespace mmkv {
- bool tryAtomicRename(const char *src, const char *dst) {
- bool renamed = false;
- // try atomic swap first
- if (@available(iOS 10.0, watchOS 3.0, macOS 10.12, *)) {
- // renameat2() equivalent
- if (renamex_np(src, dst, RENAME_SWAP) == 0) {
- renamed = true;
- } else if (errno != ENOENT) {
- MMKVError("fail to renamex_np %s to %s, %s", src, dst, strerror(errno));
- }
- }
- if (!renamed) {
- // try old style rename
- if (rename(src, dst) != 0) {
- MMKVError("fail to rename %s to %s, %s", src, dst, strerror(errno));
- return false;
- }
- }
- unlink(src);
- return true;
- }
- bool copyFile(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
- // prepare a temp file for atomic rename, avoid data corruption of suddent crash
- NSString *uniqueFileName = [NSString stringWithFormat:@"mmkv_%llu", mach_absolute_time()];
- NSString *tmpFile = [NSTemporaryDirectory() stringByAppendingPathComponent:uniqueFileName];
- if (copyfile(srcPath.c_str(), tmpFile.UTF8String, nullptr, COPYFILE_UNLINK | COPYFILE_CLONE) != 0) {
- MMKVError("fail to copyfile [%s] to [%s], %s", srcPath.c_str(), tmpFile.UTF8String, strerror(errno));
- return false;
- }
- MMKVInfo("copyfile [%s] to [%s]", srcPath.c_str(), tmpFile.UTF8String);
- if (tryAtomicRename(tmpFile.UTF8String, dstPath.c_str())) {
- MMKVInfo("copyfile [%s] to [%s] finish.", srcPath.c_str(), dstPath.c_str());
- return true;
- }
- unlink(tmpFile.UTF8String);
- return false;
- }
- bool copyFileContent(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
- File dstFile(dstPath, OpenFlag::WriteOnly | OpenFlag::Create | OpenFlag::Truncate);
- if (!dstFile.isFileValid()) {
- return false;
- }
- if (copyFileContent(srcPath, dstFile.getFd())) {
- MMKVInfo("copy content from %s to fd[%s] finish", srcPath.c_str(), dstPath.c_str());
- return true;
- }
- MMKVError("fail to copyfile(): target file %s", dstPath.c_str());
- return false;
- }
- bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD) {
- if (dstFD < 0) {
- return false;
- }
- File srcFile(srcPath, OpenFlag::ReadOnly);
- if (!srcFile.isFileValid()) {
- return false;
- }
- // sendfile() equivalent
- if (::fcopyfile(srcFile.getFd(), dstFD, nullptr, COPYFILE_ACL | COPYFILE_STAT | COPYFILE_XATTR | COPYFILE_DATA) == 0) {
- MMKVInfo("copy content from %s to fd[%d] finish", srcPath.c_str(), dstFD);
- return true;
- }
- MMKVError("fail to copyfile(): %d(%s), source file %s", errno, strerror(errno), srcPath.c_str());
- return false;
- }
- bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD, bool needTruncate) {
- return copyFileContent(srcPath, dstFD);
- }
- } // namespace mmkv
- #endif // MMKV_APPLE
|