diff options
| author | bors <bors@rust-lang.org> | 2025-04-15 08:02:23 +0000 | 
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-04-15 08:02:23 +0000 | 
| commit | f433fa46b0fd27d35219357ad75f54d294081bc4 (patch) | |
| tree | 856536d645c04538bda01df760fe645d77529dd0 /library/std/src/sys/process/uefi.rs | |
| parent | 58c2dd9a54a325f4ce96f70332ceb07a3b58f0e5 (diff) | |
| parent | 783b08156ebf2e8f2ee766bb4bfc2f8025c38243 (diff) | |
| download | rust-f433fa46b0fd27d35219357ad75f54d294081bc4.tar.gz rust-f433fa46b0fd27d35219357ad75f54d294081bc4.zip | |
Auto merge of #139845 - Zalathar:rollup-u5u5y1v, r=Zalathar
Rollup of 17 pull requests
Successful merges:
 - #138374 (Enable contracts for const functions)
 - #138380 (ci: add runners for vanilla LLVM 20)
 - #138393 (Allow const patterns of matches to contain pattern types)
 - #139517 (std: sys: process: uefi: Use NULL stdin by default)
 - #139554 (std: add Output::exit_ok)
 - #139660 (compiletest: Add an experimental new executor to replace libtest)
 - #139669 (Overhaul `AssocItem`)
 - #139671 (Proc macro span API redesign: Replace proc_macro::SourceFile by Span::{file, local_file})
 - #139750 (std/thread: Use default stack size from menuconfig for NuttX)
 - #139772 (Remove `hir::Map`)
 - #139785 (Let CStrings be either 1 or 2 byte aligned.)
 - #139789 (do not unnecessarily leak auto traits in item bounds)
 - #139791 (drop global where-bounds before merging candidates)
 - #139798 (normalize: prefer `ParamEnv` over `AliasBound` candidates)
 - #139822 (Fix: Map EOPNOTSUPP to ErrorKind::Unsupported on Unix)
 - #139833 (Fix some HIR pretty-printing problems)
 - #139836 (Basic tests of MPMC receiver cloning)
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library/std/src/sys/process/uefi.rs')
| -rw-r--r-- | library/std/src/sys/process/uefi.rs | 119 | 
1 files changed, 114 insertions, 5 deletions
| diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index b46418ae9bb..5f922292d05 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -1,4 +1,4 @@ -use r_efi::protocols::simple_text_output; +use r_efi::protocols::{simple_text_input, simple_text_output}; use crate::collections::BTreeMap; pub use crate::ffi::OsString as EnvKey; @@ -23,6 +23,7 @@ pub struct Command { args: Vec<OsString>, stdout: Option<Stdio>, stderr: Option<Stdio>, + stdin: Option<Stdio>, env: CommandEnv, } @@ -48,6 +49,7 @@ impl Command { args: Vec::new(), stdout: None, stderr: None, + stdin: None, env: Default::default(), } } @@ -64,8 +66,8 @@ impl Command { panic!("unsupported") } - pub fn stdin(&mut self, _stdin: Stdio) { - panic!("unsupported") + pub fn stdin(&mut self, stdin: Stdio) { + self.stdin = Some(stdin); } pub fn stdout(&mut self, stdout: Stdio) { @@ -122,6 +124,22 @@ impl Command { } } + fn create_stdin( + s: Stdio, + ) -> io::Result<Option<helpers::OwnedProtocol<uefi_command_internal::InputProtocol>>> { + match s { + Stdio::Null => unsafe { + helpers::OwnedProtocol::create( + uefi_command_internal::InputProtocol::null(), + simple_text_input::PROTOCOL_GUID, + ) + } + .map(Some), + Stdio::Inherit => Ok(None), + Stdio::MakePipe => unsupported(), + } + } + pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> { let mut cmd = uefi_command_internal::Image::load_image(&self.prog)?; @@ -149,6 +167,15 @@ impl Command { cmd.stderr_inherit() }; + // Setup Stdin + let stdin = self.stdin.unwrap_or(Stdio::Null); + let stdin = Self::create_stdin(stdin)?; + if let Some(con) = stdin { + cmd.stdin_init(con) + } else { + cmd.stdin_inherit() + }; + let env = env_changes(&self.env); // Set any new vars @@ -334,7 +361,7 @@ impl<'a> fmt::Debug for CommandArgs<'a> { #[allow(dead_code)] mod uefi_command_internal { - use r_efi::protocols::{loaded_image, simple_text_output}; + use r_efi::protocols::{loaded_image, simple_text_input, simple_text_output}; use crate::ffi::{OsStr, OsString}; use crate::io::{self, const_error}; @@ -350,6 +377,7 @@ mod uefi_command_internal { handle: NonNull<crate::ffi::c_void>, stdout: Option<helpers::OwnedProtocol<PipeProtocol>>, stderr: Option<helpers::OwnedProtocol<PipeProtocol>>, + stdin: Option<helpers::OwnedProtocol<InputProtocol>>, st: OwnedTable<r_efi::efi::SystemTable>, args: Option<(*mut u16, usize)>, } @@ -384,7 +412,14 @@ mod uefi_command_internal { helpers::open_protocol(child_handle, loaded_image::PROTOCOL_GUID).unwrap(); let st = OwnedTable::from_table(unsafe { (*loaded_image.as_ptr()).system_table }); - Ok(Self { handle: child_handle, stdout: None, stderr: None, st, args: None }) + Ok(Self { + handle: child_handle, + stdout: None, + stderr: None, + stdin: None, + st, + args: None, + }) } } @@ -445,6 +480,17 @@ mod uefi_command_internal { } } + fn set_stdin( + &mut self, + handle: r_efi::efi::Handle, + protocol: *mut simple_text_input::Protocol, + ) { + unsafe { + (*self.st.as_mut_ptr()).console_in_handle = handle; + (*self.st.as_mut_ptr()).con_in = protocol; + } + } + pub fn stdout_init(&mut self, protocol: helpers::OwnedProtocol<PipeProtocol>) { self.set_stdout( protocol.handle().as_ptr(), @@ -471,6 +517,19 @@ mod uefi_command_internal { unsafe { self.set_stderr((*st.as_ptr()).standard_error_handle, (*st.as_ptr()).std_err) } } + pub(crate) fn stdin_init(&mut self, protocol: helpers::OwnedProtocol<InputProtocol>) { + self.set_stdin( + protocol.handle().as_ptr(), + protocol.as_ref() as *const InputProtocol as *mut simple_text_input::Protocol, + ); + self.stdin = Some(protocol); + } + + pub(crate) fn stdin_inherit(&mut self) { + let st: NonNull<r_efi::efi::SystemTable> = system_table().cast(); + unsafe { self.set_stdin((*st.as_ptr()).console_in_handle, (*st.as_ptr()).con_in) } + } + pub fn stderr(&self) -> io::Result<Vec<u8>> { match &self.stderr { Some(stderr) => stderr.as_ref().utf8(), @@ -722,6 +781,56 @@ mod uefi_command_internal { } } + #[repr(C)] + pub(crate) struct InputProtocol { + reset: simple_text_input::ProtocolReset, + read_key_stroke: simple_text_input::ProtocolReadKeyStroke, + wait_for_key: r_efi::efi::Event, + } + + impl InputProtocol { + pub(crate) fn null() -> Self { + let evt = helpers::OwnedEvent::new( + r_efi::efi::EVT_NOTIFY_WAIT, + r_efi::efi::TPL_CALLBACK, + Some(Self::empty_notify), + None, + ) + .unwrap(); + + Self { + reset: Self::null_reset, + read_key_stroke: Self::null_read_key, + wait_for_key: evt.into_raw(), + } + } + + extern "efiapi" fn null_reset( + _: *mut simple_text_input::Protocol, + _: r_efi::efi::Boolean, + ) -> r_efi::efi::Status { + r_efi::efi::Status::SUCCESS + } + + extern "efiapi" fn null_read_key( + _: *mut simple_text_input::Protocol, + _: *mut simple_text_input::InputKey, + ) -> r_efi::efi::Status { + r_efi::efi::Status::UNSUPPORTED + } + + extern "efiapi" fn empty_notify(_: r_efi::efi::Event, _: *mut crate::ffi::c_void) {} + } + + impl Drop for InputProtocol { + fn drop(&mut self) { + // Close wait_for_key + unsafe { + let _ = helpers::OwnedEvent::from_raw(self.wait_for_key); + } + } + } + pub fn create_args(prog: &OsStr, args: &[OsString]) -> Box<[u16]> { const QUOTE: u16 = 0x0022; const SPACE: u16 = 0x0020; | 
