Skip to content

Commit 1f01d9b

Browse files
committed
std: sys: net: uefi: tcp4: Implement read
A blocking implementation of tcp4 read. Signed-off-by: Ayush Singh <[email protected]>
1 parent d98a5da commit 1f01d9b

File tree

3 files changed

+52
-6
lines changed

3 files changed

+52
-6
lines changed

library/std/src/sys/net/connection/uefi/mod.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,17 @@ impl TcpStream {
3838
unsupported()
3939
}
4040

41-
pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
42-
unsupported()
41+
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
42+
self.0.read(buf)
4343
}
4444

45-
pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> {
46-
unsupported()
45+
pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
46+
crate::io::default_read_buf(|buf| self.read(buf), cursor)
4747
}
4848

49-
pub fn read_vectored(&self, _: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
50-
unsupported()
49+
pub fn read_vectored(&self, buf: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
50+
// FIXME: UEFI does support vectored read, so implement that.
51+
crate::io::default_read_vectored(|b| self.read(b), buf)
5152
}
5253

5354
pub fn is_read_vectored(&self) -> bool {

library/std/src/sys/net/connection/uefi/tcp.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,10 @@ impl Tcp {
2424
Self::V4(client) => client.write(buf),
2525
}
2626
}
27+
28+
pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
29+
match self {
30+
Self::V4(client) => client.read(buf),
31+
}
32+
}
2733
}

library/std/src/sys/net/connection/uefi/tcp4.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,45 @@ impl Tcp4 {
128128
}
129129
}
130130

131+
pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
132+
let evt = unsafe { self.create_evt() }?;
133+
let completion_token =
134+
tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS };
135+
let data_len = u32::try_from(buf.len()).unwrap_or(u32::MAX);
136+
137+
let fragment = tcp4::FragmentData {
138+
fragment_length: data_len,
139+
fragment_buffer: buf.as_mut_ptr().cast::<crate::ffi::c_void>(),
140+
};
141+
let mut tx_data = tcp4::ReceiveData {
142+
urgent_flag: r_efi::efi::Boolean::FALSE,
143+
data_length: data_len,
144+
fragment_count: 1,
145+
fragment_table: [fragment],
146+
};
147+
148+
let protocol = self.protocol.as_ptr();
149+
let mut token = tcp4::IoToken {
150+
completion_token,
151+
packet: tcp4::IoTokenPacket {
152+
rx_data: (&raw mut tx_data).cast::<tcp4::ReceiveData<0>>(),
153+
},
154+
};
155+
156+
let r = unsafe { ((*protocol).receive)(protocol, &mut token) };
157+
if r.is_error() {
158+
return Err(io::Error::from_raw_os_error(r.as_usize()));
159+
}
160+
161+
self.wait_for_flag();
162+
163+
if completion_token.status.is_error() {
164+
Err(io::Error::from_raw_os_error(completion_token.status.as_usize()))
165+
} else {
166+
Ok(data_len as usize)
167+
}
168+
}
169+
131170
unsafe fn create_evt(&self) -> io::Result<helpers::OwnedEvent> {
132171
self.flag.store(false, Ordering::Relaxed);
133172
helpers::OwnedEvent::new(

0 commit comments

Comments
 (0)