mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 05:26:47 +00:00
Merge 285bee715a
into 65fa0ab924
This commit is contained in:
commit
ea97747953
@ -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::NOT_READY
|
||||
}
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user