diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp index 8126cde76de..4845435f42c 100644 --- a/Userland/Libraries/LibCore/System.cpp +++ b/Userland/Libraries/LibCore/System.cpp @@ -1315,6 +1315,32 @@ ErrorOr recvfrom(int sockfd, void* buffer, size_t buffer_length, int fl return received; } +ErrorOr getaddrinfo(char const* nodename, char const* servname, struct addrinfo const& hints) +{ + struct addrinfo* results = nullptr; + + int const rc = ::getaddrinfo(nodename, servname, &hints, &results); + if (rc != 0) { + if (rc == EAI_SYSTEM) { + return Error::from_syscall("getaddrinfo"sv, -errno); + } + + auto const* error_string = gai_strerror(rc); + return Error::from_string_view({ error_string, strlen(error_string) }); + } + + Vector addresses; + + for (auto* result = results; result != nullptr; result = result->ai_next) + TRY(addresses.try_append(*result)); + + return AddressInfoVector { move(addresses), results, + [](struct addrinfo* ptr) { + if (ptr) + ::freeaddrinfo(ptr); + } }; +} + ErrorOr getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size) { if (::getsockopt(sockfd, level, option, value, value_size) < 0) diff --git a/Userland/Libraries/LibCore/System.h b/Userland/Libraries/LibCore/System.h index bcc6bb4dbe9..542f8d23c69 100644 --- a/Userland/Libraries/LibCore/System.h +++ b/Userland/Libraries/LibCore/System.h @@ -9,10 +9,14 @@ #pragma once #include +#include +#include #include +#include #include #include #include +#include #include #include #include @@ -210,6 +214,30 @@ ErrorOr access(StringView pathname, int mode); ErrorOr readlink(StringView pathname); ErrorOr poll(Span, int timeout); +class AddressInfoVector { + AK_MAKE_NONCOPYABLE(AddressInfoVector); + +public: + AddressInfoVector(AddressInfoVector&&) = default; + ~AddressInfoVector() = default; + + Span addresses() const { return m_addresses; } + +private: + friend ErrorOr getaddrinfo(char const* nodename, char const* servname, struct addrinfo const& hints); + + AddressInfoVector(Vector&& addresses, struct addrinfo* ptr, AK::Function deleter) + : m_addresses(move(addresses)) + , m_ptr(ptr, move(deleter)) + { + } + + Vector m_addresses {}; + OwnPtrWithCustomDeleter m_ptr; +}; + +ErrorOr getaddrinfo(char const* nodename, char const* servname, struct addrinfo const& hints); + #ifdef AK_OS_SERENITY ErrorOr posix_fallocate(int fd, off_t offset, off_t length); #endif