Skip to content

Commit 24a9582

Browse files
committed
uefi: process: Add null protocol
Signed-off-by: Ayush Singh <[email protected]>
1 parent 36a0e1e commit 24a9582

File tree

1 file changed

+100
-38
lines changed

1 file changed

+100
-38
lines changed

std/src/sys/pal/uefi/process.rs

+100-38
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use r_efi::protocols::simple_text_output;
2+
13
use crate::ffi::OsStr;
24
use crate::ffi::OsString;
35
use crate::fmt;
@@ -13,12 +15,16 @@ use crate::sys_common::process::{CommandEnv, CommandEnvs};
1315

1416
pub use crate::ffi::OsString as EnvKey;
1517

18+
use super::helpers;
19+
1620
////////////////////////////////////////////////////////////////////////////////
1721
// Command
1822
////////////////////////////////////////////////////////////////////////////////
1923

2024
pub struct Command {
2125
prog: OsString,
26+
stdout: Option<uefi_command_internal::PipeProtocol>,
27+
stderr: Option<uefi_command_internal::PipeProtocol>,
2228
}
2329

2430
// passed back to std::process with the pipes connected to the child, if any
@@ -39,7 +45,7 @@ pub enum Stdio {
3945

4046
impl Command {
4147
pub fn new(program: &OsStr) -> Command {
42-
Command { prog: program.to_os_string() }
48+
Command { prog: program.to_os_string(), stdout: None, stderr: None }
4349
}
4450

4551
pub fn arg(&mut self, _arg: &OsStr) {
@@ -58,12 +64,20 @@ impl Command {
5864
panic!("unsupported")
5965
}
6066

61-
pub fn stdout(&mut self, _stdout: Stdio) {
62-
panic!("unsupported")
67+
pub fn stdout(&mut self, stdout: Stdio) {
68+
self.stdout = match stdout {
69+
Stdio::MakePipe => Some(uefi_command_internal::PipeProtocol::new()),
70+
Stdio::Null => Some(uefi_command_internal::PipeProtocol::null()),
71+
_ => None,
72+
};
6373
}
6474

65-
pub fn stderr(&mut self, _stderr: Stdio) {
66-
panic!("unsupported")
75+
pub fn stderr(&mut self, stderr: Stdio) {
76+
self.stderr = match stderr {
77+
Stdio::MakePipe => Some(uefi_command_internal::PipeProtocol::new()),
78+
Stdio::Null => Some(uefi_command_internal::PipeProtocol::null()),
79+
_ => None,
80+
};
6781
}
6882

6983
pub fn get_program(&self) -> &OsStr {
@@ -93,8 +107,26 @@ impl Command {
93107
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
94108
let mut cmd = uefi_command_internal::Command::load_image(&self.prog)?;
95109

96-
cmd.stdout_init()?;
97-
cmd.stderr_init()?;
110+
let stdout: helpers::Protocol<uefi_command_internal::PipeProtocol> =
111+
match self.stdout.take() {
112+
Some(s) => helpers::Protocol::create(s, simple_text_output::PROTOCOL_GUID),
113+
None => helpers::Protocol::create(
114+
uefi_command_internal::PipeProtocol::new(),
115+
simple_text_output::PROTOCOL_GUID,
116+
),
117+
}?;
118+
119+
let stderr: helpers::Protocol<uefi_command_internal::PipeProtocol> =
120+
match self.stderr.take() {
121+
Some(s) => helpers::Protocol::create(s, simple_text_output::PROTOCOL_GUID),
122+
None => helpers::Protocol::create(
123+
uefi_command_internal::PipeProtocol::new(),
124+
simple_text_output::PROTOCOL_GUID,
125+
),
126+
}?;
127+
128+
cmd.stdout_init(stdout)?;
129+
cmd.stderr_init(stderr)?;
98130

99131
let stat = cmd.start_image()?;
100132
let stdout = cmd.stdout()?;
@@ -342,10 +374,10 @@ mod uefi_command_internal {
342374
Ok(r)
343375
}
344376

345-
pub fn stdout_init(&mut self) -> io::Result<()> {
346-
let mut protocol =
347-
helpers::Protocol::create(PipeProtocol::new(), simple_text_output::PROTOCOL_GUID)?;
348-
377+
pub fn stdout_init(
378+
&mut self,
379+
mut protocol: helpers::Protocol<PipeProtocol>,
380+
) -> io::Result<()> {
349381
self.st.console_out_handle = protocol.handle().as_ptr();
350382
self.st.con_out =
351383
protocol.as_mut() as *mut PipeProtocol as *mut simple_text_output::Protocol;
@@ -355,10 +387,10 @@ mod uefi_command_internal {
355387
Ok(())
356388
}
357389

358-
pub fn stderr_init(&mut self) -> io::Result<()> {
359-
let mut protocol =
360-
helpers::Protocol::create(PipeProtocol::new(), simple_text_output::PROTOCOL_GUID)?;
361-
390+
pub fn stderr_init(
391+
&mut self,
392+
mut protocol: helpers::Protocol<PipeProtocol>,
393+
) -> io::Result<()> {
362394
self.st.standard_error_handle = protocol.handle().as_ptr();
363395
self.st.std_err =
364396
protocol.as_mut() as *mut PipeProtocol as *mut simple_text_output::Protocol;
@@ -368,29 +400,17 @@ mod uefi_command_internal {
368400
Ok(())
369401
}
370402

371-
pub fn stdout(&self) -> io::Result<Vec<u8>> {
372-
if let Some(stdout) = &self.stdout {
373-
stdout
374-
.as_ref()
375-
.utf8()
376-
.into_string()
377-
.map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed"))
378-
.map(Into::into)
379-
} else {
380-
Err(const_io_error!(io::ErrorKind::NotFound, "stdout not found"))
403+
pub fn stderr(&self) -> io::Result<Vec<u8>> {
404+
match &self.stderr {
405+
Some(stderr) => stderr.as_ref().utf8(),
406+
None => Ok(Vec::new()),
381407
}
382408
}
383409

384-
pub fn stderr(&self) -> io::Result<Vec<u8>> {
385-
if let Some(stderr) = &self.stderr {
386-
stderr
387-
.as_ref()
388-
.utf8()
389-
.into_string()
390-
.map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed"))
391-
.map(Into::into)
392-
} else {
393-
Err(const_io_error!(io::ErrorKind::NotFound, "stdout not found"))
410+
pub fn stdout(&self) -> io::Result<Vec<u8>> {
411+
match &self.stdout {
412+
Some(stdout) => stdout.as_ref().utf8(),
413+
None => Ok(Vec::new()),
394414
}
395415
}
396416
}
@@ -407,7 +427,7 @@ mod uefi_command_internal {
407427
}
408428

409429
#[repr(C)]
410-
struct PipeProtocol {
430+
pub struct PipeProtocol {
411431
reset: simple_text_output::ProtocolReset,
412432
output_string: simple_text_output::ProtocolOutputString,
413433
test_string: simple_text_output::ProtocolTestString,
@@ -423,7 +443,7 @@ mod uefi_command_internal {
423443
}
424444

425445
impl PipeProtocol {
426-
fn new() -> Self {
446+
pub fn new() -> Self {
427447
let mut mode = Box::new(simple_text_output::Mode {
428448
max_mode: 0,
429449
mode: 0,
@@ -448,8 +468,36 @@ mod uefi_command_internal {
448468
}
449469
}
450470

451-
fn utf8(&self) -> OsString {
471+
pub fn null() -> Self {
472+
let mut mode = Box::new(simple_text_output::Mode {
473+
max_mode: 0,
474+
mode: 0,
475+
attribute: 0,
476+
cursor_column: 0,
477+
cursor_row: 0,
478+
cursor_visible: r_efi::efi::Boolean::FALSE,
479+
});
480+
Self {
481+
reset: Self::reset_null,
482+
output_string: Self::output_string_null,
483+
test_string: Self::test_string,
484+
query_mode: Self::query_mode,
485+
set_mode: Self::set_mode,
486+
set_attribute: Self::set_attribute,
487+
clear_screen: Self::clear_screen,
488+
set_cursor_position: Self::set_cursor_position,
489+
enable_cursor: Self::enable_cursor,
490+
mode: mode.as_mut(),
491+
_mode: mode,
492+
_buffer: Vec::new(),
493+
}
494+
}
495+
496+
pub fn utf8(&self) -> io::Result<Vec<u8>> {
452497
OsString::from_wide(&self._buffer)
498+
.into_string()
499+
.map(Into::into)
500+
.map_err(|_| const_io_error!(io::ErrorKind::Other, "utf8 conversion failed"))
453501
}
454502

455503
extern "efiapi" fn reset(
@@ -463,6 +511,13 @@ mod uefi_command_internal {
463511
r_efi::efi::Status::SUCCESS
464512
}
465513

514+
extern "efiapi" fn reset_null(
515+
_: *mut simple_text_output::Protocol,
516+
_: r_efi::efi::Boolean,
517+
) -> r_efi::efi::Status {
518+
r_efi::efi::Status::SUCCESS
519+
}
520+
466521
extern "efiapi" fn output_string(
467522
proto: *mut simple_text_output::Protocol,
468523
buf: *mut r_efi::efi::Char16,
@@ -484,6 +539,13 @@ mod uefi_command_internal {
484539
r_efi::efi::Status::SUCCESS
485540
}
486541

542+
extern "efiapi" fn output_string_null(
543+
_: *mut simple_text_output::Protocol,
544+
_: *mut r_efi::efi::Char16,
545+
) -> r_efi::efi::Status {
546+
r_efi::efi::Status::SUCCESS
547+
}
548+
487549
extern "efiapi" fn test_string(
488550
_: *mut simple_text_output::Protocol,
489551
_: *mut r_efi::efi::Char16,

0 commit comments

Comments
 (0)