Skip to main content

SourceDirectory

Struct SourceDirectory 

Source
pub struct SourceDirectory { /* private fields */ }
Expand description

A directory beneath the root. Every name is a single entry of it.

Implementations§

Source§

impl SourceDirectory

Source

pub fn write( &self, name: &str, access: Option<&Access>, bytes: &[u8], ) -> Result<(), AccessError>

Writes a new file name with bytes and syncs it. Whatever was at name is removed first, so a link or hard link there is never written through. With access, the file is its owner’s alone until written, then takes that mode and group, and on Linux no access control list it would get from the directory; it must have the labels of access, which is checked before anything is written. Where there are no modes, it is read-only if access has no write bits. Without access, it has the platform’s default.

Source

pub fn create( &self, name: &str, access: Option<&Access>, bytes: &[u8], ) -> Result<(), AccessError>

Creates a new file name holding bytes and syncs it, only if nothing is at name: for callers that must never replace or remove a file that is not theirs, such as one writing output a user named. name is checked as for write, and access means what it does there.

What it promises on every platform:

  • The file is made by an exclusive create (O_CREAT | O_EXCL on Unix, CREATE_NEW on Windows), which fails if anything is at the name, a link or a dangling link included, and follows none. Then the error is AccessError::Io of kind AlreadyExists, and AccessError::already_exists says so.
  • Nothing that was at the name before the call is removed, replaced or written through, on success or on any error. Something another process puts at the name while a create is failing is removed only in the Unix window below; on Windows nothing is removed.
  • All of bytes is written and the file is synced (fsync; on macOS F_FULLFSYNC, as std syncs) before it succeeds. As with write, the directory is not synced: call sync to make the new name durable.

When it fails after making the file, as when the disk is full or access cannot be given:

  • On Unix the file is removed only if the entry at name is still the file it made: same device and inode as the open file, read without following a link. However many links the file has, the name is still that file’s, so removing it removes no one else’s data. Between that check and the removal (unlinkat), a window of the order of a microsecond, another process that renames a file over the name, over the new file, has its file removed; that is the only file at risk. POSIX has no call that removes a name only if it is a given file, so this window cannot be closed. Where the file is not removed, AccessError::may_be_left says so.
  • On Windows the file is never removed: std gives no way to tell the entry at a path is the file it made, so a partly written file may be left at the name, and AccessError::may_be_left says so. Removing it is the caller’s choice.

What it cannot promise: on Unix the directory is the one this handle opened, but a process that can change an ancestor can move or replace it, and the file is then made where the handle is. On Windows every step is by path, after the directory’s components were checked for reparse points when it was opened, so a local process changing the tree at the same time can redirect where the file is made (but the create still never replaces an entry).

Source

pub fn access(&self, name: &str) -> Result<Option<Access>, AccessError>

Who may use the regular file name; None when there is no regular file there. A file whose access publishing could not keep is refused: on Linux one with an access control list, and on Windows a read-only or encrypted one. macOS and Windows access control lists are neither read nor kept.

Source

pub fn own_access(&self) -> Result<Access, AccessError>

Who may use this directory. On Linux, a directory with an access control list, its own or one it gives new files, is refused.

Source

pub fn set_own_access(&self, access: &Access) -> Result<(), AccessError>

Gives this directory the mode and group of access, and checks that it has the labels of access.

Source

pub fn check_final_name( &self, staged: &str, name: &str, ) -> Result<(), AccessError>

Checks, before either is made, that a file made here as name would get the access control beside the mode bits that one made as staged would: on Linux with SELinux, the label its policy gives a new file of that name, which may depend on the name and is not given again on renaming. Elsewhere there is nothing to check.

Source

pub fn rename(&self, from: &str, to: &str) -> Result<(), AccessError>

Renames from to to, replacing to, atomically.

Source

pub fn remove_file(&self, name: &str) -> Result<bool, AccessError>

Removes the file name; false when there was none.

Source

pub fn remove_directory(&self, name: &str) -> Result<bool, AccessError>

Removes the directory name if it is empty; false when it is missing or not empty.

Source

pub fn unchecked_file_system( &self, mounts: &Mounts, ) -> Result<Option<String>, AccessError>

The file system this directory is on, in words, where publishing does not read the access control lists of what is in it: on Linux any but the local ones that keep them as the attributes publishing reads (ext2, ext3, ext4, XFS, Btrfs, tmpfs, F2FS, ZFS and bcachefs), so network, host-shared (such as WSL’s Windows drives or a virtual machine’s shared folders), FUSE, NTFS and stacked ones (overlayfs) among them. The directory’s mount is found by its ID in mounts, and both the type the kernel names it with and the magic number statfs gives must be such a file system’s; one that cannot be told, as where /proc cannot be read or the mount’s line is malformed, is not checked either, and says why. None where it is checked, and on other platforms, which do not read access control lists at all.

Source

pub fn sync(&self) -> Result<bool, AccessError>

Syncs the directory, making renames and removals in it durable. Returns false on platforms that cannot sync a directory, where they may not be durable yet.

Auto Trait Implementations§

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> 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> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.