about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-07-06 10:03:22 +0200
committerGitHub <noreply@github.com>2025-07-06 10:03:22 +0200
commit19f8ba4733c3eb8fa98ba06be63df8b621625d0b (patch)
treee130b6d42fa57a93f5a40347e3c64deff83ee700
parent71b73e529a4898ae97e8448cad62f9166da968f1 (diff)
parent1f01d9b3db949340c614cb0a9cf8319808088054 (diff)
downloadrust-19f8ba4733c3eb8fa98ba06be63df8b621625d0b.tar.gz
rust-19f8ba4733c3eb8fa98ba06be63df8b621625d0b.zip
Rollup merge of #143470 - Ayush1325:uefi-tcp4-recv, r=joshtriplett
std: sys: net: uefi: tcp4: Implement read

- A blocking implementation of tcp4 read.
- Basically a copy of [write](https://github.com/rust-lang/rust/pull/141532)
-rw-r--r--library/std/src/sys/net/connection/uefi/mod.rs13
-rw-r--r--library/std/src/sys/net/connection/uefi/tcp.rs6
-rw-r--r--library/std/src/sys/net/connection/uefi/tcp4.rs39
3 files changed, 52 insertions, 6 deletions
diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs
index 2d465bd0efa..6835ba44ee2 100644
--- a/library/std/src/sys/net/connection/uefi/mod.rs
+++ b/library/std/src/sys/net/connection/uefi/mod.rs
@@ -38,16 +38,17 @@ impl TcpStream {
         unsupported()
     }
 
-    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
-        unsupported()
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.0.read(buf)
     }
 
-    pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> {
-        unsupported()
+    pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        crate::io::default_read_buf(|buf| self.read(buf), cursor)
     }
 
-    pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        unsupported()
+    pub fn read_vectored(&self, buf: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        // FIXME: UEFI does support vectored read, so implement that.
+        crate::io::default_read_vectored(|b| self.read(b), buf)
     }
 
     pub fn is_read_vectored(&self) -> bool {
diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs
index 9c3462e3468..55b6dbf2490 100644
--- a/library/std/src/sys/net/connection/uefi/tcp.rs
+++ b/library/std/src/sys/net/connection/uefi/tcp.rs
@@ -24,4 +24,10 @@ impl Tcp {
             Self::V4(client) => client.write(buf),
         }
     }
+
+    pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        match self {
+            Self::V4(client) => client.read(buf),
+        }
+    }
 }
diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs
index d0f0d27d975..af1ba2be47a 100644
--- a/library/std/src/sys/net/connection/uefi/tcp4.rs
+++ b/library/std/src/sys/net/connection/uefi/tcp4.rs
@@ -128,6 +128,45 @@ impl Tcp4 {
         }
     }
 
+    pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        let evt = unsafe { self.create_evt() }?;
+        let completion_token =
+            tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS };
+        let data_len = u32::try_from(buf.len()).unwrap_or(u32::MAX);
+
+        let fragment = tcp4::FragmentData {
+            fragment_length: data_len,
+            fragment_buffer: buf.as_mut_ptr().cast::<crate::ffi::c_void>(),
+        };
+        let mut tx_data = tcp4::ReceiveData {
+            urgent_flag: r_efi::efi::Boolean::FALSE,
+            data_length: data_len,
+            fragment_count: 1,
+            fragment_table: [fragment],
+        };
+
+        let protocol = self.protocol.as_ptr();
+        let mut token = tcp4::IoToken {
+            completion_token,
+            packet: tcp4::IoTokenPacket {
+                rx_data: (&raw mut tx_data).cast::<tcp4::ReceiveData<0>>(),
+            },
+        };
+
+        let r = unsafe { ((*protocol).receive)(protocol, &mut token) };
+        if r.is_error() {
+            return Err(io::Error::from_raw_os_error(r.as_usize()));
+        }
+
+        self.wait_for_flag();
+
+        if completion_token.status.is_error() {
+            Err(io::Error::from_raw_os_error(completion_token.status.as_usize()))
+        } else {
+            Ok(data_len as usize)
+        }
+    }
+
     unsafe fn create_evt(&self) -> io::Result<helpers::OwnedEvent> {
         self.flag.store(false, Ordering::Relaxed);
         helpers::OwnedEvent::new(