Basic cross-platform file accessibility checks for Rust.
pub trait PathExt {
fn access(&self, mode: AccessMode) -> std::io::Result<()>;
fn readable(&self) -> bool;
fn writable(&self) -> bool;
fn executable(&self) -> bool;
}
impl PathExt for std::path::Path;
faccess
provides an extension trait for std::path::Path
which adds an
access
method for checking the accessibility of a path for the given access
permissions — a bitwise-inclusive OR of one or more AccessMode
flags
(EXISTS
, READ
, WRITE
, EXECUTE
).
It also provides convenience methods readable
, writable
, and executable
if only a single permission needs to be checked in a simple boolean fashion.
use std::path::Path;
use faccess::{AccessMode, PathExt};
let path = Path::new("/bin/ls");
assert!(path.access(AccessMode::READ | AccessMode::EXECUTE).is_ok());
assert!(path.readable());
assert!(!path.writable());
assert!(path.executable());
On Unix platforms, access
directly maps to faccessat(2)
, with the
AT_EACCESS
flag used where available to test against the effective user and
group ID's.
On Windows, a complex custom implementation is used to approximate these
semantics in a best-effort fashion, using a mixture of file extension checks,
simply attempting to open a file, GetNamedSecurityInfoW
, and AccessCheck
,
depending on the permissions being checked. This is similar to implementations
found in other languages.
On other platforms it simply proxies to exists()
and readonly()
as appropriate.
There is a history of time-of-check to time-of-use (TOCTOU) bugs with this class of function, particularly with set-user-ID programs relying on them to validate effective user/group permissions prior to accessing files on behalf of other users. They should not be relied upon in a security context.