uefi: process: Add null protocol · model-checking/verify-rust-std@24a9582 (original) (raw)
``
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, Vec)> {
`
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,
`
``
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,
`
``
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> {
`
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> {
`
``
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> {
`
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> {
`
``
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> {
`
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,
`