///////////////////////////////////////////////////////
| 929 | |
| 930 | //////////////////////////////////////////////////////////// |
| 931 | Sftp::ListingResult Sftp::getDirectoryListing(const std::filesystem::path& path, const TimeoutWithPredicate& timeout) |
| 932 | { |
| 933 | LIBSSH2_SFTP_HANDLE* handle{}; |
| 934 | |
| 935 | { |
| 936 | const auto pathString = pathToUtf8(path); |
| 937 | const auto result = m_impl->waitForOperationComplete( |
| 938 | [&] |
| 939 | { |
| 940 | handle = libssh2_sftp_open_ex(m_impl->sftpSession.get(), |
| 941 | pathString.data(), |
| 942 | static_cast<unsigned int>(pathString.size()), |
| 943 | 0, |
| 944 | 0, |
| 945 | LIBSSH2_SFTP_OPENDIR); |
| 946 | |
| 947 | if (handle) |
| 948 | return LIBSSH2_ERROR_NONE; |
| 949 | |
| 950 | return libssh2_session_last_errno(m_impl->ssh2Session.get()); |
| 951 | }, |
| 952 | timeout); |
| 953 | |
| 954 | if (result == LIBSSH2_ERROR_EAGAIN) |
| 955 | return {Result(Result::Value::Timeout), {}}; |
| 956 | |
| 957 | if (!handle) |
| 958 | return {makeError(m_impl->ssh2Session.get(), m_impl->sftpSession.get()), {}}; |
| 959 | } |
| 960 | |
| 961 | std::vector<Attributes> listing; |
| 962 | |
| 963 | { |
| 964 | std::array<char, 4096> buffer{}; |
| 965 | LIBSSH2_SFTP_ATTRIBUTES attributes{}; |
| 966 | |
| 967 | while (true) |
| 968 | { |
| 969 | const auto result = m_impl->waitForOperationComplete( |
| 970 | [&] { return libssh2_sftp_readdir_ex(handle, buffer.data(), buffer.size(), nullptr, 0, &attributes); }, |
| 971 | timeout); |
| 972 | |
| 973 | if (result > 0) |
| 974 | { |
| 975 | // The filename from libssh2 is UTF-8 encoded, convert before constructing filesystem::path |
| 976 | listing.emplace_back( |
| 977 | makeAttributes(path / pathFromUtf8({buffer.data(), static_cast<std::size_t>(result)}), attributes)); |
| 978 | |
| 979 | continue; |
| 980 | } |
| 981 | |
| 982 | if (result == LIBSSH2_ERROR_EAGAIN) |
| 983 | { |
| 984 | libssh2_sftp_close_handle(handle); |
| 985 | return {Result(Result::Value::Timeout), {}}; |
| 986 | } |
| 987 | |
| 988 | if (result == 0) |
nothing calls this directly
no test coverage detected