Skip to content

Rollup of 12 pull requests #139837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 31 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b9754f9
Enable contracts for const functions
celinval Feb 25, 2025
3feac59
Fix unreachable expression warning
celinval Apr 8, 2025
8c86bb4
rustdoc: Output target feature information
willglynn Apr 4, 2025
13f1c84
Apply suggestions from code review
celinval Apr 10, 2025
7582554
Update target_features doc comment
willglynn Apr 12, 2025
86e2a07
opt-dist: use executable-extension for host llvm-profdata
ognevny Apr 12, 2025
a404015
std: sys: process: uefi: Use NULL stdin by default
Ayush1325 Apr 8, 2025
af25995
std: sys: stdio: uefi: Tread UNSUPPORTED Status as read(0)
Ayush1325 Apr 13, 2025
d994fef
std: sys: process: uefi: Allow specifying Stdin
Ayush1325 Apr 10, 2025
ed5f31a
Avoid unused clones in Cloned<I> and Copied<I>
thaliaarchi Apr 13, 2025
f3344ef
tests: use `compiletest-ignore-dir` for bootstrap self-tests
jieyouxu Apr 14, 2025
6a8718c
Add test for issue 34834
reddevilmidzy Apr 14, 2025
2c2c9df
drop global where-bounds before merging candidates
lcnr Apr 14, 2025
ce9d867
do not leak auto traits in item bounds
lcnr Apr 14, 2025
2e79f7c
move tests
lcnr Apr 14, 2025
836ea25
add RPITIT tests: method compat auto trait leakage
lcnr Apr 14, 2025
7ad1697
Allow const patterns of matches to contain pattern types
oli-obk Jan 24, 2025
c2712bc
ci: add runners for vanilla LLVM 20
cuviper Mar 12, 2025
9676d4a
std: add Output::exit_ok
lolbinarycat Apr 8, 2025
eea9048
Rollup merge of #138374 - celinval:issue-136925-const-contract, r=com…
Zalathar Apr 15, 2025
8c1f55b
Rollup merge of #138380 - cuviper:ci-llvm-20, r=Kobzol
Zalathar Apr 15, 2025
a295c7e
Rollup merge of #138393 - oli-obk:pattern-type-in-pattern, r=BoxyUwU
Zalathar Apr 15, 2025
e2d5382
Rollup merge of #139393 - willglynn:rustdoc_output_target_feature_inf…
Zalathar Apr 15, 2025
1373a2f
Rollup merge of #139517 - Ayush1325:uefi-cmd-stdin-null, r=joboet
Zalathar Apr 15, 2025
d179ea0
Rollup merge of #139554 - lolbinarycat:std-output-exit_ok, r=tgross35
Zalathar Apr 15, 2025
83cd669
Rollup merge of #139745 - thaliaarchi:iter-unused-clone-copy, r=joboet
Zalathar Apr 15, 2025
e668f8c
Rollup merge of #139757 - ognevny:opt-dist-hostllvm, r=Kobzol
Zalathar Apr 15, 2025
7771e67
Rollup merge of #139778 - reddevilmidzy:add-success-test, r=lcnr
Zalathar Apr 15, 2025
cdd69c9
Rollup merge of #139783 - jieyouxu:ignore-dir, r=Zalathar
Zalathar Apr 15, 2025
b2897d0
Rollup merge of #139789 - lcnr:opaques-auto-trait-leakage, r=compiler…
Zalathar Apr 15, 2025
7f3fec3
Rollup merge of #139791 - lcnr:ignore-global-where-bounds, r=compiler…
Zalathar Apr 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
std: sys: process: uefi: Use NULL stdin by default
According to the docs in `Command::output`:

> By default, stdout and stderr are captured (and used to provide the
resulting output). Stdin is not inherited from the parent and any attempt
by the child process to read from the stdin stream will result in the
stream immediately closing.

This was being violated by UEFI which was inheriting stdin by default.

While the docs don't explicitly state that the default should be NULL,
the behaviour seems like reading from NULL.

UEFI however, has a bit of a problem. The `EFI_SIMPLE_TEXT_INPUT_PROTOCOL`
only provides support for reading 1 key press. This means that you
either get an error, or it is assumed that the keypress was read
successfully. So there is no way to have a successful read of length 0.
Currently, I am returning UNSUPPORTED error when trying to read from
NULL stdin. On linux however, you will get a read of length 0 for Null
stdin.

One possible way to get around this is to translate one of the UEFI
errors to a read 0 (Maybe unsupported?). It is also possible to have a
non-standard error code, but well, not sure if we go that route.

Alternatively, if meaning of Stdio::Null is platform dependent, it
should be fine to keep the current behaviour of returning an error.

Signed-off-by: Ayush Singh <[email protected]>
  • Loading branch information
Ayush1325 committed Apr 13, 2025
commit a404015775276f2e21e16c69fab36cc8228d51f6
112 changes: 109 additions & 3 deletions library/std/src/sys/process/uefi.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use r_efi::protocols::simple_text_output;
use r_efi::protocols::{simple_text_input, simple_text_output};

use crate::collections::BTreeMap;
pub use crate::ffi::OsString as EnvKey;
Expand Down Expand Up @@ -122,6 +122,22 @@ impl Command {
}
}

fn create_stdin(
s: Stdio,
) -> io::Result<Option<helpers::OwnedProtocol<uefi_command_internal::InputProtocol>>> {
match s {
Stdio::Null => unsafe {
helpers::OwnedProtocol::create(
uefi_command_internal::InputProtocol::null(),
simple_text_input::PROTOCOL_GUID,
)
}
.map(Some),
Stdio::Inherit => Ok(None),
Stdio::MakePipe => unsupported(),
}
}

pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
let mut cmd = uefi_command_internal::Image::load_image(&self.prog)?;

Expand Down Expand Up @@ -149,6 +165,14 @@ impl Command {
cmd.stderr_inherit()
};

// Setup Stdin
let stdin = Self::create_stdin(Stdio::Null)?;
if let Some(con) = stdin {
cmd.stdin_init(con)
} else {
cmd.stdin_inherit()
};

let env = env_changes(&self.env);

// Set any new vars
Expand Down Expand Up @@ -334,7 +358,7 @@ impl<'a> fmt::Debug for CommandArgs<'a> {

#[allow(dead_code)]
mod uefi_command_internal {
use r_efi::protocols::{loaded_image, simple_text_output};
use r_efi::protocols::{loaded_image, simple_text_input, simple_text_output};

use crate::ffi::{OsStr, OsString};
use crate::io::{self, const_error};
Expand All @@ -350,6 +374,7 @@ mod uefi_command_internal {
handle: NonNull<crate::ffi::c_void>,
stdout: Option<helpers::OwnedProtocol<PipeProtocol>>,
stderr: Option<helpers::OwnedProtocol<PipeProtocol>>,
stdin: Option<helpers::OwnedProtocol<InputProtocol>>,
st: OwnedTable<r_efi::efi::SystemTable>,
args: Option<(*mut u16, usize)>,
}
Expand Down Expand Up @@ -384,7 +409,14 @@ mod uefi_command_internal {
helpers::open_protocol(child_handle, loaded_image::PROTOCOL_GUID).unwrap();
let st = OwnedTable::from_table(unsafe { (*loaded_image.as_ptr()).system_table });

Ok(Self { handle: child_handle, stdout: None, stderr: None, st, args: None })
Ok(Self {
handle: child_handle,
stdout: None,
stderr: None,
stdin: None,
st,
args: None,
})
}
}

Expand Down Expand Up @@ -445,6 +477,17 @@ mod uefi_command_internal {
}
}

fn set_stdin(
&mut self,
handle: r_efi::efi::Handle,
protocol: *mut simple_text_input::Protocol,
) {
unsafe {
(*self.st.as_mut_ptr()).console_in_handle = handle;
(*self.st.as_mut_ptr()).con_in = protocol;
}
}

pub fn stdout_init(&mut self, protocol: helpers::OwnedProtocol<PipeProtocol>) {
self.set_stdout(
protocol.handle().as_ptr(),
Expand All @@ -471,6 +514,19 @@ mod uefi_command_internal {
unsafe { self.set_stderr((*st.as_ptr()).standard_error_handle, (*st.as_ptr()).std_err) }
}

pub(crate) fn stdin_init(&mut self, protocol: helpers::OwnedProtocol<InputProtocol>) {
self.set_stdin(
protocol.handle().as_ptr(),
protocol.as_ref() as *const InputProtocol as *mut simple_text_input::Protocol,
);
self.stdin = Some(protocol);
}

pub(crate) fn stdin_inherit(&mut self) {
let st: NonNull<r_efi::efi::SystemTable> = system_table().cast();
unsafe { self.set_stdin((*st.as_ptr()).console_in_handle, (*st.as_ptr()).con_in) }
}

pub fn stderr(&self) -> io::Result<Vec<u8>> {
match &self.stderr {
Some(stderr) => stderr.as_ref().utf8(),
Expand Down Expand Up @@ -722,6 +778,56 @@ mod uefi_command_internal {
}
}

#[repr(C)]
pub(crate) struct InputProtocol {
reset: simple_text_input::ProtocolReset,
read_key_stroke: simple_text_input::ProtocolReadKeyStroke,
wait_for_key: r_efi::efi::Event,
}

impl InputProtocol {
pub(crate) fn null() -> Self {
let evt = helpers::OwnedEvent::new(
r_efi::efi::EVT_NOTIFY_WAIT,
r_efi::efi::TPL_CALLBACK,
Some(Self::empty_notify),
None,
)
.unwrap();

Self {
reset: Self::null_reset,
read_key_stroke: Self::null_read_key,
wait_for_key: evt.into_raw(),
}
}

extern "efiapi" fn null_reset(
_: *mut simple_text_input::Protocol,
_: r_efi::efi::Boolean,
) -> r_efi::efi::Status {
r_efi::efi::Status::SUCCESS
}

extern "efiapi" fn null_read_key(
_: *mut simple_text_input::Protocol,
_: *mut simple_text_input::InputKey,
) -> r_efi::efi::Status {
r_efi::efi::Status::UNSUPPORTED
}

extern "efiapi" fn empty_notify(_: r_efi::efi::Event, _: *mut crate::ffi::c_void) {}
}

impl Drop for InputProtocol {
fn drop(&mut self) {
// Close wait_for_key
unsafe {
let _ = helpers::OwnedEvent::from_raw(self.wait_for_key);
}
}
}

pub fn create_args(prog: &OsStr, args: &[OsString]) -> Box<[u16]> {
const QUOTE: u16 = 0x0022;
const SPACE: u16 = 0x0020;
Expand Down