cap_primitives/fs/
open_dir.rs

1//! This defines `open_dir`, a wrapper around `open` which can be used to open
2//! path as a directory.
3
4#[allow(unused_imports)]
5use crate::fs::open_unchecked;
6use crate::fs::{dir_options, open, open_ambient_dir_impl, readdir_options, FollowSymlinks};
7use ambient_authority::AmbientAuthority;
8use std::path::{Component, Path};
9use std::{fs, io};
10
11/// Open a directory by performing an `openat`-like operation,
12/// ensuring that the resolution of the path never escapes
13/// the directory tree rooted at `start`.
14#[inline]
15pub fn open_dir(start: &fs::File, path: &Path) -> io::Result<fs::File> {
16    open(start, path, &dir_options())
17}
18
19/// Like `open_dir`, but additionally request the ability to read the directory
20/// entries.
21#[cfg(not(windows))]
22#[inline]
23pub(crate) fn open_dir_for_reading(
24    start: &fs::File,
25    path: &Path,
26    follow: FollowSymlinks,
27) -> io::Result<fs::File> {
28    open(start, path, readdir_options().follow(follow))
29}
30
31/// Similar to `open_dir`, but fails if the path names a symlink.
32#[inline]
33pub fn open_dir_nofollow(start: &fs::File, path: &Path) -> io::Result<fs::File> {
34    open(start, path, dir_options().follow(FollowSymlinks::No))
35}
36
37/// Open a directory by performing an unsandboxed `openat`-like operation.
38#[inline]
39#[allow(dead_code)]
40pub(crate) fn open_dir_unchecked(start: &fs::File, path: &Path) -> io::Result<fs::File> {
41    open_unchecked(start, path, &dir_options()).map_err(Into::into)
42}
43
44/// Like `open_dir_unchecked`, but additionally request the ability to read the
45/// directory entries.
46#[inline]
47#[allow(dead_code)]
48pub(crate) fn open_dir_for_reading_unchecked(
49    start: &fs::File,
50    path: &Path,
51    follow: FollowSymlinks,
52) -> io::Result<fs::File> {
53    open_unchecked(start, path, readdir_options().follow(follow)).map_err(Into::into)
54}
55
56/// Open a directory named by a bare path, using the host process' ambient
57/// authority.
58///
59/// # Ambient Authority
60///
61/// This function is not sandboxed and may trivially access any path that the
62/// host process has access to.
63#[inline]
64pub fn open_ambient_dir(path: &Path, ambient_authority: AmbientAuthority) -> io::Result<fs::File> {
65    open_ambient_dir_impl(path, ambient_authority)
66}
67
68/// Open the parent directory of a given open directory, using the host
69/// process' ambient authority.
70///
71/// # Ambient Authority
72///
73/// This function accesses a path outside of the `start` directory subtree.
74#[inline]
75pub fn open_parent_dir(
76    start: &fs::File,
77    ambient_authority: AmbientAuthority,
78) -> io::Result<fs::File> {
79    let _ = ambient_authority;
80    open_dir_unchecked(start, Component::ParentDir.as_ref())
81}