// be the next one.
int last_open_socket = findLastSocketFd();
+ // Fill holes.
+ fillFdHoles holes(last_open_socket);
+
// Connect to the host backend.
ASSERT_NO_THROW(HostMgr::addBackend(validConnectString()));
return (last_socket);
}
-}; // namespace test
-}; // namespace dhcp
-}; // namespace isc
+fillFdHoles::fillFdHoles(int limit) : fds_() {
+ if (limit <= 0) {
+ return;
+ }
+ for (;;) {
+ int fd = open("/dev/null", O_RDWR, 0);
+ if (fd == -1) {
+ return;
+ }
+ if (fd < limit) {
+ fds_.push_front(fd);
+ } else {
+ static_cast<void>(close(fd));
+ return;
+ }
+ }
+}
+
+fillFdHoles::~fillFdHoles() {
+ while (!fds_.empty()) {
+ static_cast<void>(close(fds_.back()));
+ fds_.pop_back();
+ }
+}
+
+} // namespace test
+} // namespace dhcp
+} // namespace isc
-// Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
#define LIBDHCPSRV_TEST_UTILS_H
#include <dhcpsrv/lease_mgr.h>
+#include <list>
#include <vector>
namespace isc {
/// are none.
int findLastSocketFd();
+/// @brief RAII tool which fills holes in the file descriptor sequence
+///
+/// The @ref findLastSocketFd requires new socket descriptors are allocated
+/// after the last open socket descriptor so there is no hole i.e. a free
+/// file descriptor in the sequence.
+/// This tool detects and fills such holes. It uses the RAII idiom to avoid
+/// file descriptor leaks: the destructor called when the object goes out
+/// of scope closes all file descriptors which were opened by the constructor.
+class fillFdHoles {
+public:
+ /// @brief Constructor
+ ///
+ /// @param limit Holes will be filled up to this limit
+ fillFdHoles(int limit);
+
+ /// @brief Destructor
+ ///
+ /// The destructor closes members of the list
+ ~fillFdHoles();
+
+private:
+ /// @brief The list of holes
+ std::list<int> fds_;
+};
-}; // namespace test
-}; // namespace dhcp
-}; // namespace isc
+} // namespace test
+} // namespace dhcp
+} // namespace isc
#endif