-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
set_symlink_permissions
and access
functions to DirExt
`set_symlink_permissions` is to `set_permissions` as `symlink_metadata` is to `metadata`; it doesn't follow symlinks. `access` follows the POSIX `faccessat` behavior.
- Loading branch information
1 parent
9c1e426
commit 37a3033
Showing
17 changed files
with
473 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
//! Access test functions. | ||
use crate::fs::{access_impl, FollowSymlinks}; | ||
#[cfg(racy_asserts)] | ||
use crate::fs::{access_unchecked, file_path}; | ||
use std::path::Path; | ||
use std::{fs, io}; | ||
|
||
/// Access modes for use with [`DirExt::access`]. | ||
#[derive(Clone, Copy, Debug)] | ||
pub struct AccessModes { | ||
/// Is the object readable? | ||
pub readable: bool, | ||
/// Is the object writable? | ||
pub writable: bool, | ||
/// Is the object executable? | ||
pub executable: bool, | ||
} | ||
|
||
/// Access modes for use with [`DirExt::access`]. | ||
#[derive(Clone, Copy, Debug)] | ||
pub enum AccessType { | ||
/// Test whether the named object is accessible in the given modes. | ||
Access(AccessModes), | ||
|
||
/// Test whether the named object exists. | ||
Exists, | ||
} | ||
|
||
/// Canonicalize the given path, ensuring that the resolution of the path never | ||
/// escapes the directory tree rooted at `start`. | ||
#[cfg_attr(not(racy_asserts), allow(clippy::let_and_return))] | ||
pub fn access( | ||
start: &fs::File, | ||
path: &Path, | ||
type_: AccessType, | ||
follow: FollowSymlinks, | ||
) -> io::Result<()> { | ||
// Call the underlying implementation. | ||
let result = access_impl(start, path, type_, follow); | ||
|
||
#[cfg(racy_asserts)] | ||
let unchecked = access_unchecked(start, path, type_, follow); | ||
|
||
#[cfg(racy_asserts)] | ||
check_access(start, path, type_, follow, &result, &unchecked); | ||
|
||
result | ||
} | ||
|
||
#[cfg(racy_asserts)] | ||
#[allow(clippy::enum_glob_use)] | ||
fn check_access( | ||
start: &fs::File, | ||
path: &Path, | ||
_type_: AccessType, | ||
_follow: FollowSymlinks, | ||
result: &io::Result<()>, | ||
unchecked: &io::Result<()>, | ||
) { | ||
use io::ErrorKind::*; | ||
|
||
match (map_result(result), map_result(stat)) { | ||
(Ok(()), Ok(())) => {} | ||
|
||
(Err((PermissionDenied, message)), _) => { | ||
// TODO: Check that access in the no-follow case got the right | ||
// error. | ||
} | ||
|
||
(Err((kind, message)), Err((unchecked_kind, unchecked_message))) => { | ||
assert_eq!(kind, unchecked_kind); | ||
assert_eq!( | ||
message, | ||
unchecked_message, | ||
"start='{:?}', path='{:?}'", | ||
start, | ||
path.display() | ||
); | ||
} | ||
|
||
other => panic!( | ||
"unexpected result from access start='{:?}', path='{}':\n{:#?}", | ||
start, | ||
path.display(), | ||
other, | ||
), | ||
} | ||
} |
Oops, something went wrong.