Skip to content

Commit f4ef1a7

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

File tree

3 files changed

+53
-6
lines changed

3 files changed

+53
-6
lines changed

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::time::Duration;
77
mod tcp;
88
pub(crate) mod tcp4;
99

10-
pub struct TcpStream(#[expect(dead_code)] tcp::Tcp);
10+
pub struct TcpStream(tcp::Tcp);
1111

1212
impl TcpStream {
1313
pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
@@ -54,12 +54,13 @@ impl TcpStream {
5454
false
5555
}
5656

57-
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
58-
unsupported()
57+
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
58+
self.0.write(buf)
5959
}
6060

61-
pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result<usize> {
62-
unsupported()
61+
pub fn write_vectored(&self, buf: &[IoSlice<'_>]) -> io::Result<usize> {
62+
// FIXME: UEFI does support vectored write, so implement that.
63+
crate::io::default_write_vectored(|b| self.write(b), buf)
6364
}
6465

6566
pub fn is_write_vectored(&self) -> bool {

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::io;
33
use crate::net::SocketAddr;
44

55
pub(crate) enum Tcp {
6-
V4(#[expect(dead_code)] tcp4::Tcp4),
6+
V4(tcp4::Tcp4),
77
}
88

99
impl Tcp {
@@ -18,4 +18,10 @@ impl Tcp {
1818
SocketAddr::V6(_) => todo!(),
1919
}
2020
}
21+
22+
pub(crate) fn write(&self, buf: &[u8]) -> io::Result<usize> {
23+
match self {
24+
Self::V4(client) => client.write(buf),
25+
}
26+
}
2127
}

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,46 @@ impl Tcp4 {
8888
}
8989
}
9090

91+
pub(crate) fn write(&self, buf: &[u8]) -> io::Result<usize> {
92+
let evt = unsafe { self.create_evt() }?;
93+
let completion_token =
94+
tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS };
95+
let data_len = u32::try_from(buf.len()).unwrap_or(u32::MAX);
96+
97+
let fragment = tcp4::FragmentData {
98+
fragment_length: data_len,
99+
fragment_buffer: buf.as_ptr().cast::<crate::ffi::c_void>().cast_mut(),
100+
};
101+
let mut tx_data = tcp4::TransmitData {
102+
push: r_efi::efi::Boolean::FALSE,
103+
urgent: r_efi::efi::Boolean::FALSE,
104+
data_length: data_len,
105+
fragment_count: 1,
106+
fragment_table: [fragment],
107+
};
108+
109+
let protocol = self.protocol.as_ptr();
110+
let mut token = tcp4::IoToken {
111+
completion_token,
112+
packet: tcp4::IoTokenPacket {
113+
tx_data: (&raw mut tx_data).cast::<tcp4::TransmitData<0>>(),
114+
},
115+
};
116+
117+
let r = unsafe { ((*protocol).transmit)(protocol, &mut token) };
118+
if r.is_error() {
119+
return Err(io::Error::from_raw_os_error(r.as_usize()));
120+
}
121+
122+
self.wait_for_flag();
123+
124+
if completion_token.status.is_error() {
125+
Err(io::Error::from_raw_os_error(completion_token.status.as_usize()))
126+
} else {
127+
Ok(data_len as usize)
128+
}
129+
}
130+
91131
unsafe fn create_evt(&self) -> io::Result<helpers::OwnedEvent> {
92132
self.flag.store(false, Ordering::Relaxed);
93133
helpers::OwnedEvent::new(

0 commit comments

Comments
 (0)