| 1542 | #endif |
| 1543 | |
| 1544 | cmSystemTools::CopyResult cmSystemTools::CopySingleFile( |
| 1545 | std::string const& oldname, std::string const& newname, CopyWhen when, |
| 1546 | CopyInputRecent inputRecent, std::string* err) |
| 1547 | { |
| 1548 | switch (when) { |
| 1549 | case CopyWhen::Always: |
| 1550 | break; |
| 1551 | case CopyWhen::OnlyIfDifferent: |
| 1552 | if (!FilesDiffer(oldname, newname)) { |
| 1553 | return CopyResult::Success; |
| 1554 | } |
| 1555 | break; |
| 1556 | case CopyWhen::OnlyIfNewer: { |
| 1557 | if (!SystemTools::FileExists(newname)) { |
| 1558 | break; |
| 1559 | } |
| 1560 | int timeResult = 0; |
| 1561 | cmsys::Status timeStatus = |
| 1562 | cmsys::SystemTools::FileTimeCompare(oldname, newname, &timeResult); |
| 1563 | if (timeStatus.IsSuccess() && timeResult <= 0) { |
| 1564 | return CopyResult::Success; |
| 1565 | } |
| 1566 | break; |
| 1567 | } |
| 1568 | } |
| 1569 | |
| 1570 | mode_t perm = 0; |
| 1571 | cmsys::Status perms = SystemTools::GetPermissions(oldname, perm); |
| 1572 | |
| 1573 | // If files are the same do not copy |
| 1574 | if (SystemTools::SameFile(oldname, newname)) { |
| 1575 | return CopyResult::Success; |
| 1576 | } |
| 1577 | |
| 1578 | cmsys::SystemTools::CopyStatus status; |
| 1579 | status = cmsys::SystemTools::CloneFileContent(oldname, newname); |
| 1580 | if (!status) { |
| 1581 | // if cloning did not succeed, fall back to blockwise copy |
| 1582 | #ifdef _WIN32 |
| 1583 | if (inputRecent == CopyInputRecent::Yes) { |
| 1584 | // Windows sometimes locks a file immediately after creation. |
| 1585 | // Retry a few times. |
| 1586 | WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry(); |
| 1587 | while ((status = |
| 1588 | cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname), |
| 1589 | status.Path == cmsys::SystemTools::CopyStatus::SourcePath && |
| 1590 | status.GetPOSIX() == EACCES && --retry.Count)) { |
| 1591 | cmSystemTools::Delay(retry.Delay); |
| 1592 | } |
| 1593 | } else { |
| 1594 | status = cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname); |
| 1595 | } |
| 1596 | #else |
| 1597 | static_cast<void>(inputRecent); |
| 1598 | status = cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname); |
| 1599 | #endif |
| 1600 | } |
| 1601 | if (!status) { |
nothing calls this directly
no test coverage detected