cap_primitives/fs/manually/
open_entry.rs

1use super::{internal_open, read_link_one};
2use crate::fs::{open_unchecked, FollowSymlinks, MaybeOwnedFile, OpenOptions, OpenUncheckedError};
3use std::ffi::OsStr;
4use std::path::PathBuf;
5use std::{fs, io};
6
7pub(crate) fn open_entry(
8    start: &fs::File,
9    path: &OsStr,
10    options: &OpenOptions,
11) -> io::Result<fs::File> {
12    match open_unchecked(
13        start,
14        path.as_ref(),
15        options.clone().follow(FollowSymlinks::No),
16    ) {
17        Ok(file) => Ok(file),
18        Err(OpenUncheckedError::Symlink(_, _)) if options.follow == FollowSymlinks::Yes => {
19            let mut symlink_count = 0;
20            let destination = read_link_one(start, path, &mut symlink_count, PathBuf::new())?;
21            let maybe = MaybeOwnedFile::borrowed(start);
22            internal_open(maybe, &destination, options, &mut symlink_count, None)
23                .map(MaybeOwnedFile::unwrap_owned)
24        }
25        Err(OpenUncheckedError::NotFound(err))
26        | Err(OpenUncheckedError::Other(err))
27        | Err(OpenUncheckedError::Symlink(err, _)) => Err(err),
28    }
29}