| 203 | } |
| 204 | |
| 205 | bool IsSameFileUtf8(const std::string& first, const std::string& second) { |
| 206 | #ifdef _WIN32 |
| 207 | const std::wstring wideFirst = internal::WideFromUtf8(first); |
| 208 | const std::wstring wideSecond = internal::WideFromUtf8(second); |
| 209 | |
| 210 | HANDLE firstHandle = |
| 211 | CreateFileW(wideFirst.c_str(), 0, |
| 212 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 213 | nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); |
| 214 | if (firstHandle == INVALID_HANDLE_VALUE) { |
| 215 | return false; |
| 216 | } |
| 217 | HANDLE secondHandle = |
| 218 | CreateFileW(wideSecond.c_str(), 0, |
| 219 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 220 | nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); |
| 221 | if (secondHandle == INVALID_HANDLE_VALUE) { |
| 222 | CloseHandle(firstHandle); |
| 223 | return false; |
| 224 | } |
| 225 | |
| 226 | BY_HANDLE_FILE_INFORMATION firstInfo = {}; |
| 227 | BY_HANDLE_FILE_INFORMATION secondInfo = {}; |
| 228 | const bool success = |
| 229 | GetFileInformationByHandle(firstHandle, &firstInfo) != 0 && |
| 230 | GetFileInformationByHandle(secondHandle, &secondInfo) != 0; |
| 231 | CloseHandle(secondHandle); |
| 232 | CloseHandle(firstHandle); |
| 233 | |
| 234 | if (!success) { |
| 235 | return false; |
| 236 | } |
| 237 | return firstInfo.dwVolumeSerialNumber == secondInfo.dwVolumeSerialNumber && |
| 238 | firstInfo.nFileIndexHigh == secondInfo.nFileIndexHigh && |
| 239 | firstInfo.nFileIndexLow == secondInfo.nFileIndexLow; |
| 240 | #else |
| 241 | struct stat firstStat; |
| 242 | struct stat secondStat; |
| 243 | if (stat(first.c_str(), &firstStat) != 0 || |
| 244 | stat(second.c_str(), &secondStat) != 0) { |
| 245 | return false; |
| 246 | } |
| 247 | return firstStat.st_dev == secondStat.st_dev && |
| 248 | firstStat.st_ino == secondStat.st_ino; |
| 249 | #endif |
| 250 | } |
| 251 | |
| 252 | int PreserveMetadataUtf8(const std::string& source, |
| 253 | const std::string& target) { |
no test coverage detected