cap_primitives/fs/via_parent/
read_link.rs

1use super::open_parent;
2use crate::fs::{read_link_unchecked, MaybeOwnedFile};
3use std::path::{Path, PathBuf};
4use std::{fs, io};
5
6/// Implement `read_link` by `open`ing up the parent component of the path and
7/// then calling `read_link_unchecked` on the last component.
8///
9/// This technique doesn't work in all cases on Windows. In particular, a
10/// directory symlink such as `C:\Documents and Settings` may not grant any
11/// access other than what is needed to resolve the symlink, so `open_parent`'s
12/// technique of returning a relative path of `.` from that point doesn't work,
13/// because opening `.` within such a directory is denied. Consequently, we use
14/// a different implementation on Windows.
15pub(crate) fn read_link(start: &fs::File, path: &Path) -> io::Result<PathBuf> {
16    let start = MaybeOwnedFile::borrowed(start);
17
18    let (dir, basename) = open_parent(start, path)?;
19
20    read_link_unchecked(&dir, basename.as_ref(), PathBuf::new())
21}