
I am working on fs support for UEFI [0], which similar to windows has prefix components, but is not quite same as Windows. It also seems that Prefix is tied closely to Windows and cannot really be extended [1]. This PR just tries to remove coupling between Prefix and absolute path checking to allow platforms to provide there own implementation to check if a path is absolute or not. I am not sure if any platform other than windows currently uses Prefix, so I have kept the path.prefix().is_some() check in most cases. [0]: https://github.com/rust-lang/rust/pull/135368 [1]: https://github.com/rust-lang/rust/issues/52331#issuecomment-2492796137 Signed-off-by: Ayush Singh <ayush@beagleboard.org>
73 lines
2.4 KiB
Rust
73 lines
2.4 KiB
Rust
use crate::ffi::OsStr;
|
|
use crate::path::{Path, PathBuf, Prefix};
|
|
use crate::{env, io};
|
|
|
|
#[inline]
|
|
pub fn is_sep_byte(b: u8) -> bool {
|
|
b == b'/'
|
|
}
|
|
|
|
#[inline]
|
|
pub fn is_verbatim_sep(b: u8) -> bool {
|
|
b == b'/'
|
|
}
|
|
|
|
#[inline]
|
|
pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
|
|
None
|
|
}
|
|
|
|
pub const MAIN_SEP_STR: &str = "/";
|
|
pub const MAIN_SEP: char = '/';
|
|
|
|
/// Make a POSIX path absolute without changing its semantics.
|
|
pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
|
|
// This is mostly a wrapper around collecting `Path::components`, with
|
|
// exceptions made where this conflicts with the POSIX specification.
|
|
// See 4.13 Pathname Resolution, IEEE Std 1003.1-2017
|
|
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
|
|
|
|
// Get the components, skipping the redundant leading "." component if it exists.
|
|
let mut components = path.strip_prefix(".").unwrap_or(path).components();
|
|
let path_os = path.as_os_str().as_encoded_bytes();
|
|
|
|
let mut normalized = if path.is_absolute() {
|
|
// "If a pathname begins with two successive <slash> characters, the
|
|
// first component following the leading <slash> characters may be
|
|
// interpreted in an implementation-defined manner, although more than
|
|
// two leading <slash> characters shall be treated as a single <slash>
|
|
// character."
|
|
if path_os.starts_with(b"//") && !path_os.starts_with(b"///") {
|
|
components.next();
|
|
PathBuf::from("//")
|
|
} else {
|
|
PathBuf::new()
|
|
}
|
|
} else {
|
|
env::current_dir()?
|
|
};
|
|
normalized.extend(components);
|
|
|
|
// "Interfaces using pathname resolution may specify additional constraints
|
|
// when a pathname that does not name an existing directory contains at
|
|
// least one non- <slash> character and contains one or more trailing
|
|
// <slash> characters".
|
|
// A trailing <slash> is also meaningful if "a symbolic link is
|
|
// encountered during pathname resolution".
|
|
if path_os.ends_with(b"/") {
|
|
normalized.push("");
|
|
}
|
|
|
|
Ok(normalized)
|
|
}
|
|
|
|
pub(crate) fn is_absolute(path: &Path) -> bool {
|
|
if cfg!(target_os = "redox") {
|
|
// FIXME: Allow Redox prefixes
|
|
path.has_root() || crate::path::has_redox_scheme(path.as_u8_slice())
|
|
} else if cfg!(any(unix, target_os = "hermit", target_os = "wasi")) {
|
|
path.has_root()
|
|
} else {
|
|
path.has_root() && path.prefix().is_some()
|
|
}
|
|
}
|