]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/unix/path.rs
Rollup merge of #106886 - dtolnay:fastinstall, r=Mark-Simulacrum
[rust.git] / library / std / src / sys / unix / path.rs
1 use crate::env;
2 use crate::ffi::OsStr;
3 use crate::io;
4 use crate::path::{Path, PathBuf, Prefix};
5
6 #[inline]
7 pub fn is_sep_byte(b: u8) -> bool {
8     b == b'/'
9 }
10
11 #[inline]
12 pub fn is_verbatim_sep(b: u8) -> bool {
13     b == b'/'
14 }
15
16 #[inline]
17 pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
18     None
19 }
20
21 pub const MAIN_SEP_STR: &str = "/";
22 pub const MAIN_SEP: char = '/';
23
24 /// Make a POSIX path absolute without changing its semantics.
25 pub(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().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 }