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,

`