cap_primitives/fs/
access.rs1use crate::fs::{access_impl, FollowSymlinks};
4#[cfg(racy_asserts)]
5use crate::fs::{access_unchecked, file_path};
6use std::path::Path;
7use std::{fs, io};
8
9#[derive(Clone, Copy, Debug)]
11pub struct AccessModes {
12 pub readable: bool,
14 pub writable: bool,
16 pub executable: bool,
18}
19
20#[derive(Clone, Copy, Debug)]
22pub enum AccessType {
23 Access(AccessModes),
25
26 Exists,
28}
29
30#[cfg_attr(not(racy_asserts), allow(clippy::let_and_return))]
33pub fn access(
34 start: &fs::File,
35 path: &Path,
36 type_: AccessType,
37 follow: FollowSymlinks,
38) -> io::Result<()> {
39 let result = access_impl(start, path, type_, follow);
41
42 #[cfg(racy_asserts)]
43 let unchecked = access_unchecked(start, path, type_, follow);
44
45 #[cfg(racy_asserts)]
46 check_access(start, path, type_, follow, &result, &unchecked);
47
48 result
49}
50
51#[cfg(racy_asserts)]
52#[allow(clippy::enum_glob_use)]
53fn check_access(
54 start: &fs::File,
55 path: &Path,
56 _type_: AccessType,
57 _follow: FollowSymlinks,
58 result: &io::Result<()>,
59 unchecked: &io::Result<()>,
60) {
61 use io::ErrorKind::*;
62
63 match (map_result(result), map_result(stat)) {
64 (Ok(()), Ok(())) => {}
65
66 (Err((PermissionDenied, message)), _) => {
67 }
70
71 (Err((kind, message)), Err((unchecked_kind, unchecked_message))) => {
72 assert_eq!(kind, unchecked_kind);
73 assert_eq!(
74 message,
75 unchecked_message,
76 "start='{:?}', path='{:?}'",
77 start,
78 path.display()
79 );
80 }
81
82 other => panic!(
83 "unexpected result from access start='{:?}', path='{}':\n{:#?}",
84 start,
85 path.display(),
86 other,
87 ),
88 }
89}