do it by sendfile()
| 88 | |
| 89 | // do it by sendfile() |
| 90 | bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD, bool needTruncate) { |
| 91 | if (dstFD < 0) { |
| 92 | return false; |
| 93 | } |
| 94 | File srcFile(srcPath, OpenFlag::ReadOnly); |
| 95 | if (!srcFile.isFileValid()) { |
| 96 | return false; |
| 97 | } |
| 98 | auto srcFileSize = srcFile.getActualFileSize(); |
| 99 | |
| 100 | lseek(dstFD, 0, SEEK_SET); |
| 101 | auto writtenSize = ::sendfile(dstFD, srcFile.getFd(), nullptr, srcFileSize); |
| 102 | auto ret = (writtenSize == srcFileSize); |
| 103 | if (!ret) { |
| 104 | if (writtenSize < 0) { |
| 105 | MMKVError("fail to sendfile() %s to fd[%d], %d(%s)", srcPath.c_str(), dstFD, errno, strerror(errno)); |
| 106 | } else { |
| 107 | MMKVError("sendfile() %s to fd[%d], written %lld < %zu", srcPath.c_str(), dstFD, writtenSize, srcFileSize); |
| 108 | } |
| 109 | } else if (needTruncate) { |
| 110 | size_t dstFileSize = 0; |
| 111 | getFileSize(dstFD, dstFileSize); |
| 112 | if ((dstFileSize != srcFileSize) && (::ftruncate(dstFD, static_cast<off_t>(srcFileSize)) != 0)) { |
| 113 | MMKVError("fail to truncate [%d] to size [%zu], %d(%s)", dstFD, srcFileSize, errno, strerror(errno)); |
| 114 | ret = false; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | if (ret) { |
| 119 | MMKVInfo("copy content from %s to fd[%d] finish", srcPath.c_str(), dstFD); |
| 120 | } |
| 121 | return ret; |
| 122 | } |
| 123 | |
| 124 | } // namespace mmkv |
| 125 |
nothing calls this directly
no test coverage detected