copy to a temp file then rename it this is the best we can do under the POSIX standard
| 580 | // copy to a temp file then rename it |
| 581 | // this is the best we can do under the POSIX standard |
| 582 | bool copyFile(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { |
| 583 | auto pair = createUniqueTempFile("MMKV"); |
| 584 | auto tmpFD = pair.second; |
| 585 | auto &tmpPath = pair.first; |
| 586 | if (tmpFD < 0) { |
| 587 | return false; |
| 588 | } |
| 589 | |
| 590 | bool renamed = false; |
| 591 | if (copyFileContent(srcPath, tmpFD, false)) { |
| 592 | MMKVInfo("copyfile [%s] to [%s]", srcPath.c_str(), tmpPath.c_str()); |
| 593 | renamed = tryAtomicRename(tmpPath, dstPath); |
| 594 | if (!renamed) { |
| 595 | MMKVInfo("rename fail, try copy file content instead."); |
| 596 | if (copyFileContent(tmpPath, dstPath)) { |
| 597 | renamed = true; |
| 598 | ::unlink(tmpPath.c_str()); |
| 599 | } |
| 600 | } |
| 601 | if (renamed) { |
| 602 | MMKVInfo("copyfile [%s] to [%s] finish.", srcPath.c_str(), dstPath.c_str()); |
| 603 | } |
| 604 | } |
| 605 | |
| 606 | ::close(tmpFD); |
| 607 | if (!renamed) { |
| 608 | ::unlink(tmpPath.c_str()); |
| 609 | } |
| 610 | return renamed; |
| 611 | } |
| 612 | |
| 613 | bool copyFileContent(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) { |
| 614 | File dstFile(dstPath, OpenFlag::WriteOnly | OpenFlag::Create | OpenFlag::Truncate); |
no test coverage detected