uefi: process: Add support for args

Also fix stdio inherit

Signed-off-by: Ayush Singh <ayushdevel1325@gmail.com>
This commit is contained in:
Ayush Singh 2024-03-29 19:44:37 +05:30 committed by Ayush Singh
parent d44b3fb120
commit 29c198c85f
No known key found for this signature in database
GPG Key ID: 05CEF5C789E55A74

View File

@ -23,6 +23,7 @@ use super::helpers;
pub struct Command { pub struct Command {
prog: OsString, prog: OsString,
args: OsString,
stdout: Option<Stdio>, stdout: Option<Stdio>,
stderr: Option<Stdio>, stderr: Option<Stdio>,
} }
@ -45,11 +46,17 @@ pub enum Stdio {
impl Command { impl Command {
pub fn new(program: &OsStr) -> Command { pub fn new(program: &OsStr) -> Command {
Command { prog: program.to_os_string(), stdout: None, stderr: None } Command {
prog: program.to_os_string(),
args: program.to_os_string(),
stdout: None,
stderr: None,
}
} }
pub fn arg(&mut self, _arg: &OsStr) { pub fn arg(&mut self, arg: &OsStr) {
panic!("unsupported") self.args.push(" ");
self.args.push(arg);
} }
pub fn env_mut(&mut self) -> &mut CommandEnv { pub fn env_mut(&mut self) -> &mut CommandEnv {
@ -137,11 +144,17 @@ impl Command {
.map(Some), .map(Some),
}?; }?;
if let Some(stdout) = stdout { match stdout {
cmd.stdout_init(stdout)?; Some(stdout) => cmd.stdout_init(stdout),
} None => cmd.stdout_inherit(),
if let Some(stderr) = stderr { };
cmd.stderr_init(stderr)?; match stderr {
Some(stderr) => cmd.stderr_init(stderr),
None => cmd.stderr_inherit(),
};
if !self.args.is_empty() {
cmd.set_args(&self.args);
} }
let stat = cmd.start_image()?; let stat = cmd.start_image()?;
@ -308,8 +321,8 @@ mod uefi_command_internal {
use crate::ffi::{OsStr, OsString}; use crate::ffi::{OsStr, OsString};
use crate::io::{self, const_io_error}; use crate::io::{self, const_io_error};
use crate::mem::MaybeUninit; use crate::mem::MaybeUninit;
use crate::os::uefi::env::{boot_services, image_handle}; use crate::os::uefi::env::{boot_services, image_handle, system_table};
use crate::os::uefi::ffi::OsStringExt; use crate::os::uefi::ffi::{OsStrExt, OsStringExt};
use crate::ptr::NonNull; use crate::ptr::NonNull;
use crate::slice; use crate::slice;
use crate::sys_common::wstr::WStrUnits; use crate::sys_common::wstr::WStrUnits;
@ -319,6 +332,7 @@ mod uefi_command_internal {
stdout: Option<helpers::Protocol<PipeProtocol>>, stdout: Option<helpers::Protocol<PipeProtocol>>,
stderr: Option<helpers::Protocol<PipeProtocol>>, stderr: Option<helpers::Protocol<PipeProtocol>>,
st: Box<r_efi::efi::SystemTable>, st: Box<r_efi::efi::SystemTable>,
args: Option<Vec<u16>>,
} }
impl Command { impl Command {
@ -326,7 +340,7 @@ mod uefi_command_internal {
handle: NonNull<crate::ffi::c_void>, handle: NonNull<crate::ffi::c_void>,
st: Box<r_efi::efi::SystemTable>, st: Box<r_efi::efi::SystemTable>,
) -> Self { ) -> Self {
Self { handle, stdout: None, stderr: None, st } Self { handle, stdout: None, stderr: None, st, args: None }
} }
pub fn load_image(p: &OsStr) -> io::Result<Self> { pub fn load_image(p: &OsStr) -> io::Result<Self> {
@ -391,30 +405,34 @@ mod uefi_command_internal {
Ok(r) Ok(r)
} }
pub fn stdout_init( pub fn stdout_init(&mut self, mut protocol: helpers::Protocol<PipeProtocol>) {
&mut self,
mut protocol: helpers::Protocol<PipeProtocol>,
) -> io::Result<()> {
self.st.console_out_handle = protocol.handle().as_ptr(); self.st.console_out_handle = protocol.handle().as_ptr();
self.st.con_out = self.st.con_out =
protocol.as_mut() as *mut PipeProtocol as *mut simple_text_output::Protocol; protocol.as_mut() as *mut PipeProtocol as *mut simple_text_output::Protocol;
self.stdout = Some(protocol); self.stdout = Some(protocol);
Ok(())
} }
pub fn stderr_init( pub fn stdout_inherit(&mut self) {
&mut self, let st: NonNull<r_efi::efi::SystemTable> = system_table().cast();
mut protocol: helpers::Protocol<PipeProtocol>,
) -> io::Result<()> { self.st.console_out_handle = unsafe { (*st.as_ptr()).console_out_handle };
self.st.con_out = unsafe { (*st.as_ptr()).con_out };
}
pub fn stderr_init(&mut self, mut protocol: helpers::Protocol<PipeProtocol>) {
self.st.standard_error_handle = protocol.handle().as_ptr(); self.st.standard_error_handle = protocol.handle().as_ptr();
self.st.std_err = self.st.std_err =
protocol.as_mut() as *mut PipeProtocol as *mut simple_text_output::Protocol; protocol.as_mut() as *mut PipeProtocol as *mut simple_text_output::Protocol;
self.stderr = Some(protocol); self.stderr = Some(protocol);
}
Ok(()) pub fn stderr_inherit(&mut self) {
let st: NonNull<r_efi::efi::SystemTable> = system_table().cast();
self.st.standard_error_handle = unsafe { (*st.as_ptr()).standard_error_handle };
self.st.std_err = unsafe { (*st.as_ptr()).std_err };
} }
pub fn stderr(&self) -> io::Result<Vec<u8>> { pub fn stderr(&self) -> io::Result<Vec<u8>> {
@ -430,6 +448,22 @@ mod uefi_command_internal {
None => Ok(Vec::new()), None => Ok(Vec::new()),
} }
} }
pub fn set_args(&mut self, args: &OsStr) {
let loaded_image: NonNull<loaded_image::Protocol> =
helpers::open_protocol(self.handle, loaded_image::PROTOCOL_GUID).unwrap();
let mut args = args.encode_wide().collect::<Vec<u16>>();
let args_size = (crate::mem::size_of::<u16>() * args.len()) as u32;
unsafe {
(*loaded_image.as_ptr()).load_options =
args.as_mut_ptr() as *mut crate::ffi::c_void;
(*loaded_image.as_ptr()).load_options_size = args_size;
}
self.args = Some(args);
}
} }
impl Drop for Command { impl Drop for Command {