///////////////////////////////////////////////////////
| 1052 | |
| 1053 | //////////////////////////////////////////////////////////// |
| 1054 | Sftp::Result Sftp::rename(const std::filesystem::path& oldPath, |
| 1055 | const std::filesystem::path& newPath, |
| 1056 | bool overwrite, |
| 1057 | const TimeoutWithPredicate& timeout) |
| 1058 | { |
| 1059 | const auto oldPathString = pathToUtf8(oldPath); |
| 1060 | const auto newPathString = pathToUtf8(newPath); |
| 1061 | |
| 1062 | // POSIX rename is only supported starting from libssh2 1.11.1 |
| 1063 | #if (LIBSSH2_VERSION_NUM >= 0x010b01) |
| 1064 | // POSIX rename doesn't support not overwriting |
| 1065 | auto usePosix = overwrite && m_impl->posixRenameSupported; |
| 1066 | #endif |
| 1067 | |
| 1068 | while (true) |
| 1069 | { |
| 1070 | const auto result = m_impl->waitForOperationComplete( |
| 1071 | [&] |
| 1072 | { |
| 1073 | #if (LIBSSH2_VERSION_NUM >= 0x010b01) |
| 1074 | if (usePosix) |
| 1075 | { |
| 1076 | return libssh2_sftp_posix_rename_ex(m_impl->sftpSession.get(), |
| 1077 | oldPathString.data(), |
| 1078 | static_cast<unsigned int>(oldPathString.size()), |
| 1079 | newPathString.data(), |
| 1080 | static_cast<unsigned int>(newPathString.size())); |
| 1081 | } |
| 1082 | #endif |
| 1083 | |
| 1084 | return libssh2_sftp_rename_ex(m_impl->sftpSession.get(), |
| 1085 | oldPathString.data(), |
| 1086 | static_cast<unsigned int>(oldPathString.size()), |
| 1087 | newPathString.data(), |
| 1088 | static_cast<unsigned int>(newPathString.size()), |
| 1089 | overwrite ? LIBSSH2_SFTP_RENAME_OVERWRITE : 0); |
| 1090 | }, |
| 1091 | timeout); |
| 1092 | |
| 1093 | if (result == LIBSSH2_ERROR_EAGAIN) |
| 1094 | return Result(Result::Value::Timeout); |
| 1095 | |
| 1096 | #if (LIBSSH2_VERSION_NUM >= 0x010b01) |
| 1097 | // Retry using normal rename if we find out POSIX rename isn't supported |
| 1098 | if (usePosix && (result == LIBSSH2_FX_OP_UNSUPPORTED)) |
| 1099 | { |
| 1100 | m_impl->posixRenameSupported = false; |
| 1101 | usePosix = false; |
| 1102 | continue; |
| 1103 | } |
| 1104 | #endif |
| 1105 | |
| 1106 | if (result < 0) |
| 1107 | return makeError(m_impl->ssh2Session.get(), m_impl->sftpSession.get()); |
| 1108 | |
| 1109 | return Result(Result::Value::Success); |
| 1110 | } |
| 1111 | } |
no test coverage detected