From 69a6ce90df7e0f074a714e0938cfd526076e38a3 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 7 Jun 2019 09:18:21 +0200 Subject: [PATCH] AK: Add a ScopeGuard helper that invokes a callback when destroyed. This is useful when you want to ensure some little thing happens when you exit a certain scope. This patch makes use of it in LibC's netdb code to make sure we close the connection to the LookupServer. --- AK/ScopeGuard.h | 24 ++++++++++++++++++++++++ LibC/netdb.cpp | 30 ++++++++++++++++-------------- 2 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 AK/ScopeGuard.h diff --git a/AK/ScopeGuard.h b/AK/ScopeGuard.h new file mode 100644 index 0000000000..44556e0ee6 --- /dev/null +++ b/AK/ScopeGuard.h @@ -0,0 +1,24 @@ +#pragma once + +namespace AK { + +template +class ScopeGuard { +public: + ScopeGuard(Callback callback) + : m_callback(move(callback)) + { + } + + ~ScopeGuard() + { + m_callback(); + } + +private: + Callback m_callback; +}; + +} + +using AK::ScopeGuard; diff --git a/LibC/netdb.cpp b/LibC/netdb.cpp index 2826027b5b..3376269223 100644 --- a/LibC/netdb.cpp +++ b/LibC/netdb.cpp @@ -1,12 +1,13 @@ +#include +#include +#include +#include +#include #include +#include #include #include -#include -#include #include -#include -#include -#include extern "C" { @@ -73,11 +74,15 @@ hostent* gethostbyname(const char* name) if (fd < 0) return nullptr; + auto close_fd_on_exit = ScopeGuard([fd] { + dbgprintf("closing fd\n"); + close(fd); + }); + auto line = String::format("L%s\n", name); int nsent = write(fd, line.characters(), line.length()); if (nsent < 0) { perror("write"); - close(fd); return nullptr; } @@ -87,11 +92,9 @@ hostent* gethostbyname(const char* name) int nrecv = read(fd, buffer, sizeof(buffer) - 1); if (nrecv < 0) { perror("recv"); - close(fd); return nullptr; } buffer[nrecv] = '\0'; - close(fd); if (!memcmp(buffer, "Not found.", sizeof("Not found.") - 1)) return nullptr; @@ -129,18 +132,20 @@ hostent* gethostbyaddr(const void* addr, socklen_t addr_size, int type) if (fd < 0) return nullptr; + auto close_fd_on_exit = ScopeGuard([fd] { + close(fd); + }); + IPv4Address ipv4_address((const byte*)&((const in_addr*)addr)->s_addr); auto line = String::format("R%d.%d.%d.%d.in-addr.arpa\n", ipv4_address[3], ipv4_address[2], ipv4_address[1], - ipv4_address[0] - ); + ipv4_address[0]); int nsent = write(fd, line.characters(), line.length()); if (nsent < 0) { perror("write"); - close(fd); return nullptr; } @@ -150,7 +155,6 @@ hostent* gethostbyaddr(const void* addr, socklen_t addr_size, int type) int nrecv = read(fd, buffer, sizeof(buffer) - 1); if (nrecv < 0) { perror("recv"); - close(fd); return nullptr; } if (nrecv > 1) { @@ -158,7 +162,6 @@ hostent* gethostbyaddr(const void* addr, socklen_t addr_size, int type) buffer[nrecv - 1] = '\0'; } buffer[nrecv] = '\0'; - close(fd); if (!memcmp(buffer, "Not found.", sizeof("Not found.") - 1)) return nullptr; @@ -175,5 +178,4 @@ hostent* gethostbyaddr(const void* addr, socklen_t addr_size, int type) return &__gethostbyaddr_buffer; } - }