pub struct RootRef<'fd> { /* private fields */ }Expand description
Borrowed version of Root.
Unlike Root, when RootRef is dropped the underlying file descriptor
is not closed. This is mainly useful for programs and libraries that have
to do operations on &Files and BorrowedFds passed from
elsewhere.
Implementations§
Source§impl RootRef<'_>
impl RootRef<'_>
Sourcepub fn from_fd(inner: BorrowedFd<'_>) -> RootRef<'_>
pub fn from_fd(inner: BorrowedFd<'_>) -> RootRef<'_>
Wrap a BorrowedFd into a RootRef.
The BorrowedFd should be a file descriptor referencing a directory,
otherwise all Root operations will fail.
The configuration is set to the system default and should be configured prior to usage, if appropriate.
Sourcepub fn resolver_flags(&self) -> ResolverFlags
pub fn resolver_flags(&self) -> ResolverFlags
Get the current ResolverFlags for this RootRef.
Sourcepub fn set_resolver_flags(&mut self, flags: ResolverFlags) -> &mut Self
pub fn set_resolver_flags(&mut self, flags: ResolverFlags) -> &mut Self
Set the ResolverFlags for all operations in this RootRef.
Note that this only affects this instance of RootRef. Neither the
original Root nor any other RootRef references to the same
underlying Root will have their ResolverFlags unchanged.
RootRef::clone also copies the current ResolverFlags of the
RootRef.
Sourcepub fn with_resolver_flags(self, flags: ResolverFlags) -> Self
pub fn with_resolver_flags(self, flags: ResolverFlags) -> Self
Set the ResolverFlags for all operations in this RootRef.
This is identical to RootRef::set_resolver_flags except that it can
more easily be used with chaining to configure a RootRef in a single
line:
let fd: OwnedFd = File::open(rootdir)?.into();
let root = RootRef::from_fd(fd.as_fd())
.with_resolver_flags(ResolverFlags::NO_SYMLINKS);
// Continue to use RootRef.
root.mkdir_all("foo/bar/baz", &perm)?;
root.create("one", &InodeType::Directory(perm))?;
root.remove_all("foo")?;The other primary usecase for RootRef::with_resolver_flags is with
Root::as_ref to temporarily set some flags for a single one-line or
a few operations without modifying the original Root resolver flags:
let root = Root::open(rootdir)?;
// Apply ResolverFlags::NO_SYMLINKS for a single operation.
root.as_ref()
.with_resolver_flags(ResolverFlags::NO_SYMLINKS)
.mkdir_all("foo/bar/baz", &perm)?;
// Create a temporary RootRef to do multiple operations.
let root2 = root
.as_ref()
.with_resolver_flags(ResolverFlags::NO_SYMLINKS);
root2.create("one", &InodeType::Directory(perm))?;
root2.remove_all("foo")?;Sourcepub fn try_clone(&self) -> Result<Root, Error>
pub fn try_clone(&self) -> Result<Root, Error>
Create a copy of a RootRef.
Note that (unlike BorrowedFd::clone) this method creates a full copy
of the underlying file descriptor and thus is more equivalent to
BorrowedFd::try_clone_to_owned.
To create a shallow copy of a RootRef, you can use Clone::clone
(or just Copy).
Sourcepub fn resolve(&self, path: impl AsRef<Path>) -> Result<Handle, Error>
pub fn resolve(&self, path: impl AsRef<Path>) -> Result<Handle, Error>
Within the given RootRef’s tree, resolve path and return a
Handle.
All symlink path components are scoped to RootRef. Trailing symlinks
are followed, if you want to get a handle to a symlink use
resolve_nofollow.
§Errors
If path doesn’t exist, or an attack was detected during resolution, a
corresponding Error will be returned. If no error is returned, then
the path is guaranteed to have been reachable from the root of the
directory tree and thus have been inside the root at one point in the
resolution.
Sourcepub fn resolve_nofollow(&self, path: impl AsRef<Path>) -> Result<Handle, Error>
pub fn resolve_nofollow(&self, path: impl AsRef<Path>) -> Result<Handle, Error>
Identical to resolve, except that trailing symlinks are not
followed.
If the trailing component is a symlink resolve_nofollow will return
a handle to the symlink itself. This is effectively equivalent to
O_NOFOLLOW.
Sourcepub fn open_subpath(
&self,
path: impl AsRef<Path>,
flags: impl Into<OpenFlags>,
) -> Result<File, Error>
pub fn open_subpath( &self, path: impl AsRef<Path>, flags: impl Into<OpenFlags>, ) -> Result<File, Error>
Open a path without creating an intermediate Handle object.
This is effectively just shorthand for resolve followed by
Handle::reopen. However, some resolvers (such as the openat2
resolver) can implement open_subpath slightly more efficiently than
naively doing a two-step open operation with Handle::reopen. If you
wish to create an OpenFlags::O_PATH file handle, it probably makes
more sense to use resolve or resolve_nofollow.
If flags contains OpenFlags::O_NOFOLLOW and the path refers to a
symlink then this method will match the behaviour of openat2 (this
is in contrast to Handle::reopen which does not permit re-opening a
handle to a symlink):
- If
flagsalso containsOpenFlags::O_PATHthen the returned file is equivalent to theHandlethat would’ve been returned fromresolve_nofollow. - Otherwise, an error will be returned to match the behaviour of
OpenFlags::O_NOFOLLOWwhen encountering a trailing symlink.
Sourcepub fn readlink(&self, path: impl AsRef<Path>) -> Result<PathBuf, Error>
pub fn readlink(&self, path: impl AsRef<Path>) -> Result<PathBuf, Error>
Get the target of a symlink within a RootRef.
NOTE: The returned path is not modified to be “safe” outside of the
root. You should not use this path for doing further path lookups – use
resolve instead.
This method is just shorthand for calling readlinkat(2) on the handle
returned by resolve_nofollow.
Sourcepub fn create_file(
&self,
path: impl AsRef<Path>,
flags: impl Into<OpenFlags>,
perm: &Permissions,
) -> Result<File, Error>
pub fn create_file( &self, path: impl AsRef<Path>, flags: impl Into<OpenFlags>, perm: &Permissions, ) -> Result<File, Error>
Create an InodeType::File within the RootRef’s tree at path
with the mode given by perm, and return a Handle to the
newly-created file.
However, unlike the trivial way of doing the above:
root.create(path, inode_type)?;
// What happens if the file is replaced here!?
let handle = root.resolve(path, perm)?;create_file guarantees that the returned Handle is the same as
the file created by the operation. This is only possible to guarantee
for ordinary files because there is no O_CREAT-equivalent for other
inode types.
§Errors
Identical to create.
Sourcepub fn mkdir_all(
&self,
path: impl AsRef<Path>,
perm: &Permissions,
) -> Result<Handle, Error>
pub fn mkdir_all( &self, path: impl AsRef<Path>, perm: &Permissions, ) -> Result<Handle, Error>
Within the RootRef’s tree, create a directory and any of its parent
component if they are missing.
This is effectively equivalent to std::fs::create_dir_all, Go’s
os.MkdirAll, or Unix’s mkdir -p.
The provided set of Permissions only applies to path components
created by this function, existing components will not have their
permissions modified. In addition, if the provided path already exists
and is a directory, this function will return successfully.
The returned Handle is an O_DIRECTORY handle referencing the
created directory (due to kernel limitations, we cannot guarantee that
the handle is the exact directory created and not a similar-looking
directory that was swapped in by an attacker, but we do as much
validation as possible to make sure the directory is functionally
identical to the directory we would’ve created).
§Errors
This method will return an error if any of the path components in the provided path were invalid (non-directory components or dangling symlink components) or if certain exchange attacks were detected.
If an error occurs, it is possible for any number of the directories in
path to have been created despite this method returning an error.
Sourcepub fn remove_dir(&self, path: impl AsRef<Path>) -> Result<(), Error>
pub fn remove_dir(&self, path: impl AsRef<Path>) -> Result<(), Error>
Within the RootRef’s tree, remove the empty directory at path.
Any existing Handles to path will continue to work as before,
since Linux does not invalidate file handles to unlinked files (though,
directory handling is not as simple).
§Errors
If the path does not exist, was not actually a directory, or was a
non-empty directory an error will be returned. In order to remove a
directory and all of its children, you can use remove_all.
Sourcepub fn remove_file(&self, path: impl AsRef<Path>) -> Result<(), Error>
pub fn remove_file(&self, path: impl AsRef<Path>) -> Result<(), Error>
Within the RootRef’s tree, remove the file (any non-directory inode)
at path.
Any existing Handles to path will continue to work as before,
since Linux does not invalidate file handles to unlinked files (though,
directory handling is not as simple).
§Errors
If the path does not exist or was actually a directory an error will be
returned. In order to remove a path regardless of its type (even if it
is a non-empty directory), you can use remove_all.
Sourcepub fn remove_all(&self, path: impl AsRef<Path>) -> Result<(), Error>
pub fn remove_all(&self, path: impl AsRef<Path>) -> Result<(), Error>
Within the RootRef’s tree, recursively delete the provided path
and any children it contains if it is a directory. This is effectively
equivalent to std::fs::remove_dir_all, Go’s os.RemoveAll, or
Unix’s rm -r.
Any existing Handles to paths within path will continue to work as
before, since Linux does not invalidate file handles to unlinked files
(though, directory handling is not as simple).
§Errors
If the path does not exist or some other error occurred during the deletion process an error will be returned.
Sourcepub fn rename(
&self,
source: impl AsRef<Path>,
destination: impl AsRef<Path>,
rflags: RenameFlags,
) -> Result<(), Error>
pub fn rename( &self, source: impl AsRef<Path>, destination: impl AsRef<Path>, rflags: RenameFlags, ) -> Result<(), Error>
Within the RootRef’s tree, perform a rename with the given source
and directory. The flags argument is passed directly to
renameat2(2).
§Errors
The error rules are identical to renameat2(2).
Trait Implementations§
Source§impl AsFd for RootRef<'_>
impl AsFd for RootRef<'_>
Source§fn as_fd(&self) -> BorrowedFd<'_>
fn as_fd(&self) -> BorrowedFd<'_>
Access the underlying file descriptor for a RootRef.
Note: This method is primarily intended to allow for tests and other
code to check the status of the underlying file descriptor. It is not
safe to use this BorrowedFd directly to do filesystem operations.
Please use the provided RootRef methods.
Source§impl<'fd> From<BorrowedFd<'fd>> for RootRef<'fd>
impl<'fd> From<BorrowedFd<'fd>> for RootRef<'fd>
Source§fn from(fd: BorrowedFd<'fd>) -> Self
fn from(fd: BorrowedFd<'fd>) -> Self
Shorthand for RootRef::from_fd.
impl<'fd> Copy for RootRef<'fd>
Auto Trait Implementations§
impl<'fd> Freeze for RootRef<'fd>
impl<'fd> RefUnwindSafe for RootRef<'fd>
impl<'fd> Send for RootRef<'fd>
impl<'fd> Sync for RootRef<'fd>
impl<'fd> Unpin for RootRef<'fd>
impl<'fd> UnwindSafe for RootRef<'fd>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more