@@ -23,6 +23,7 @@ use super::helpers;
23
23
24
24
pub struct Command {
25
25
prog : OsString ,
26
+ args : OsString ,
26
27
stdout : Option < Stdio > ,
27
28
stderr : Option < Stdio > ,
28
29
}
@@ -45,11 +46,17 @@ pub enum Stdio {
45
46
46
47
impl Command {
47
48
pub fn new ( program : & OsStr ) -> Command {
48
- Command { prog : program. to_os_string ( ) , stdout : None , stderr : None }
49
+ Command {
50
+ prog : program. to_os_string ( ) ,
51
+ args : program. to_os_string ( ) ,
52
+ stdout : None ,
53
+ stderr : None ,
54
+ }
49
55
}
50
56
51
- pub fn arg ( & mut self , _arg : & OsStr ) {
52
- panic ! ( "unsupported" )
57
+ pub fn arg ( & mut self , arg : & OsStr ) {
58
+ self . args . push ( " " ) ;
59
+ self . args . push ( arg) ;
53
60
}
54
61
55
62
pub fn env_mut ( & mut self ) -> & mut CommandEnv {
@@ -137,11 +144,17 @@ impl Command {
137
144
. map ( Some ) ,
138
145
} ?;
139
146
140
- if let Some ( stdout) = stdout {
141
- cmd. stdout_init ( stdout) ?;
142
- }
143
- if let Some ( stderr) = stderr {
144
- cmd. stderr_init ( stderr) ?;
147
+ match stdout {
148
+ Some ( stdout) => cmd. stdout_init ( stdout) ,
149
+ None => cmd. stdout_inherit ( ) ,
150
+ } ;
151
+ match stderr {
152
+ Some ( stderr) => cmd. stderr_init ( stderr) ,
153
+ None => cmd. stderr_inherit ( ) ,
154
+ } ;
155
+
156
+ if !self . args . is_empty ( ) {
157
+ cmd. set_args ( & self . args ) ;
145
158
}
146
159
147
160
let stat = cmd. start_image ( ) ?;
@@ -308,8 +321,8 @@ mod uefi_command_internal {
308
321
use crate :: ffi:: { OsStr , OsString } ;
309
322
use crate :: io:: { self , const_io_error} ;
310
323
use crate :: mem:: MaybeUninit ;
311
- use crate :: os:: uefi:: env:: { boot_services, image_handle} ;
312
- use crate :: os:: uefi:: ffi:: OsStringExt ;
324
+ use crate :: os:: uefi:: env:: { boot_services, image_handle, system_table } ;
325
+ use crate :: os:: uefi:: ffi:: { OsStrExt , OsStringExt } ;
313
326
use crate :: ptr:: NonNull ;
314
327
use crate :: slice;
315
328
use crate :: sys_common:: wstr:: WStrUnits ;
@@ -319,14 +332,15 @@ mod uefi_command_internal {
319
332
stdout : Option < helpers:: Protocol < PipeProtocol > > ,
320
333
stderr : Option < helpers:: Protocol < PipeProtocol > > ,
321
334
st : Box < r_efi:: efi:: SystemTable > ,
335
+ args : Option < Vec < u16 > > ,
322
336
}
323
337
324
338
impl Command {
325
339
const fn new (
326
340
handle : NonNull < crate :: ffi:: c_void > ,
327
341
st : Box < r_efi:: efi:: SystemTable > ,
328
342
) -> Self {
329
- Self { handle, stdout : None , stderr : None , st }
343
+ Self { handle, stdout : None , stderr : None , st, args : None }
330
344
}
331
345
332
346
pub fn load_image ( p : & OsStr ) -> io:: Result < Self > {
@@ -391,30 +405,34 @@ mod uefi_command_internal {
391
405
Ok ( r)
392
406
}
393
407
394
- pub fn stdout_init (
395
- & mut self ,
396
- mut protocol : helpers:: Protocol < PipeProtocol > ,
397
- ) -> io:: Result < ( ) > {
408
+ pub fn stdout_init ( & mut self , mut protocol : helpers:: Protocol < PipeProtocol > ) {
398
409
self . st . console_out_handle = protocol. handle ( ) . as_ptr ( ) ;
399
410
self . st . con_out =
400
411
protocol. as_mut ( ) as * mut PipeProtocol as * mut simple_text_output:: Protocol ;
401
412
402
413
self . stdout = Some ( protocol) ;
414
+ }
403
415
404
- Ok ( ( ) )
416
+ pub fn stdout_inherit ( & mut self ) {
417
+ let st: NonNull < r_efi:: efi:: SystemTable > = system_table ( ) . cast ( ) ;
418
+
419
+ self . st . console_out_handle = unsafe { ( * st. as_ptr ( ) ) . console_out_handle } ;
420
+ self . st . con_out = unsafe { ( * st. as_ptr ( ) ) . con_out } ;
405
421
}
406
422
407
- pub fn stderr_init (
408
- & mut self ,
409
- mut protocol : helpers:: Protocol < PipeProtocol > ,
410
- ) -> io:: Result < ( ) > {
423
+ pub fn stderr_init ( & mut self , mut protocol : helpers:: Protocol < PipeProtocol > ) {
411
424
self . st . standard_error_handle = protocol. handle ( ) . as_ptr ( ) ;
412
425
self . st . std_err =
413
426
protocol. as_mut ( ) as * mut PipeProtocol as * mut simple_text_output:: Protocol ;
414
427
415
428
self . stderr = Some ( protocol) ;
429
+ }
430
+
431
+ pub fn stderr_inherit ( & mut self ) {
432
+ let st: NonNull < r_efi:: efi:: SystemTable > = system_table ( ) . cast ( ) ;
416
433
417
- Ok ( ( ) )
434
+ self . st . standard_error_handle = unsafe { ( * st. as_ptr ( ) ) . standard_error_handle } ;
435
+ self . st . std_err = unsafe { ( * st. as_ptr ( ) ) . std_err } ;
418
436
}
419
437
420
438
pub fn stderr ( & self ) -> io:: Result < Vec < u8 > > {
@@ -430,6 +448,22 @@ mod uefi_command_internal {
430
448
None => Ok ( Vec :: new ( ) ) ,
431
449
}
432
450
}
451
+
452
+ pub fn set_args ( & mut self , args : & OsStr ) {
453
+ let loaded_image: NonNull < loaded_image:: Protocol > =
454
+ helpers:: open_protocol ( self . handle , loaded_image:: PROTOCOL_GUID ) . unwrap ( ) ;
455
+
456
+ let mut args = args. encode_wide ( ) . collect :: < Vec < u16 > > ( ) ;
457
+ let args_size = ( crate :: mem:: size_of :: < u16 > ( ) * args. len ( ) ) as u32 ;
458
+
459
+ unsafe {
460
+ ( * loaded_image. as_ptr ( ) ) . load_options =
461
+ args. as_mut_ptr ( ) as * mut crate :: ffi:: c_void ;
462
+ ( * loaded_image. as_ptr ( ) ) . load_options_size = args_size;
463
+ }
464
+
465
+ self . args = Some ( args) ;
466
+ }
433
467
}
434
468
435
469
impl Drop for Command {
0 commit comments