aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLexi Winter <lexi@hemlock.eden.le-fay.org>2025-03-29 07:07:53 +0000
committerLexi Winter <lexi@hemlock.eden.le-fay.org>2025-03-29 07:07:53 +0000
commit4a789145cfecc2fe63c5a1100e8a02b009c94144 (patch)
treee44728c9a8e44e30fd222bbe8567d884eeeb5405
parent661b39b557abc9891335d4106162c359f520434a (diff)
downloadlibnvxx-4a789145cfecc2fe63c5a1100e8a02b009c94144.tar.gz
libnvxx-4a789145cfecc2fe63c5a1100e8a02b009c94144.tar.bz2
add tests for send() and recv()
-rw-r--r--libnvxx/const_nv_list.cc7
-rw-r--r--libnvxx/nvxx_base.h2
-rw-r--r--libnvxx/tests/nvxx_basic.cc85
3 files changed, 90 insertions, 4 deletions
diff --git a/libnvxx/const_nv_list.cc b/libnvxx/const_nv_list.cc
index 22d3771..0098d60 100644
--- a/libnvxx/const_nv_list.cc
+++ b/libnvxx/const_nv_list.cc
@@ -116,10 +116,11 @@ __const_nv_list::send(int fd) const
{
__throw_if_error();
- if (::nvlist_send(fd, __m_nv) == 0)
- return;
+ if (auto ret = ::nvlist_send(fd, __m_nv); ret != 0)
+ throw std::system_error(
+ std::make_error_code(static_cast<std::errc>(errno)));
- throw std::system_error(error());
+ return;
}
void
diff --git a/libnvxx/nvxx_base.h b/libnvxx/nvxx_base.h
index 9eebb4e..07cd9e7 100644
--- a/libnvxx/nvxx_base.h
+++ b/libnvxx/nvxx_base.h
@@ -432,7 +432,7 @@ struct nv_list final
* Receive an nv_list from a file descriptor by calling nvlist_recv(),
* to which flags is passed. On failure, throws std::system_error.
*/
- [[nodiscard]] static auto recv(int, int) -> nv_list;
+ [[nodiscard]] static auto recv(int __fd, int __flags = 0) -> nv_list;
/*
* Send an nv_list over a file descriptor and receive another nv_list
diff --git a/libnvxx/tests/nvxx_basic.cc b/libnvxx/tests/nvxx_basic.cc
index 09b8976..31d2b11 100644
--- a/libnvxx/tests/nvxx_basic.cc
+++ b/libnvxx/tests/nvxx_basic.cc
@@ -11,6 +11,8 @@
#include <string>
#include <string_view>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <atf-c++.hpp>
#include "nvxx.h"
@@ -393,6 +395,84 @@ TEST_CASE(nvxx_unpack_range)
ATF_REQUIRE_EQ(value, nvl.get_number(key));
}
+TEST_CASE(nvxx_send_non_socket)
+{
+ using namespace std::literals;
+ auto constexpr key = "test"sv;
+ auto constexpr value = 42u;
+
+ auto nvl = bsd::nv_list();
+ nvl.add_number(key, value);
+
+ auto fds = std::array<int, 2>{};
+ auto ret = ::pipe(&fds[0]);
+ ATF_REQUIRE_EQ(0, ret);
+
+ bsd::nv_fd fd0(fds[0]);
+ bsd::nv_fd fd1(fds[1]);
+
+ ATF_REQUIRE_THROW(std::system_error, nvl.send(fd0.get()));
+
+ try {
+ nvl.send(fd0.get());
+ } catch (std::system_error const &exc) {
+ ATF_REQUIRE_EQ(true, exc.code().value() == ENOTSOCK);
+ }
+}
+
+TEST_CASE(nvxx_send_recv)
+{
+ using namespace std::literals;
+ auto constexpr key = "test"sv;
+ auto constexpr value = 42u;
+
+ auto nvl = bsd::nv_list();
+ nvl.add_number(key, value);
+
+ auto fds = std::array<int, 2>{};
+ auto ret = ::socketpair(AF_UNIX, SOCK_STREAM, 0, &fds[0]);
+ ATF_REQUIRE_EQ(0, ret);
+
+ bsd::nv_fd fd0(fds[0]);
+ bsd::nv_fd fd1(fds[1]);
+
+ nvl.send(fd0.get());
+
+ auto nvl2 = bsd::nv_list::recv(fd1.get());
+ ATF_REQUIRE_EQ(value, nvl2.get_number(key));
+}
+
+TEST_CASE(nvxx_send_error)
+{
+ using namespace std::literals;
+
+ auto nvl = bsd::nv_list();
+ nvl.set_error(std::errc::invalid_argument);
+
+ auto fds = std::array<int, 2>{};
+ auto ret = ::socketpair(AF_UNIX, SOCK_STREAM, 0, &fds[0]);
+ ATF_REQUIRE_EQ(0, ret);
+
+ bsd::nv_fd fd0(fds[0]);
+ bsd::nv_fd fd1(fds[1]);
+
+ ATF_REQUIRE_THROW(bsd::nv_error_state, nvl.send(fd0.get()));
+}
+
+TEST_CASE(nvxx_send_empty)
+{
+ auto cnv = bsd::const_nv_list();
+
+ auto fds = std::array<int, 2>{};
+ auto ret = ::socketpair(AF_UNIX, SOCK_STREAM, 0, &fds[0]);
+ ATF_REQUIRE_EQ(0, ret);
+
+ bsd::nv_fd fd0(fds[0]);
+ bsd::nv_fd fd1(fds[1]);
+
+ ATF_REQUIRE_THROW(std::logic_error, cnv.send(fd0.get()));
+}
+
/*
* exists(_type)
*/
@@ -1933,6 +2013,11 @@ ATF_INIT_TEST_CASES(tcs)
ATF_ADD_TEST_CASE(tcs, nvxx_unpack);
ATF_ADD_TEST_CASE(tcs, nvxx_unpack_range);
+ ATF_ADD_TEST_CASE(tcs, nvxx_send_non_socket);
+ ATF_ADD_TEST_CASE(tcs, nvxx_send_recv);
+ ATF_ADD_TEST_CASE(tcs, nvxx_send_empty);
+ ATF_ADD_TEST_CASE(tcs, nvxx_send_error);
+
ATF_ADD_TEST_CASE(tcs, nvxx_exists);
ATF_ADD_TEST_CASE(tcs, nvxx_exists_nul_key);
ATF_ADD_TEST_CASE(tcs, nvxx_exists_type);