fd/intf: Add sendto / recvfrom operations

Change-Id: I2f3f20cb79e806aa665cc3b7e5823cbf3d71034a
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/fd/impl.cpp b/src/fd/impl.cpp
index 1ac9938..22a1b3b 100644
--- a/src/fd/impl.cpp
+++ b/src/fd/impl.cpp
@@ -46,6 +46,19 @@
                 ::recv(get(), buf.data(), buf.size(), static_cast<int>(flags)));
 }
 
+std::tuple<std::span<std::byte>, std::span<std::byte>>
+    FdImpl::recvfrom(std::span<std::byte> buf, RecvFlags flags,
+                     std::span<std::byte> sockaddr)
+{
+    socklen_t sockaddrsize = sockaddr.size();
+    auto ret =
+        fret(buf, "recvfrom",
+             ::recvfrom(get(), buf.data(), buf.size(), static_cast<int>(flags),
+                        reinterpret_cast<struct sockaddr*>(sockaddr.data()),
+                        &sockaddrsize));
+    return std::make_tuple(ret, sockaddr.subspan(0, sockaddrsize));
+}
+
 std::span<const std::byte> FdImpl::write(std::span<const std::byte> data)
 {
     return fret(data, "write", ::write(get(), data.data(), data.size()));
@@ -59,6 +72,17 @@
         ::send(get(), data.data(), data.size(), static_cast<int>(flags)));
 }
 
+std::span<const std::byte> FdImpl::sendto(std::span<const std::byte> data,
+                                          SendFlags flags,
+                                          std::span<const std::byte> sockaddr)
+{
+    return fret(
+        data, "sendto",
+        ::sendto(get(), data.data(), data.size(), static_cast<int>(flags),
+                 reinterpret_cast<const struct sockaddr*>(sockaddr.data()),
+                 sockaddr.size()));
+}
+
 static std::string_view whenceStr(Whence whence)
 {
     switch (whence)