Skip to content

Commit

Permalink
AK: Add a ScopeGuard helper that invokes a callback when destroyed.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
awesomekling committed Jun 7, 2019
1 parent 4edc73a commit 69a6ce9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 14 deletions.
24 changes: 24 additions & 0 deletions AK/ScopeGuard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

namespace AK {

template<typename Callback>
class ScopeGuard {
public:
ScopeGuard(Callback callback)
: m_callback(move(callback))
{
}

~ScopeGuard()
{
m_callback();
}

private:
Callback m_callback;
};

}

using AK::ScopeGuard;
30 changes: 16 additions & 14 deletions LibC/netdb.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#include <AK/AKString.h>
#include <AK/Assertions.h>
#include <AK/ScopeGuard.h>
#include <Kernel/Net/IPv4.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <AK/Assertions.h>
#include <AK/AKString.h>
#include <Kernel/Net/IPv4.h>

extern "C" {

Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -150,15 +155,13 @@ 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) {
// Strip newline.
buffer[nrecv - 1] = '\0';
}
buffer[nrecv] = '\0';
close(fd);

if (!memcmp(buffer, "Not found.", sizeof("Not found.") - 1))
return nullptr;
Expand All @@ -175,5 +178,4 @@ hostent* gethostbyaddr(const void* addr, socklen_t addr_size, int type)

return &__gethostbyaddr_buffer;
}

}

0 comments on commit 69a6ce9

Please sign in to comment.