SharedSystem

Struct SharedSystem 

Source
pub struct SharedSystem(/* private fields */);
Expand description

System shared by a reference counter.

A SharedSystem is a reference-counted container of a System instance accompanied with an internal state for supporting asynchronous interactions with the system. As it is reference-counted, cloning a SharedSystem instance only increments the reference count without cloning the backing system instance. This behavior allows calling SharedSystem’s methods concurrently from different async tasks that each have a SharedSystem instance sharing the same state.

SharedSystem implements System by delegating to the contained system instance. You should avoid calling some of the System methods, however. Prefer async functions provided by SharedSystem (e.g., read_async) over raw system functions (e.g., read).

The following example illustrates how multiple concurrent tasks are run in a single-threaded pool:

let mut system = SharedSystem::new(Box::new(VirtualSystem::new()));
let mut system2 = system.clone();
let mut system3 = system.clone();
let (reader, writer) = system.pipe().unwrap();
let mut executor = futures_executor::LocalPool::new();

// We add a task that tries to read from the pipe, but nothing has been
// written to it, so the task is stalled.
let read_task = executor.spawner().spawn_local_with_handle(async move {
    let mut buffer = [0; 1];
    system.read_async(reader, &mut buffer).await.unwrap();
    buffer[0]
});
executor.run_until_stalled();

// Let's add a task that writes to the pipe.
executor.spawner().spawn_local(async move {
    system2.write_all(writer, &[123]).await.unwrap();
});
executor.run_until_stalled();

// The write task has written a byte to the pipe, but the read task is still
// stalled. We need to wake it up by calling `select`.
system3.select(false).unwrap();

// Now the read task can proceed to the end.
let number = executor.run_until(read_task.unwrap());
assert_eq!(number, 123);

If there is a child process in the VirtualSystem, you should call SystemState::select_all in addition to SharedSystem::select so that the child process task is woken up when needed. (TBD code example)

Implementations§

Source§

impl SharedSystem

Source

pub fn new(system: Box<dyn System>) -> Self

Creates a new shared system.

Source

pub async fn read_async(&self, fd: Fd, buffer: &mut [u8]) -> Result<usize>

Reads from the file descriptor.

This function waits for one or more bytes to be available for reading. If successful, returns the number of bytes read.

Source

pub async fn write_all(&self, fd: Fd, buffer: &[u8]) -> Result<usize>

Writes to the file descriptor.

This function calls System::write repeatedly until the whole buffer is written to the FD. If the buffer is empty, write is not called at all, so any error that would be returned from write is not returned.

This function silently ignores signals that may interrupt writes.

Source

pub async fn print_error(&self, message: &str)

Convenience function for printing a message to the standard error

Source

pub async fn wait_until(&self, target: Instant)

Waits until the specified time point.

Source

pub async fn wait_for_signals(&self) -> Rc<[Number]>

Waits for some signals to be delivered to this process.

Before calling this function, you need to set the signal disposition to Catch. Without doing so, this function cannot detect the receipt of the signals.

Returns an array of signals that were caught.

If this SharedSystem is part of an Env, you should call Env::wait_for_signals rather than calling this function directly so that the trap set can remember the caught signal.

Source

pub async fn wait_for_signal(&self, signal: Number)

Waits for a signal to be delivered to this process.

Before calling this function, you need to set the signal disposition to Catch. Without doing so, this function cannot detect the receipt of the signal.

If this SharedSystem is part of an Env, you should call Env::wait_for_signal rather than calling this function directly so that the trap set can remember the caught signal.

Source

pub fn select(&self, poll: bool) -> Result<()>

Waits for a next event to occur.

This function calls System::select with arguments computed from the current internal state of the SharedSystem. It will wake up tasks waiting for the file descriptor to be ready in read_async and write_all or for a signal to be caught in wait_for_signal. If no tasks are woken for FDs or signals and poll is false, this function will block until the first task waiting for a specific time point is woken.

If poll is true, this function does not block, so it may not wake up any tasks.

This function may wake up a task even if the condition it is expecting has not yet been met.

Trait Implementations§

Source§

impl Clone for SharedSystem

Source§

fn clone(&self) -> SharedSystem

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 Debug for SharedSystem

Source§

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

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

impl SignalSystem for &SharedSystem

Source§

fn signal_name_from_number(&self, number: Number) -> Name

Returns the name of a signal from its number.
Source§

fn signal_number_from_name(&self, name: Name) -> Option<Number>

Returns the signal number from its name. Read more
Source§

fn get_disposition(&self, signal: Number) -> Result<Disposition>

Returns the current disposition for a signal. Read more
Source§

fn set_disposition( &mut self, signal: Number, disposition: Disposition, ) -> Result<Disposition>

Sets how a signal is handled. Read more
Source§

impl SignalSystem for SharedSystem

Source§

fn signal_name_from_number(&self, number: Number) -> Name

Returns the name of a signal from its number.
Source§

fn signal_number_from_name(&self, name: Name) -> Option<Number>

Returns the signal number from its name. Read more
Source§

fn get_disposition(&self, signal: Number) -> Result<Disposition>

Returns the current disposition for a signal. Read more
Source§

fn set_disposition( &mut self, signal: Number, disposition: Disposition, ) -> Result<Disposition>

Sets how a signal is handled. Read more
Source§

impl System for &SharedSystem

Delegates System methods to the contained system instance.

This implementation only requires a non-mutable reference to the shared system because it uses RefCell to access the contained system instance.

Source§

fn fstat(&self, fd: Fd) -> Result<Stat>

Retrieves metadata of a file.
Source§

fn fstatat( &self, dir_fd: Fd, path: &CStr, follow_symlinks: bool, ) -> Result<Stat>

Retrieves metadata of a file.
Source§

fn is_executable_file(&self, path: &CStr) -> bool

Whether there is an executable file at the specified path.
Source§

fn is_directory(&self, path: &CStr) -> bool

Whether there is a directory at the specified path.
Source§

fn pipe(&mut self) -> Result<(Fd, Fd)>

Creates an unnamed pipe. Read more
Source§

fn dup(&mut self, from: Fd, to_min: Fd, flags: EnumSet<FdFlag>) -> Result<Fd>

Duplicates a file descriptor. Read more
Source§

fn dup2(&mut self, from: Fd, to: Fd) -> Result<Fd>

Duplicates a file descriptor. Read more
Source§

fn open( &mut self, path: &CStr, access: OfdAccess, flags: EnumSet<OpenFlag>, mode: Mode, ) -> Result<Fd>

Opens a file descriptor. Read more
Source§

fn open_tmpfile(&mut self, parent_dir: &Path) -> Result<Fd>

Opens a file descriptor associated with an anonymous temporary file. Read more
Source§

fn close(&mut self, fd: Fd) -> Result<()>

Closes a file descriptor. Read more
Source§

fn ofd_access(&self, fd: Fd) -> Result<OfdAccess>

Returns the open file description access mode.
Source§

fn get_and_set_nonblocking(&mut self, fd: Fd, nonblocking: bool) -> Result<bool>

Gets and sets the non-blocking mode for the open file description. Read more
Source§

fn fcntl_getfd(&self, fd: Fd) -> Result<EnumSet<FdFlag>>

Returns the attributes for the file descriptor. Read more
Source§

fn fcntl_setfd(&mut self, fd: Fd, flags: EnumSet<FdFlag>) -> Result<()>

Sets attributes for the file descriptor. Read more
Source§

fn isatty(&self, fd: Fd) -> bool

Tests if a file descriptor is associated with a terminal device. Read more
Source§

fn read(&mut self, fd: Fd, buffer: &mut [u8]) -> Result<usize>

Reads from the file descriptor. Read more
Source§

fn write(&mut self, fd: Fd, buffer: &[u8]) -> Result<usize>

Writes to the file descriptor. Read more
Source§

fn lseek(&mut self, fd: Fd, position: SeekFrom) -> Result<u64>

Moves the position of the open file description.
Source§

fn fdopendir(&mut self, fd: Fd) -> Result<Box<dyn Dir>>

Opens a directory for enumerating entries.
Source§

fn opendir(&mut self, path: &CStr) -> Result<Box<dyn Dir>>

Opens a directory for enumerating entries.
Source§

fn umask(&mut self, mask: Mode) -> Mode

Gets and sets the file creation mode mask. Read more
Source§

fn now(&self) -> Instant

Returns the current time.
Source§

fn times(&self) -> Result<Times>

Returns consumed CPU times.
Source§

fn validate_signal(&self, number: RawNumber) -> Option<(Name, Number)>

Tests if a signal number is valid. Read more
Source§

fn signal_number_from_name(&self, name: Name) -> Option<Number>

Gets the signal number from the signal name. Read more
Source§

fn sigmask( &mut self, op: Option<(SigmaskOp, &[Number])>, old_mask: Option<&mut Vec<Number>>, ) -> Result<()>

Gets and/or sets the signal blocking mask. Read more
Source§

fn get_sigaction(&self, signal: Number) -> Result<Disposition>

Gets the disposition for a signal. Read more
Source§

fn sigaction( &mut self, signal: Number, action: Disposition, ) -> Result<Disposition>

Gets and sets the disposition for a signal. Read more
Source§

fn caught_signals(&mut self) -> Vec<Number>

Returns signals this process has caught, if any. Read more
Source§

fn kill( &mut self, target: Pid, signal: Option<Number>, ) -> FlexFuture<Result<()>>

Sends a signal. Read more
Source§

fn raise(&mut self, signal: Number) -> FlexFuture<Result<()>>

Sends a signal to the current process. Read more
Source§

fn select( &mut self, readers: &mut Vec<Fd>, writers: &mut Vec<Fd>, timeout: Option<Duration>, signal_mask: Option<&[Number]>, ) -> Result<c_int>

Waits for a next event. Read more
Source§

fn getsid(&self, pid: Pid) -> Result<Pid>

Returns the session ID of the specified process. Read more
Source§

fn getpid(&self) -> Pid

Returns the process ID of the current process.
Source§

fn getppid(&self) -> Pid

Returns the process ID of the parent process.
Source§

fn getpgrp(&self) -> Pid

Returns the process group ID of the current process.
Source§

fn setpgid(&mut self, pid: Pid, pgid: Pid) -> Result<()>

Modifies the process group ID of a process. Read more
Source§

fn tcgetpgrp(&self, fd: Fd) -> Result<Pid>

Returns the current foreground process group ID. Read more
Source§

fn tcsetpgrp(&mut self, fd: Fd, pgid: Pid) -> Result<()>

Switches the foreground process group. Read more
Source§

fn new_child_process(&mut self) -> Result<ChildProcessStarter>

Creates a new child process. Read more
Source§

fn wait(&mut self, target: Pid) -> Result<Option<(Pid, ProcessState)>>

Reports updated status of a child process. Read more
Source§

fn execve( &mut self, path: &CStr, args: &[CString], envs: &[CString], ) -> FlexFuture<Result<Infallible>>

Replaces the current process with an external utility. Read more
Source§

fn exit(&mut self, exit_status: ExitStatus) -> FlexFuture<Infallible>

Terminates the current process. Read more
Source§

fn getcwd(&self) -> Result<PathBuf>

Returns the current working directory path.
Source§

fn chdir(&mut self, path: &CStr) -> Result<()>

Changes the working directory.
Source§

fn getuid(&self) -> Uid

Returns the real user ID of the current process.
Source§

fn geteuid(&self) -> Uid

Returns the effective user ID of the current process.
Source§

fn getgid(&self) -> Gid

Returns the real group ID of the current process.
Source§

fn getegid(&self) -> Gid

Returns the effective group ID of the current process.
Source§

fn getpwnam_dir(&self, name: &CStr) -> Result<Option<PathBuf>>

Returns the home directory path of the given user. Read more
Source§

fn confstr_path(&self) -> Result<UnixString>

Returns the standard $PATH value where all standard utilities are expected to be found. Read more
Source§

fn shell_path(&self) -> CString

Returns the path to the shell executable. Read more
Source§

fn getrlimit(&self, resource: Resource) -> Result<LimitPair>

Returns the limits for the specified resource. Read more
Source§

fn setrlimit(&mut self, resource: Resource, limits: LimitPair) -> Result<()>

Sets the limits for the specified resource. Read more
Source§

impl System for SharedSystem

Delegates System methods to the contained system instance.

Source§

fn fstat(&self, fd: Fd) -> Result<Stat>

Retrieves metadata of a file.
Source§

fn fstatat( &self, dir_fd: Fd, path: &CStr, follow_symlinks: bool, ) -> Result<Stat>

Retrieves metadata of a file.
Source§

fn is_executable_file(&self, path: &CStr) -> bool

Whether there is an executable file at the specified path.
Source§

fn is_directory(&self, path: &CStr) -> bool

Whether there is a directory at the specified path.
Source§

fn pipe(&mut self) -> Result<(Fd, Fd)>

Creates an unnamed pipe. Read more
Source§

fn dup(&mut self, from: Fd, to_min: Fd, flags: EnumSet<FdFlag>) -> Result<Fd>

Duplicates a file descriptor. Read more
Source§

fn dup2(&mut self, from: Fd, to: Fd) -> Result<Fd>

Duplicates a file descriptor. Read more
Source§

fn open( &mut self, path: &CStr, access: OfdAccess, flags: EnumSet<OpenFlag>, mode: Mode, ) -> Result<Fd>

Opens a file descriptor. Read more
Source§

fn open_tmpfile(&mut self, parent_dir: &Path) -> Result<Fd>

Opens a file descriptor associated with an anonymous temporary file. Read more
Source§

fn close(&mut self, fd: Fd) -> Result<()>

Closes a file descriptor. Read more
Source§

fn ofd_access(&self, fd: Fd) -> Result<OfdAccess>

Returns the open file description access mode.
Source§

fn get_and_set_nonblocking(&mut self, fd: Fd, nonblocking: bool) -> Result<bool>

Gets and sets the non-blocking mode for the open file description. Read more
Source§

fn fcntl_getfd(&self, fd: Fd) -> Result<EnumSet<FdFlag>>

Returns the attributes for the file descriptor. Read more
Source§

fn fcntl_setfd(&mut self, fd: Fd, flags: EnumSet<FdFlag>) -> Result<()>

Sets attributes for the file descriptor. Read more
Source§

fn isatty(&self, fd: Fd) -> bool

Tests if a file descriptor is associated with a terminal device. Read more
Source§

fn read(&mut self, fd: Fd, buffer: &mut [u8]) -> Result<usize>

Reads from the file descriptor. Read more
Source§

fn write(&mut self, fd: Fd, buffer: &[u8]) -> Result<usize>

Writes to the file descriptor. Read more
Source§

fn lseek(&mut self, fd: Fd, position: SeekFrom) -> Result<u64>

Moves the position of the open file description.
Source§

fn fdopendir(&mut self, fd: Fd) -> Result<Box<dyn Dir>>

Opens a directory for enumerating entries.
Source§

fn opendir(&mut self, path: &CStr) -> Result<Box<dyn Dir>>

Opens a directory for enumerating entries.
Source§

fn umask(&mut self, mask: Mode) -> Mode

Gets and sets the file creation mode mask. Read more
Source§

fn now(&self) -> Instant

Returns the current time.
Source§

fn times(&self) -> Result<Times>

Returns consumed CPU times.
Source§

fn validate_signal(&self, number: RawNumber) -> Option<(Name, Number)>

Tests if a signal number is valid. Read more
Source§

fn signal_number_from_name(&self, name: Name) -> Option<Number>

Gets the signal number from the signal name. Read more
Source§

fn sigmask( &mut self, op: Option<(SigmaskOp, &[Number])>, old_mask: Option<&mut Vec<Number>>, ) -> Result<()>

Gets and/or sets the signal blocking mask. Read more
Source§

fn get_sigaction(&self, signal: Number) -> Result<Disposition>

Gets the disposition for a signal. Read more
Source§

fn sigaction( &mut self, signal: Number, action: Disposition, ) -> Result<Disposition>

Gets and sets the disposition for a signal. Read more
Source§

fn caught_signals(&mut self) -> Vec<Number>

Returns signals this process has caught, if any. Read more
Source§

fn kill( &mut self, target: Pid, signal: Option<Number>, ) -> FlexFuture<Result<()>>

Sends a signal. Read more
Source§

fn raise(&mut self, signal: Number) -> FlexFuture<Result<()>>

Sends a signal to the current process. Read more
Source§

fn select( &mut self, readers: &mut Vec<Fd>, writers: &mut Vec<Fd>, timeout: Option<Duration>, signal_mask: Option<&[Number]>, ) -> Result<c_int>

Waits for a next event. Read more
Source§

fn getsid(&self, pid: Pid) -> Result<Pid>

Returns the session ID of the specified process. Read more
Source§

fn getpid(&self) -> Pid

Returns the process ID of the current process.
Source§

fn getppid(&self) -> Pid

Returns the process ID of the parent process.
Source§

fn getpgrp(&self) -> Pid

Returns the process group ID of the current process.
Source§

fn setpgid(&mut self, pid: Pid, pgid: Pid) -> Result<()>

Modifies the process group ID of a process. Read more
Source§

fn tcgetpgrp(&self, fd: Fd) -> Result<Pid>

Returns the current foreground process group ID. Read more
Source§

fn tcsetpgrp(&mut self, fd: Fd, pgid: Pid) -> Result<()>

Switches the foreground process group. Read more
Source§

fn new_child_process(&mut self) -> Result<ChildProcessStarter>

Creates a new child process. Read more
Source§

fn wait(&mut self, target: Pid) -> Result<Option<(Pid, ProcessState)>>

Reports updated status of a child process. Read more
Source§

fn execve( &mut self, path: &CStr, args: &[CString], envs: &[CString], ) -> FlexFuture<Result<Infallible>>

Replaces the current process with an external utility. Read more
Source§

fn exit(&mut self, exit_status: ExitStatus) -> FlexFuture<Infallible>

Terminates the current process. Read more
Source§

fn getcwd(&self) -> Result<PathBuf>

Returns the current working directory path.
Source§

fn chdir(&mut self, path: &CStr) -> Result<()>

Changes the working directory.
Source§

fn getuid(&self) -> Uid

Returns the real user ID of the current process.
Source§

fn geteuid(&self) -> Uid

Returns the effective user ID of the current process.
Source§

fn getgid(&self) -> Gid

Returns the real group ID of the current process.
Source§

fn getegid(&self) -> Gid

Returns the effective group ID of the current process.
Source§

fn getpwnam_dir(&self, name: &CStr) -> Result<Option<PathBuf>>

Returns the home directory path of the given user. Read more
Source§

fn confstr_path(&self) -> Result<UnixString>

Returns the standard $PATH value where all standard utilities are expected to be found. Read more
Source§

fn shell_path(&self) -> CString

Returns the path to the shell executable. Read more
Source§

fn getrlimit(&self, resource: Resource) -> Result<LimitPair>

Returns the limits for the specified resource. Read more
Source§

fn setrlimit(&mut self, resource: Resource, limits: LimitPair) -> Result<()>

Sets the limits for the specified resource. Read more

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> 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> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

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> SystemEx for T
where T: System + ?Sized,

Source§

fn move_fd_internal(&mut self, from: Fd) -> Result<Fd>

Moves a file descriptor to MIN_INTERNAL_FD or larger. Read more
Source§

fn fd_is_pipe(&self, fd: Fd) -> bool

Tests if a file descriptor is a pipe.
Source§

fn tcsetpgrp_with_block(&mut self, fd: Fd, pgid: Pid) -> Result<()>

Switches the foreground process group with SIGTTOU blocked. Read more
Source§

fn tcsetpgrp_without_block(&mut self, fd: Fd, pgid: Pid) -> Result<()>

Switches the foreground process group with the default SIGTTOU settings. Read more
Source§

fn signal_name_from_number(&self, number: Number) -> Name

Returns the signal name for the signal number. Read more
Source§

fn exit_or_raise( &mut self, exit_status: ExitStatus, ) -> impl Future<Output = Infallible>

Terminates the current process with the given exit status, possibly sending a signal to kill the process. 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.