Selaa lähdekoodia

LibCore: Add a wrapper for `getaddrinfo()`

Lucas CHOLLET 2 vuotta sitten
vanhempi
commit
687ef7740a
2 muutettua tiedostoa jossa 54 lisäystä ja 0 poistoa
  1. 26 0
      Userland/Libraries/LibCore/System.cpp
  2. 28 0
      Userland/Libraries/LibCore/System.h

+ 26 - 0
Userland/Libraries/LibCore/System.cpp

@@ -1315,6 +1315,32 @@ ErrorOr<ssize_t> recvfrom(int sockfd, void* buffer, size_t buffer_length, int fl
     return received;
 }
 
+ErrorOr<AddressInfoVector> 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<struct addrinfo> 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<void> getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size)
 {
     if (::getsockopt(sockfd, level, option, value, value_size) < 0)

+ 28 - 0
Userland/Libraries/LibCore/System.h

@@ -9,10 +9,14 @@
 #pragma once
 
 #include <AK/Error.h>
+#include <AK/Noncopyable.h>
+#include <AK/OwnPtrWithCustomDeleter.h>
 #include <AK/StringView.h>
+#include <AK/Vector.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <grp.h>
+#include <netdb.h>
 #include <poll.h>
 #include <pwd.h>
 #include <signal.h>
@@ -210,6 +214,30 @@ ErrorOr<void> access(StringView pathname, int mode);
 ErrorOr<DeprecatedString> readlink(StringView pathname);
 ErrorOr<int> poll(Span<struct pollfd>, int timeout);
 
+class AddressInfoVector {
+    AK_MAKE_NONCOPYABLE(AddressInfoVector);
+
+public:
+    AddressInfoVector(AddressInfoVector&&) = default;
+    ~AddressInfoVector() = default;
+
+    Span<struct addrinfo const> addresses() const { return m_addresses; }
+
+private:
+    friend ErrorOr<AddressInfoVector> getaddrinfo(char const* nodename, char const* servname, struct addrinfo const& hints);
+
+    AddressInfoVector(Vector<struct addrinfo>&& addresses, struct addrinfo* ptr, AK::Function<void(struct addrinfo*)> deleter)
+        : m_addresses(move(addresses))
+        , m_ptr(ptr, move(deleter))
+    {
+    }
+
+    Vector<struct addrinfo> m_addresses {};
+    OwnPtrWithCustomDeleter<struct addrinfo> m_ptr;
+};
+
+ErrorOr<AddressInfoVector> getaddrinfo(char const* nodename, char const* servname, struct addrinfo const& hints);
+
 #ifdef AK_OS_SERENITY
 ErrorOr<void> posix_fallocate(int fd, off_t offset, off_t length);
 #endif