Skip to main content

RootRef

Struct RootRef 

Source
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<'_>

Source

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.

Source

pub fn resolver_flags(&self) -> ResolverFlags

Get the current ResolverFlags for this RootRef.

Source

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.

Source

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")?;
Source

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).

Source

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.

Source

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.

Source

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):

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.

Source

pub fn create( &self, path: impl AsRef<Path>, inode_type: &InodeType, ) -> Result<(), Error>

Within the RootRef’s tree, create an inode at path as specified by inode_type.

§Errors

If the path already exists (regardless of the type of the existing inode), an error is returned.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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<'_>

Source§

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> Clone for RootRef<'fd>

Source§

fn clone(&self) -> RootRef<'fd>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'fd> Debug for RootRef<'fd>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'fd> From<BorrowedFd<'fd>> for RootRef<'fd>

Source§

fn from(fd: BorrowedFd<'fd>) -> Self

Shorthand for RootRef::from_fd.

Source§

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.