cap_primitives/fs/
stat.rs1#[cfg(racy_asserts)]
4use crate::fs::{canonicalize, map_result, stat_unchecked};
5use crate::fs::{stat_impl, FollowSymlinks, Metadata};
6use std::path::Path;
7use std::{fs, io};
8
9#[cfg_attr(not(racy_asserts), allow(clippy::let_and_return))]
12#[inline]
13pub fn stat(start: &fs::File, path: &Path, follow: FollowSymlinks) -> io::Result<Metadata> {
14 let result = stat_impl(start, path, follow);
16
17 #[cfg(racy_asserts)]
18 let stat = stat_unchecked(start, path, follow);
19
20 #[cfg(racy_asserts)]
21 check_stat(start, path, follow, &result, &stat);
22
23 result
24}
25
26#[cfg(racy_asserts)]
27#[allow(clippy::enum_glob_use)]
28fn check_stat(
29 start: &fs::File,
30 path: &Path,
31 follow: FollowSymlinks,
32 result: &io::Result<Metadata>,
33 stat: &io::Result<Metadata>,
34) {
35 use io::ErrorKind::*;
36
37 match (map_result(result), map_result(stat)) {
38 (Ok(metadata), Ok(unchecked_metadata)) => {
39 assert_same_file_metadata!(
40 metadata,
41 unchecked_metadata,
42 "path resolution inconsistency: start='{:?}', path='{}'",
43 start,
44 path.display(),
45 );
46 }
47
48 (Err((PermissionDenied, message)), _) => {
49 if let FollowSymlinks::Yes = follow {
50 match map_result(&canonicalize(start, path)) {
51 Ok(_) => (),
52 Err((PermissionDenied, canon_message)) => {
53 assert_eq!(message, canon_message);
54 }
55 err => panic!("stat failed where canonicalize succeeded: {:?}", err),
56 }
57 } else {
58 }
61 }
62
63 (Err((kind, message)), Err((unchecked_kind, unchecked_message))) => {
64 assert_eq!(kind, unchecked_kind);
65 assert_eq!(
66 message,
67 unchecked_message,
68 "start='{:?}', path='{:?}'",
69 start,
70 path.display()
71 );
72 }
73
74 other => panic!(
75 "unexpected result from stat start='{:?}', path='{}':\n{:#?}",
76 start,
77 path.display(),
78 other,
79 ),
80 }
81}