diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-07-06 10:03:22 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-06 10:03:22 +0200 |
| commit | 19f8ba4733c3eb8fa98ba06be63df8b621625d0b (patch) | |
| tree | e130b6d42fa57a93f5a40347e3c64deff83ee700 | |
| parent | 71b73e529a4898ae97e8448cad62f9166da968f1 (diff) | |
| parent | 1f01d9b3db949340c614cb0a9cf8319808088054 (diff) | |
| download | rust-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.rs | 13 | ||||
| -rw-r--r-- | library/std/src/sys/net/connection/uefi/tcp.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys/net/connection/uefi/tcp4.rs | 39 |
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( |
