unix.rs - source
Description: Source of the Rust file `library/std/src/sys/path/unix.rs`.

#
std/sys/path/
unix.rs

    1use crate::ffi::OsStr;
    2use crate::path::{Path, PathBuf, Prefix};
    3use crate::{env, io};
    4
    5#[inline]
    6pub fn is_sep_byte(b: u8) -> bool {
    7    b == b'/'
    8}
    9
    10#[inline]
    11pub fn is_verbatim_sep(b: u8) -> bool {
    12    b == b'/'
    13}
    14
    15#[inline]
    16pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
    17    None
    18}
    19
    20pub const HAS_PREFIXES: bool = false;
    21pub const MAIN_SEP_STR: &str = "/";
    22pub const MAIN_SEP: char = '/';
    23
    24/// Make a POSIX path absolute without changing its semantics.
    25pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
    26    // This is mostly a wrapper around collecting `Path::components`, with
    27    // exceptions made where this conflicts with the POSIX specification.
    28    // See 4.13 Pathname Resolution, IEEE Std 1003.1-2017
    29    // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
    30
    31    // Get the components, skipping the redundant leading "." component if it exists.
    32    let mut components = path.strip_prefix(".").unwrap_or(path).components();
    33    let path_os = path.as_os_str().as_encoded_bytes();
    34
    35    let mut normalized = if path.is_absolute() {
    36        // "If a pathname begins with two successive <slash> characters, the
    37        // first component following the leading <slash> characters may be
    38        // interpreted in an implementation-defined manner, although more than
    39        // two leading <slash> characters shall be treated as a single <slash>
    40        // character."
    41        if path_os.starts_with(b"//") && !path_os.starts_with(b"///") {
    42            components.next();
    43            PathBuf::from("//")
    44        } else {
    45            PathBuf::new()
    46        }
    47    } else {
    48        env::current_dir()?
    49    };
    50    normalized.extend(components);
    51
    52    // "Interfaces using pathname resolution may specify additional constraints
    53    // when a pathname that does not name an existing directory contains at
    54    // least one non- <slash> character and contains one or more trailing
    55    // <slash> characters".
    56    // A trailing <slash> is also meaningful if "a symbolic link is
    57    // encountered during pathname resolution".
    58    if path_os.ends_with(b"/") {
    59        normalized.push("");
    60    }
    61
    62    Ok(normalized)
    63}
    64
    65pub(crate) fn is_absolute(path: &Path) -> bool {
    66    if cfg!(any(unix, target_os = "hermit", target_os = "wasi", target_os = "motor")) {
    67        path.has_root()
    68    } else {
    69        path.has_root() && path.prefix().is_some()
    70    }
    71}