mirror of
https://github.com/rust-lang/rust
synced 2024-10-06 08:40:35 +00:00
Use RawOsError for UEFI
Some changes from this commit will probably be converted to its own PR. Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
This commit is contained in:
parent
7a956441a1
commit
40c3dacc76
|
@ -117,4 +117,5 @@ pub fn log_wrapper<F: Fn(f64) -> f64>(n: f64, log_fn: F) -> f64 {
|
|||
log_fn(n)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "uefi"))]
|
||||
pub type RawOsError = i32;
|
||||
|
|
|
@ -43,7 +43,7 @@ fn inner(
|
|||
)
|
||||
};
|
||||
|
||||
if r.is_error() { Err(status_to_io_error(r)) } else { Ok(()) }
|
||||
if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
|
||||
}
|
||||
|
||||
let boot_services = boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
|
||||
|
@ -99,181 +99,13 @@ pub(crate) fn open_protocol<T>(
|
|||
};
|
||||
|
||||
if r.is_error() {
|
||||
Err(status_to_io_error(r))
|
||||
Err(crate::io::Error::from_raw_os_error(r.as_usize()))
|
||||
} else {
|
||||
NonNull::new(unsafe { protocol.assume_init() })
|
||||
.ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn status_to_io_error(s: r_efi::efi::Status) -> io::Error {
|
||||
use io::ErrorKind;
|
||||
use r_efi::efi::Status;
|
||||
|
||||
// Keep the List in Alphabetical Order
|
||||
// The Messages are taken from UEFI Specification Appendix D - Status Codes
|
||||
match s {
|
||||
Status::ABORTED => {
|
||||
const_io_error!(ErrorKind::ConnectionAborted, "The operation was aborted.")
|
||||
}
|
||||
Status::ACCESS_DENIED => {
|
||||
const_io_error!(ErrorKind::PermissionDenied, "Access was denied.")
|
||||
}
|
||||
Status::ALREADY_STARTED => {
|
||||
const_io_error!(ErrorKind::Other, "The protocol has already been started.")
|
||||
}
|
||||
Status::BAD_BUFFER_SIZE => {
|
||||
const_io_error!(
|
||||
ErrorKind::InvalidData,
|
||||
"The buffer was not the proper size for the request."
|
||||
)
|
||||
}
|
||||
Status::BUFFER_TOO_SMALL => {
|
||||
const_io_error!(
|
||||
ErrorKind::FileTooLarge,
|
||||
"The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs."
|
||||
)
|
||||
}
|
||||
Status::COMPROMISED_DATA => {
|
||||
const_io_error!(
|
||||
ErrorKind::Other,
|
||||
"The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status."
|
||||
)
|
||||
}
|
||||
Status::CONNECTION_FIN => {
|
||||
const_io_error!(
|
||||
ErrorKind::Other,
|
||||
"The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance."
|
||||
)
|
||||
}
|
||||
Status::CONNECTION_REFUSED => {
|
||||
const_io_error!(
|
||||
ErrorKind::ConnectionRefused,
|
||||
"The receiving or transmission operation fails because this connection is refused."
|
||||
)
|
||||
}
|
||||
Status::CONNECTION_RESET => {
|
||||
const_io_error!(
|
||||
ErrorKind::ConnectionReset,
|
||||
"The connect fails because the connection is reset either by instance itself or the communication peer."
|
||||
)
|
||||
}
|
||||
Status::CRC_ERROR => const_io_error!(ErrorKind::Other, "A CRC error was detected."),
|
||||
Status::DEVICE_ERROR => const_io_error!(
|
||||
ErrorKind::Other,
|
||||
"The physical device reported an error while attempting the operation."
|
||||
),
|
||||
Status::END_OF_FILE => {
|
||||
const_io_error!(ErrorKind::UnexpectedEof, "The end of the file was reached.")
|
||||
}
|
||||
Status::END_OF_MEDIA => {
|
||||
const_io_error!(ErrorKind::Other, "Beginning or end of media was reached")
|
||||
}
|
||||
Status::HOST_UNREACHABLE => {
|
||||
const_io_error!(ErrorKind::HostUnreachable, "The remote host is not reachable.")
|
||||
}
|
||||
Status::HTTP_ERROR => {
|
||||
const_io_error!(ErrorKind::Other, "A HTTP error occurred during the network operation.")
|
||||
}
|
||||
Status::ICMP_ERROR => {
|
||||
const_io_error!(
|
||||
ErrorKind::Other,
|
||||
"An ICMP error occurred during the network operation."
|
||||
)
|
||||
}
|
||||
Status::INCOMPATIBLE_VERSION => {
|
||||
const_io_error!(
|
||||
ErrorKind::Other,
|
||||
"The function encountered an internal version that was incompatible with a version requested by the caller."
|
||||
)
|
||||
}
|
||||
Status::INVALID_LANGUAGE => {
|
||||
const_io_error!(ErrorKind::InvalidData, "The language specified was invalid.")
|
||||
}
|
||||
Status::INVALID_PARAMETER => {
|
||||
const_io_error!(ErrorKind::InvalidInput, "A parameter was incorrect.")
|
||||
}
|
||||
Status::IP_ADDRESS_CONFLICT => {
|
||||
const_io_error!(ErrorKind::AddrInUse, "There is an address conflict address allocation")
|
||||
}
|
||||
Status::LOAD_ERROR => {
|
||||
const_io_error!(ErrorKind::Other, "The image failed to load.")
|
||||
}
|
||||
Status::MEDIA_CHANGED => {
|
||||
const_io_error!(
|
||||
ErrorKind::Other,
|
||||
"The medium in the device has changed since the last access."
|
||||
)
|
||||
}
|
||||
Status::NETWORK_UNREACHABLE => {
|
||||
const_io_error!(
|
||||
ErrorKind::NetworkUnreachable,
|
||||
"The network containing the remote host is not reachable."
|
||||
)
|
||||
}
|
||||
Status::NO_MAPPING => {
|
||||
const_io_error!(ErrorKind::Other, "A mapping to a device does not exist.")
|
||||
}
|
||||
Status::NO_MEDIA => {
|
||||
const_io_error!(
|
||||
ErrorKind::Other,
|
||||
"The device does not contain any medium to perform the operation."
|
||||
)
|
||||
}
|
||||
Status::NO_RESPONSE => {
|
||||
const_io_error!(
|
||||
ErrorKind::HostUnreachable,
|
||||
"The server was not found or did not respond to the request."
|
||||
)
|
||||
}
|
||||
Status::NOT_FOUND => const_io_error!(ErrorKind::NotFound, "The item was not found."),
|
||||
Status::NOT_READY => {
|
||||
const_io_error!(ErrorKind::ResourceBusy, "There is no data pending upon return.")
|
||||
}
|
||||
Status::NOT_STARTED => {
|
||||
const_io_error!(ErrorKind::Other, "The protocol has not been started.")
|
||||
}
|
||||
Status::OUT_OF_RESOURCES => {
|
||||
const_io_error!(ErrorKind::OutOfMemory, "A resource has run out.")
|
||||
}
|
||||
Status::PROTOCOL_ERROR => {
|
||||
const_io_error!(
|
||||
ErrorKind::Other,
|
||||
"A protocol error occurred during the network operation."
|
||||
)
|
||||
}
|
||||
Status::PROTOCOL_UNREACHABLE => {
|
||||
const_io_error!(ErrorKind::Other, "An ICMP protocol unreachable error is received.")
|
||||
}
|
||||
Status::SECURITY_VIOLATION => {
|
||||
const_io_error!(
|
||||
ErrorKind::PermissionDenied,
|
||||
"The function was not performed due to a security violation."
|
||||
)
|
||||
}
|
||||
Status::TFTP_ERROR => {
|
||||
const_io_error!(ErrorKind::Other, "A TFTP error occurred during the network operation.")
|
||||
}
|
||||
Status::TIMEOUT => const_io_error!(ErrorKind::TimedOut, "The timeout time expired."),
|
||||
Status::UNSUPPORTED => {
|
||||
const_io_error!(ErrorKind::Unsupported, "The operation is not supported.")
|
||||
}
|
||||
Status::VOLUME_FULL => {
|
||||
const_io_error!(ErrorKind::StorageFull, "There is no more space on the file system.")
|
||||
}
|
||||
Status::VOLUME_CORRUPTED => {
|
||||
const_io_error!(
|
||||
ErrorKind::Other,
|
||||
"An inconstancy was detected on the file system causing the operating to fail."
|
||||
)
|
||||
}
|
||||
Status::WRITE_PROTECTED => {
|
||||
const_io_error!(ErrorKind::ReadOnlyFilesystem, "The device cannot be written to.")
|
||||
}
|
||||
_ => io::Error::new(ErrorKind::Uncategorized, format!("Status: {}", s.as_usize())),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_event(
|
||||
signal: u32,
|
||||
tpl: efi::Tpl,
|
||||
|
@ -288,7 +120,7 @@ pub(crate) fn create_event(
|
|||
(create_event)(signal, tpl, handler, context, &mut exit_boot_service_event)
|
||||
};
|
||||
if r.is_error() {
|
||||
Err(status_to_io_error(r))
|
||||
Err(crate::io::Error::from_raw_os_error(r.as_usize()))
|
||||
} else {
|
||||
NonNull::new(exit_boot_service_event)
|
||||
.ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
|
||||
|
@ -305,5 +137,5 @@ pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result
|
|||
(close_event)(evt.as_ptr())
|
||||
};
|
||||
|
||||
if r.is_error() { Err(status_to_io_error(r)) } else { Ok(()) }
|
||||
if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
pub mod net;
|
||||
#[path = "../unsupported/once.rs"]
|
||||
pub mod once;
|
||||
#[path = "../unsupported/os.rs"]
|
||||
pub mod os;
|
||||
#[path = "../windows/os_str.rs"]
|
||||
pub mod os_str;
|
||||
|
@ -52,6 +51,8 @@
|
|||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub type RawOsError = usize;
|
||||
|
||||
use crate::cell::Cell;
|
||||
use crate::io as std_io;
|
||||
use crate::os::uefi;
|
||||
|
@ -110,14 +111,50 @@ pub const fn unsupported_err() -> std_io::Error {
|
|||
std_io::const_io_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",)
|
||||
}
|
||||
|
||||
pub fn decode_error_kind(code: i32) -> crate::io::ErrorKind {
|
||||
pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind {
|
||||
use crate::io::ErrorKind;
|
||||
use r_efi::efi::Status;
|
||||
|
||||
if let Ok(code) = usize::try_from(code) {
|
||||
helpers::status_to_io_error(Status::from_usize(code)).kind()
|
||||
} else {
|
||||
ErrorKind::Uncategorized
|
||||
match r_efi::efi::Status::from_usize(code) {
|
||||
Status::ALREADY_STARTED
|
||||
| Status::COMPROMISED_DATA
|
||||
| Status::CONNECTION_FIN
|
||||
| Status::CRC_ERROR
|
||||
| Status::DEVICE_ERROR
|
||||
| Status::END_OF_MEDIA
|
||||
| Status::HTTP_ERROR
|
||||
| Status::ICMP_ERROR
|
||||
| Status::INCOMPATIBLE_VERSION
|
||||
| Status::LOAD_ERROR
|
||||
| Status::MEDIA_CHANGED
|
||||
| Status::NO_MAPPING
|
||||
| Status::NO_MEDIA
|
||||
| Status::NOT_STARTED
|
||||
| Status::PROTOCOL_ERROR
|
||||
| Status::PROTOCOL_UNREACHABLE
|
||||
| Status::TFTP_ERROR
|
||||
| Status::VOLUME_CORRUPTED => ErrorKind::Other,
|
||||
Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => ErrorKind::InvalidData,
|
||||
Status::ABORTED => ErrorKind::ConnectionAborted,
|
||||
Status::ACCESS_DENIED => ErrorKind::PermissionDenied,
|
||||
Status::BUFFER_TOO_SMALL => ErrorKind::FileTooLarge,
|
||||
Status::CONNECTION_REFUSED => ErrorKind::ConnectionRefused,
|
||||
Status::CONNECTION_RESET => ErrorKind::ConnectionReset,
|
||||
Status::END_OF_FILE => ErrorKind::UnexpectedEof,
|
||||
Status::HOST_UNREACHABLE => ErrorKind::HostUnreachable,
|
||||
Status::INVALID_PARAMETER => ErrorKind::InvalidInput,
|
||||
Status::IP_ADDRESS_CONFLICT => ErrorKind::AddrInUse,
|
||||
Status::NETWORK_UNREACHABLE => ErrorKind::NetworkUnreachable,
|
||||
Status::NO_RESPONSE => ErrorKind::HostUnreachable,
|
||||
Status::NOT_FOUND => ErrorKind::NotFound,
|
||||
Status::NOT_READY => ErrorKind::ResourceBusy,
|
||||
Status::OUT_OF_RESOURCES => ErrorKind::OutOfMemory,
|
||||
Status::SECURITY_VIOLATION => ErrorKind::PermissionDenied,
|
||||
Status::TIMEOUT => ErrorKind::TimedOut,
|
||||
Status::UNSUPPORTED => ErrorKind::Unsupported,
|
||||
Status::VOLUME_FULL => ErrorKind::StorageFull,
|
||||
Status::WRITE_PROTECTED => ErrorKind::ReadOnlyFilesystem,
|
||||
_ => ErrorKind::Uncategorized,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
213
library/std/src/sys/uefi/os.rs
Normal file
213
library/std/src/sys/uefi/os.rs
Normal file
|
@ -0,0 +1,213 @@
|
|||
use super::{unsupported, RawOsError};
|
||||
use crate::error::Error as StdError;
|
||||
use crate::ffi::{OsStr, OsString};
|
||||
use crate::fmt;
|
||||
use crate::io;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::path::{self, PathBuf};
|
||||
|
||||
pub fn errno() -> RawOsError {
|
||||
0
|
||||
}
|
||||
|
||||
pub fn error_string(errno: RawOsError) -> String {
|
||||
use r_efi::efi::Status;
|
||||
|
||||
// Keep the List in Alphabetical Order
|
||||
// The Messages are taken from UEFI Specification Appendix D - Status Codes
|
||||
match r_efi::efi::Status::from_usize(errno) {
|
||||
Status::ABORTED => "The operation was aborted.".to_owned(),
|
||||
Status::ACCESS_DENIED => "Access was denied.".to_owned(),
|
||||
Status::ALREADY_STARTED => "The protocol has already been started.".to_owned(),
|
||||
Status::BAD_BUFFER_SIZE => "The buffer was not the proper size for the request.".to_owned(),
|
||||
Status::BUFFER_TOO_SMALL => {
|
||||
"The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs.".to_owned()
|
||||
}
|
||||
Status::COMPROMISED_DATA => {
|
||||
"The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status.".to_owned()
|
||||
}
|
||||
Status::CONNECTION_FIN => {
|
||||
"The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance.".to_owned()
|
||||
}
|
||||
Status::CONNECTION_REFUSED => {
|
||||
"The receiving or transmission operation fails because this connection is refused.".to_owned()
|
||||
}
|
||||
Status::CONNECTION_RESET => {
|
||||
"The connect fails because the connection is reset either by instance itself or the communication peer.".to_owned()
|
||||
}
|
||||
Status::CRC_ERROR => "A CRC error was detected.".to_owned(),
|
||||
Status::DEVICE_ERROR => "The physical device reported an error while attempting the operation.".to_owned()
|
||||
,
|
||||
Status::END_OF_FILE => {
|
||||
"The end of the file was reached.".to_owned()
|
||||
}
|
||||
Status::END_OF_MEDIA => {
|
||||
"Beginning or end of media was reached".to_owned()
|
||||
}
|
||||
Status::HOST_UNREACHABLE => {
|
||||
"The remote host is not reachable.".to_owned()
|
||||
}
|
||||
Status::HTTP_ERROR => {
|
||||
"A HTTP error occurred during the network operation.".to_owned()
|
||||
}
|
||||
Status::ICMP_ERROR => {
|
||||
"An ICMP error occurred during the network operation.".to_owned()
|
||||
}
|
||||
Status::INCOMPATIBLE_VERSION => {
|
||||
"The function encountered an internal version that was incompatible with a version requested by the caller.".to_owned()
|
||||
}
|
||||
Status::INVALID_LANGUAGE => {
|
||||
"The language specified was invalid.".to_owned()
|
||||
}
|
||||
Status::INVALID_PARAMETER => {
|
||||
"A parameter was incorrect.".to_owned()
|
||||
}
|
||||
Status::IP_ADDRESS_CONFLICT => {
|
||||
"There is an address conflict address allocation".to_owned()
|
||||
}
|
||||
Status::LOAD_ERROR => {
|
||||
"The image failed to load.".to_owned()
|
||||
}
|
||||
Status::MEDIA_CHANGED => {
|
||||
"The medium in the device has changed since the last access.".to_owned()
|
||||
}
|
||||
Status::NETWORK_UNREACHABLE => {
|
||||
"The network containing the remote host is not reachable.".to_owned()
|
||||
}
|
||||
Status::NO_MAPPING => {
|
||||
"A mapping to a device does not exist.".to_owned()
|
||||
}
|
||||
Status::NO_MEDIA => {
|
||||
"The device does not contain any medium to perform the operation.".to_owned()
|
||||
}
|
||||
Status::NO_RESPONSE => {
|
||||
"The server was not found or did not respond to the request.".to_owned()
|
||||
}
|
||||
Status::NOT_FOUND => "The item was not found.".to_owned(),
|
||||
Status::NOT_READY => {
|
||||
"There is no data pending upon return.".to_owned()
|
||||
}
|
||||
Status::NOT_STARTED => {
|
||||
"The protocol has not been started.".to_owned()
|
||||
}
|
||||
Status::OUT_OF_RESOURCES => {
|
||||
"A resource has run out.".to_owned()
|
||||
}
|
||||
Status::PROTOCOL_ERROR => {
|
||||
"A protocol error occurred during the network operation.".to_owned()
|
||||
}
|
||||
Status::PROTOCOL_UNREACHABLE => {
|
||||
"An ICMP protocol unreachable error is received.".to_owned()
|
||||
}
|
||||
Status::SECURITY_VIOLATION => {
|
||||
"The function was not performed due to a security violation.".to_owned()
|
||||
}
|
||||
Status::TFTP_ERROR => {
|
||||
"A TFTP error occurred during the network operation.".to_owned()
|
||||
}
|
||||
Status::TIMEOUT => "The timeout time expired.".to_owned(),
|
||||
Status::UNSUPPORTED => {
|
||||
"The operation is not supported.".to_owned()
|
||||
}
|
||||
Status::VOLUME_FULL => {
|
||||
"There is no more space on the file system.".to_owned()
|
||||
}
|
||||
Status::VOLUME_CORRUPTED => {
|
||||
"An inconstancy was detected on the file system causing the operating to fail.".to_owned()
|
||||
}
|
||||
Status::WRITE_PROTECTED => {
|
||||
"The device cannot be written to.".to_owned()
|
||||
}
|
||||
_ => format!("Status: {}", errno),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getcwd() -> io::Result<PathBuf> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub fn chdir(_: &path::Path) -> io::Result<()> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub struct SplitPaths<'a>(!, PhantomData<&'a ()>);
|
||||
|
||||
pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
|
||||
panic!("unsupported")
|
||||
}
|
||||
|
||||
impl<'a> Iterator for SplitPaths<'a> {
|
||||
type Item = PathBuf;
|
||||
fn next(&mut self) -> Option<PathBuf> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JoinPathsError;
|
||||
|
||||
pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: AsRef<OsStr>,
|
||||
{
|
||||
Err(JoinPathsError)
|
||||
}
|
||||
|
||||
impl fmt::Display for JoinPathsError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
"not supported on this platform yet".fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for JoinPathsError {
|
||||
#[allow(deprecated)]
|
||||
fn description(&self) -> &str {
|
||||
"not supported on this platform yet"
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current_exe() -> io::Result<PathBuf> {
|
||||
unsupported()
|
||||
}
|
||||
|
||||
pub struct Env(!);
|
||||
|
||||
impl Iterator for Env {
|
||||
type Item = (OsString, OsString);
|
||||
fn next(&mut self) -> Option<(OsString, OsString)> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn env() -> Env {
|
||||
panic!("not supported on this platform")
|
||||
}
|
||||
|
||||
pub fn getenv(_: &OsStr) -> Option<OsString> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
|
||||
Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
|
||||
}
|
||||
|
||||
pub fn unsetenv(_: &OsStr) -> io::Result<()> {
|
||||
Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
|
||||
}
|
||||
|
||||
pub fn temp_dir() -> PathBuf {
|
||||
panic!("no filesystem on this platform")
|
||||
}
|
||||
|
||||
pub fn home_dir() -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn exit(_code: i32) -> ! {
|
||||
crate::intrinsics::abort()
|
||||
}
|
||||
|
||||
pub fn getpid() -> u32 {
|
||||
panic!("no pids on this platform")
|
||||
}
|
Loading…
Reference in a new issue