1
+ use r_efi:: protocols:: simple_text_output;
2
+
1
3
use crate :: ffi:: OsStr ;
2
4
use crate :: ffi:: OsString ;
3
5
use crate :: fmt;
@@ -13,12 +15,16 @@ use crate::sys_common::process::{CommandEnv, CommandEnvs};
13
15
14
16
pub use crate :: ffi:: OsString as EnvKey ;
15
17
18
+ use super :: helpers;
19
+
16
20
////////////////////////////////////////////////////////////////////////////////
17
21
// Command
18
22
////////////////////////////////////////////////////////////////////////////////
19
23
20
24
pub struct Command {
21
25
prog : OsString ,
26
+ stdout : Option < uefi_command_internal:: PipeProtocol > ,
27
+ stderr : Option < uefi_command_internal:: PipeProtocol > ,
22
28
}
23
29
24
30
// passed back to std::process with the pipes connected to the child, if any
@@ -39,7 +45,7 @@ pub enum Stdio {
39
45
40
46
impl Command {
41
47
pub fn new ( program : & OsStr ) -> Command {
42
- Command { prog : program. to_os_string ( ) }
48
+ Command { prog : program. to_os_string ( ) , stdout : None , stderr : None }
43
49
}
44
50
45
51
pub fn arg ( & mut self , _arg : & OsStr ) {
@@ -58,12 +64,20 @@ impl Command {
58
64
panic ! ( "unsupported" )
59
65
}
60
66
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
+ } ;
63
73
}
64
74
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
+ } ;
67
81
}
68
82
69
83
pub fn get_program ( & self ) -> & OsStr {
@@ -93,8 +107,26 @@ impl Command {
93
107
pub fn output ( & mut self ) -> io:: Result < ( ExitStatus , Vec < u8 > , Vec < u8 > ) > {
94
108
let mut cmd = uefi_command_internal:: Command :: load_image ( & self . prog ) ?;
95
109
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) ?;
98
130
99
131
let stat = cmd. start_image ( ) ?;
100
132
let stdout = cmd. stdout ( ) ?;
@@ -342,10 +374,10 @@ mod uefi_command_internal {
342
374
Ok ( r)
343
375
}
344
376
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 < ( ) > {
349
381
self . st . console_out_handle = protocol. handle ( ) . as_ptr ( ) ;
350
382
self . st . con_out =
351
383
protocol. as_mut ( ) as * mut PipeProtocol as * mut simple_text_output:: Protocol ;
@@ -355,10 +387,10 @@ mod uefi_command_internal {
355
387
Ok ( ( ) )
356
388
}
357
389
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 < ( ) > {
362
394
self . st . standard_error_handle = protocol. handle ( ) . as_ptr ( ) ;
363
395
self . st . std_err =
364
396
protocol. as_mut ( ) as * mut PipeProtocol as * mut simple_text_output:: Protocol ;
@@ -368,29 +400,17 @@ mod uefi_command_internal {
368
400
Ok ( ( ) )
369
401
}
370
402
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 ( ) ) ,
381
407
}
382
408
}
383
409
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 ( ) ) ,
394
414
}
395
415
}
396
416
}
@@ -407,7 +427,7 @@ mod uefi_command_internal {
407
427
}
408
428
409
429
#[ repr( C ) ]
410
- struct PipeProtocol {
430
+ pub struct PipeProtocol {
411
431
reset : simple_text_output:: ProtocolReset ,
412
432
output_string : simple_text_output:: ProtocolOutputString ,
413
433
test_string : simple_text_output:: ProtocolTestString ,
@@ -423,7 +443,7 @@ mod uefi_command_internal {
423
443
}
424
444
425
445
impl PipeProtocol {
426
- fn new ( ) -> Self {
446
+ pub fn new ( ) -> Self {
427
447
let mut mode = Box :: new ( simple_text_output:: Mode {
428
448
max_mode : 0 ,
429
449
mode : 0 ,
@@ -448,8 +468,36 @@ mod uefi_command_internal {
448
468
}
449
469
}
450
470
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 > > {
452
497
OsString :: from_wide ( & self . _buffer )
498
+ . into_string ( )
499
+ . map ( Into :: into)
500
+ . map_err ( |_| const_io_error ! ( io:: ErrorKind :: Other , "utf8 conversion failed" ) )
453
501
}
454
502
455
503
extern "efiapi" fn reset (
@@ -463,6 +511,13 @@ mod uefi_command_internal {
463
511
r_efi:: efi:: Status :: SUCCESS
464
512
}
465
513
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
+
466
521
extern "efiapi" fn output_string (
467
522
proto : * mut simple_text_output:: Protocol ,
468
523
buf : * mut r_efi:: efi:: Char16 ,
@@ -484,6 +539,13 @@ mod uefi_command_internal {
484
539
r_efi:: efi:: Status :: SUCCESS
485
540
}
486
541
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
+
487
549
extern "efiapi" fn test_string (
488
550
_: * mut simple_text_output:: Protocol ,
489
551
_: * mut r_efi:: efi:: Char16 ,
0 commit comments