| 1368 | } |
| 1369 | |
| 1370 | bool FileSystem::CopyFilePath(const char* source, const char* destination, bool replace) |
| 1371 | { |
| 1372 | #ifndef _WIN32 |
| 1373 | // TODO: There's technically a race here between checking and opening the file.. |
| 1374 | // But fopen doesn't specify any way to say "don't create if it exists"... |
| 1375 | if (!replace && FileExists(destination)) |
| 1376 | return false; |
| 1377 | |
| 1378 | auto in_fp = OpenManagedCFile(source, "rb"); |
| 1379 | if (!in_fp) |
| 1380 | return false; |
| 1381 | |
| 1382 | auto out_fp = OpenManagedCFile(destination, "wb"); |
| 1383 | if (!out_fp) |
| 1384 | return false; |
| 1385 | |
| 1386 | u8 buf[4096]; |
| 1387 | while (!std::feof(in_fp.get())) |
| 1388 | { |
| 1389 | size_t bytes_in = std::fread(buf, 1, sizeof(buf), in_fp.get()); |
| 1390 | if ((bytes_in == 0 && !std::feof(in_fp.get())) || |
| 1391 | (bytes_in > 0 && std::fwrite(buf, 1, bytes_in, out_fp.get()) != bytes_in)) |
| 1392 | { |
| 1393 | out_fp.reset(); |
| 1394 | DeleteFilePath(destination); |
| 1395 | return false; |
| 1396 | } |
| 1397 | } |
| 1398 | |
| 1399 | if (std::fflush(out_fp.get()) != 0) |
| 1400 | { |
| 1401 | out_fp.reset(); |
| 1402 | DeleteFilePath(destination); |
| 1403 | return false; |
| 1404 | } |
| 1405 | |
| 1406 | return true; |
| 1407 | #else |
| 1408 | return CopyFileW(GetWin32Path(source).c_str(), GetWin32Path(destination).c_str(), !replace); |
| 1409 | #endif |
| 1410 | } |
| 1411 | |
| 1412 | #ifdef _WIN32 |
| 1413 | |