1+ use r_efi:: protocols:: simple_text_output;
2+
13use crate :: ffi:: OsStr ;
24use crate :: ffi:: OsString ;
35use crate :: fmt;
@@ -13,12 +15,16 @@ use crate::sys_common::process::{CommandEnv, CommandEnvs};
1315
1416pub use crate :: ffi:: OsString as EnvKey ;
1517
18+ use super :: helpers;
19+
1620////////////////////////////////////////////////////////////////////////////////
1721// Command
1822////////////////////////////////////////////////////////////////////////////////
1923
2024pub 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
4046impl 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