Rollup merge of #129794 - Ayush1325:uefi-os-expand, r=joboet · qinheping/verify-rust-std@435ce04 (original) (raw)
1
1
`use r_efi::efi::Status;
`
2
2
`use r_efi::efi::protocols::{device_path, loaded_image_device_path};
`
3
3
``
4
``
`-
use super::{RawOsError, helpers, unsupported};
`
``
4
`+
use super::{RawOsError, helpers, unsupported_err};
`
5
5
`use crate::error::Error as StdError;
`
6
6
`use crate::ffi::{OsStr, OsString};
`
7
7
`use crate:📑:PhantomData;
`
`@@ -125,11 +125,32 @@ pub fn error_string(errno: RawOsError) -> String {
`
125
125
`}
`
126
126
``
127
127
`pub fn getcwd() -> io::Result {
`
128
``
`-
unsupported()
`
``
128
`+
match uefi_shell::open_shell() {
`
``
129
`+
Some(shell) => {
`
``
130
`+
// SAFETY: path_ptr is managed by UEFI shell and should not be deallocated
`
``
131
`+
let path_ptr = unsafe { ((*shell.as_ptr()).get_cur_dir)(crate::ptr::null_mut()) };
`
``
132
`+
helpers::os_string_from_raw(path_ptr)
`
``
133
`+
.map(PathBuf::from)
`
``
134
`+
.ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))
`
``
135
`+
}
`
``
136
`+
None => {
`
``
137
`+
let mut t = current_exe()?;
`
``
138
`+
// SAFETY: This should never fail since the disk prefix will be present even for root
`
``
139
`+
// executables
`
``
140
`+
assert!(t.pop());
`
``
141
`+
Ok(t)
`
``
142
`+
}
`
``
143
`+
}
`
129
144
`}
`
130
145
``
131
``
`-
pub fn chdir(_: &path::Path) -> io::Result<()> {
`
132
``
`-
unsupported()
`
``
146
`+
pub fn chdir(p: &path::Path) -> io::Result<()> {
`
``
147
`+
let shell = uefi_shell::open_shell().ok_or(unsupported_err())?;
`
``
148
+
``
149
`+
let mut p = helpers::os_string_to_raw(p.as_os_str())
`
``
150
`+
.ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?;
`
``
151
+
``
152
`+
let r = unsafe { ((*shell.as_ptr()).set_cur_dir)(crate::ptr::null_mut(), p.as_mut_ptr()) };
`
``
153
`+
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
`
133
154
`}
`
134
155
``
135
156
`pub struct SplitPaths<'a>(!, PhantomData<&'a ()>);
`
`@@ -239,3 +260,37 @@ pub fn exit(code: i32) -> ! {
`
239
260
`pub fn getpid() -> u32 {
`
240
261
`panic!("no pids on this platform")
`
241
262
`}
`
``
263
+
``
264
`+
mod uefi_shell {
`
``
265
`+
use r_efi::protocols::shell;
`
``
266
+
``
267
`+
use super::super::helpers;
`
``
268
`+
use crate::ptr::NonNull;
`
``
269
`+
use crate::sync::atomic::{AtomicPtr, Ordering};
`
``
270
+
``
271
`+
pub fn open_shell() -> Option<NonNullshell::Protocol> {
`
``
272
`+
static LAST_VALID_HANDLE: AtomicPtrcrate::ffi::c_void =
`
``
273
`+
AtomicPtr::new(crate::ptr::null_mut());
`
``
274
+
``
275
`+
if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) {
`
``
276
`+
if let Ok(protocol) = helpers::open_protocol::shell::Protocol(
`
``
277
`+
handle,
`
``
278
`+
r_efi::protocols:🐚:PROTOCOL_GUID,
`
``
279
`+
) {
`
``
280
`+
return Some(protocol);
`
``
281
`+
}
`
``
282
`+
}
`
``
283
+
``
284
`+
let handles = helpers::locate_handles(shell::PROTOCOL_GUID).ok()?;
`
``
285
`+
for handle in handles {
`
``
286
`+
if let Ok(protocol) =
`
``
287
`+
helpers::open_protocol::shell::Protocol(handle, shell::PROTOCOL_GUID)
`
``
288
`+
{
`
``
289
`+
LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release);
`
``
290
`+
return Some(protocol);
`
``
291
`+
}
`
``
292
`+
}
`
``
293
+
``
294
`+
None
`
``
295
`+
}
`
``
296
`+
}
`