diff options
| author | Ayush Singh <ayushdevel1325@gmail.com> | 2024-03-29 18:36:52 +0530 |
|---|---|---|
| committer | Ayush Singh <ayush@beagleboard.org> | 2024-07-19 17:43:45 +0530 |
| commit | 725376567ae0e2b75574bbda68d191ebd3a4ce68 (patch) | |
| tree | 0539eb4fe593dcd73a226b6192aee1cafbdc1301 | |
| parent | 87d7a07f5057c33df152af06d92a1a9bbae8767d (diff) | |
| download | rust-725376567ae0e2b75574bbda68d191ebd3a4ce68.tar.gz rust-725376567ae0e2b75574bbda68d191ebd3a4ce68.zip | |
uefi: process: Add null protocol
Signed-off-by: Ayush Singh <ayushdevel1325@gmail.com>
| -rw-r--r-- | library/std/src/sys/pal/uefi/process.rs | 138 |
1 files changed, 100 insertions, 38 deletions
diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs index 06ce542b0be..fc96f382650 100644 --- a/library/std/src/sys/pal/uefi/process.rs +++ b/library/std/src/sys/pal/uefi/process.rs @@ -1,3 +1,5 @@ +use r_efi::protocols::simple_text_output; + use crate::ffi::OsStr; use crate::ffi::OsString; use crate::fmt; @@ -13,12 +15,16 @@ use crate::sys_common::process::{CommandEnv, CommandEnvs}; pub use crate::ffi::OsString as EnvKey; +use super::helpers; + //////////////////////////////////////////////////////////////////////////////// // Command //////////////////////////////////////////////////////////////////////////////// pub struct Command { prog: OsString, + stdout: Option<uefi_command_internal::PipeProtocol>, + stderr: Option<uefi_command_internal::PipeProtocol>, } // passed back to std::process with the pipes connected to the child, if any @@ -39,7 +45,7 @@ pub enum Stdio { impl Command { pub fn new(program: &OsStr) -> Command { - Command { prog: program.to_os_string() } + Command { prog: program.to_os_string(), stdout: None, stderr: None } } pub fn arg(&mut self, _arg: &OsStr) { @@ -58,12 +64,20 @@ impl Command { panic!("unsupported") } - pub fn stdout(&mut self, _stdout: Stdio) { - panic!("unsupported") + pub fn stdout(&mut self, stdout: Stdio) { + self.stdout = match stdout { + Stdio::MakePipe => Some(uefi_command_internal::PipeProtocol::new()), + Stdio::Null => Some(uefi_command_internal::PipeProtocol::null()), + _ => None, + }; } - pub fn stderr(&mut self, _stderr: Stdio) { - panic!("unsupported") + pub fn stderr(&mut self, stderr: Stdio) { + self.stderr = match stderr { + Stdio::MakePipe => Some(uefi_command_internal::PipeProtocol::new()), + Stdio::Null => Some(uefi_command_internal::PipeProtocol::null()), + _ => None, + }; } pub fn get_program(&self) -> &OsStr { @@ -93,8 +107,26 @@ impl Command { pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> { let mut cmd = uefi_command_internal::Command::load_image(&self.prog)?; - cmd.stdout_init()?; - cmd.stderr_init()?; + let stdout: helpers::Protocol<uefi_command_internal::PipeProtocol> = + match self.stdout.take() { + Some(s) => helpers::Protocol::create(s, simple_text_output::PROTOCOL_GUID), + None => helpers::Protocol::create( + uefi_command_internal::PipeProtocol::new(), + simple_text_output::PROTOCOL_GUID, + ), + }?; + + let stderr: helpers::Protocol<uefi_command_internal::PipeProtocol> = + match self.stderr.take() { + Some(s) => helpers::Protocol::create(s, simple_text_output::PROTOCOL_GUID), + None => helpers::Protocol::create( + uefi_command_internal::PipeProtocol::new(), + simple_text_output::PROTOCOL_GUID, + ), + }?; + + cmd.stdout_init(stdout)?; + cmd.stderr_init(stderr)?; let stat = cmd.start_image()?; let stdout = cmd.stdout()?; @@ -342,10 +374,10 @@ mod uefi_command_internal { Ok(r) } - pub fn stdout_init(&mut self) -> io::Result<()> { - let mut protocol = - helpers::Protocol::create(PipeProtocol::new(), simple_text_output::PROTOCOL_GUID)?; - + pub fn stdout_init( + &mut self, + mut protocol: helpers::Protocol<PipeProtocol>, + ) -> io::Result<()> { self.st.console_out_handle = protocol.handle().as_ptr(); self.st.con_out = protocol.as_mut() as *mut PipeProtocol as *mut simple_text_output::Protocol; @@ -355,10 +387,10 @@ mod uefi_command_internal { Ok(()) } - pub fn stderr_init(&mut self) -> io::Result<()> { - let mut protocol = - helpers::Protocol::create(PipeProtocol::new(), simple_text_output::PROTOCOL_GUID)?; - + pub fn stderr_init( + &mut self, + mut protocol: helpers::Protocol<PipeProtocol>, + ) -> io::Result<()> { self.st.standard_error_handle = protocol.handle().as_ptr(); self.st.std_err = protocol.as_mut() as *mut PipeProtocol as *mut simple_text_output::Protocol; @@ -368,29 +400,17 @@ mod uefi_command_internal { Ok(()) } - pub fn stdout(&self) -> io::Result<Vec<u8>> { - if let Some(stdout) = &self.stdout { - stdout - .as_ref() - .utf8() - .into_string() - .map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed")) - .map(Into::into) - } else { - Err(const_io_error!(io::ErrorKind::NotFound, "stdout not found")) + pub fn stderr(&self) -> io::Result<Vec<u8>> { + match &self.stderr { + Some(stderr) => stderr.as_ref().utf8(), + None => Ok(Vec::new()), } } - pub fn stderr(&self) -> io::Result<Vec<u8>> { - if let Some(stderr) = &self.stderr { - stderr - .as_ref() - .utf8() - .into_string() - .map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed")) - .map(Into::into) - } else { - Err(const_io_error!(io::ErrorKind::NotFound, "stdout not found")) + pub fn stdout(&self) -> io::Result<Vec<u8>> { + match &self.stdout { + Some(stdout) => stdout.as_ref().utf8(), + None => Ok(Vec::new()), } } } @@ -407,7 +427,7 @@ mod uefi_command_internal { } #[repr(C)] - struct PipeProtocol { + pub struct PipeProtocol { reset: simple_text_output::ProtocolReset, output_string: simple_text_output::ProtocolOutputString, test_string: simple_text_output::ProtocolTestString, @@ -423,7 +443,7 @@ mod uefi_command_internal { } impl PipeProtocol { - fn new() -> Self { + pub fn new() -> Self { let mut mode = Box::new(simple_text_output::Mode { max_mode: 0, mode: 0, @@ -448,8 +468,36 @@ mod uefi_command_internal { } } - fn utf8(&self) -> OsString { + pub fn null() -> Self { + let mut mode = Box::new(simple_text_output::Mode { + max_mode: 0, + mode: 0, + attribute: 0, + cursor_column: 0, + cursor_row: 0, + cursor_visible: r_efi::efi::Boolean::FALSE, + }); + Self { + reset: Self::reset_null, + output_string: Self::output_string_null, + test_string: Self::test_string, + query_mode: Self::query_mode, + set_mode: Self::set_mode, + set_attribute: Self::set_attribute, + clear_screen: Self::clear_screen, + set_cursor_position: Self::set_cursor_position, + enable_cursor: Self::enable_cursor, + mode: mode.as_mut(), + _mode: mode, + _buffer: Vec::new(), + } + } + + pub fn utf8(&self) -> io::Result<Vec<u8>> { OsString::from_wide(&self._buffer) + .into_string() + .map(Into::into) + .map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed")) } extern "efiapi" fn reset( @@ -463,6 +511,13 @@ mod uefi_command_internal { r_efi::efi::Status::SUCCESS } + extern "efiapi" fn reset_null( + _: *mut simple_text_output::Protocol, + _: r_efi::efi::Boolean, + ) -> r_efi::efi::Status { + r_efi::efi::Status::SUCCESS + } + extern "efiapi" fn output_string( proto: *mut simple_text_output::Protocol, buf: *mut r_efi::efi::Char16, @@ -484,6 +539,13 @@ mod uefi_command_internal { r_efi::efi::Status::SUCCESS } + extern "efiapi" fn output_string_null( + _: *mut simple_text_output::Protocol, + _: *mut r_efi::efi::Char16, + ) -> r_efi::efi::Status { + r_efi::efi::Status::SUCCESS + } + extern "efiapi" fn test_string( _: *mut simple_text_output::Protocol, _: *mut r_efi::efi::Char16, |
