cap_primitives/fs/manually/
canonicalize.rs1use super::internal_open;
5use crate::fs::{canonicalize_options, FollowSymlinks, MaybeOwnedFile};
6use std::path::{Path, PathBuf};
7use std::{fs, io};
8
9pub(crate) fn canonicalize(start: &fs::File, path: &Path) -> io::Result<PathBuf> {
13 canonicalize_with(start, path, FollowSymlinks::Yes)
14}
15
16pub(crate) fn canonicalize_with(
19 start: &fs::File,
20 path: &Path,
21 follow: FollowSymlinks,
22) -> io::Result<PathBuf> {
23 let mut symlink_count = 0;
24 let mut canonical_path = PathBuf::new();
25 let start = MaybeOwnedFile::borrowed(start);
26
27 match internal_open(
28 start,
29 path,
30 canonicalize_options().follow(follow),
31 &mut symlink_count,
32 Some(&mut canonical_path),
33 ) {
34 Ok(_) => (),
36
37 Err(err) if err.kind() == io::ErrorKind::InvalidInput => {
39 return Err(err);
40 }
41 #[cfg(io_error_more)]
42 Err(err) if err.kind() == io::ErrorKind::InvalidFilename => {
43 return Err(err);
44 }
45 #[cfg(windows)]
46 Err(err)
47 if err.raw_os_error()
48 == Some(windows_sys::Win32::Foundation::ERROR_INVALID_NAME as _)
49 || err.raw_os_error()
50 == Some(windows_sys::Win32::Foundation::ERROR_DIRECTORY as _) =>
51 {
52 return Err(err);
53 }
54
55 Err(err) => {
58 if canonical_path.as_os_str().is_empty() {
59 return Err(err);
60 }
61 }
62 }
63
64 Ok(canonical_path)
65}