pub struct VirtualSystem {
pub state: Rc<RefCell<SystemState>>,
pub process_id: Pid,
}Expand description
Simulated system
See the module-level documentation to grasp a basic understanding of
VirtualSystem.
A VirtualSystem instance has two members: state and process_id. The
former is a SystemState that effectively contains the whole state of the
system. The state is contained in Rc so that virtual processes can share
the same state. The latter is a process ID that identifies a process calling
the system interfaces.
When you clone a virtual system, the clone will have the same process_id
and state as the original. To simulate the fork system call, you should
call a method of the Fork trait implemented by VirtualSystem.
Fields§
§state: Rc<RefCell<SystemState>>State of the system.
process_id: PidProcess ID of the process that is interacting with the system.
Implementations§
Source§impl VirtualSystem
impl VirtualSystem
Sourcepub fn new() -> VirtualSystem
pub fn new() -> VirtualSystem
Creates a virtual system with an almost empty state.
The process_id of the returned VirtualSystem will be 2.
(Process ID 1 has special meaning in some system calls, so we don’t use
it as a default value.)
The state of the returned VirtualSystem will have a Process with
process ID 2 in the process set (SystemState::processes). The file
system will contain files named /dev/stdin, /dev/stdout, and
/dev/stderr that are opened in the process with file descriptor 0, 1,
and 2, respectively. The file system also contains an empty directory
/tmp.
Sourcepub fn current_process(&self) -> Ref<'_, Process>
pub fn current_process(&self) -> Ref<'_, Process>
Finds the current process from the system state.
§Panics
This function will panic if it cannot find a process having
self.process_id.
Sourcepub fn current_process_mut(&self) -> RefMut<'_, Process>
pub fn current_process_mut(&self) -> RefMut<'_, Process>
Finds the current process from the system state.
§Panics
This function will panic if it cannot find a process having
self.process_id.
Sourcepub fn get_open_file_description(
&self,
fd: Fd,
) -> Result<Rc<RefCell<OpenFileDescription>>>
pub fn get_open_file_description( &self, fd: Fd, ) -> Result<Rc<RefCell<OpenFileDescription>>>
Returns the open file description for the given FD.
This is a helper function for obtaining the open file description for a
given file descriptor in the current process.
Returns Err(Errno::EBADF) if the FD is not open.
Sourcepub fn with_open_file_description<F, R>(&self, fd: Fd, f: F) -> Result<R>
pub fn with_open_file_description<F, R>(&self, fd: Fd, f: F) -> Result<R>
Calls the given closure passing the open file description for the FD.
This is a helper function for performing an operation on the open file description for a given file descriptor in the current process. The closure is passed a reference to the open file description, and can perform any operation on it, such as checking its state. The return value of the closure is returned as the result of this function.
Returns Err(Errno::EBADF) if the FD is not open.
Panics if the open file description is already mutably borrowed.
Sourcepub fn with_open_file_description_mut<F, R>(&self, fd: Fd, f: F) -> Result<R>
pub fn with_open_file_description_mut<F, R>(&self, fd: Fd, f: F) -> Result<R>
Calls the given closure passing the open file description for the FD.
This is a helper function for performing a mutable operation on the open file description for a given file descriptor in the current process. The closure is passed a mutable reference to the open file description, and can perform any operation on it, such as reading and writing. The return value of the closure is returned as the result of this function.
Returns Err(Errno::EBADF) if the FD is not open.
Panics if the open file description is already borrowed.
Trait Implementations§
Source§impl CaughtSignals for VirtualSystem
impl CaughtSignals for VirtualSystem
Source§impl Chdir for VirtualSystem
impl Chdir for VirtualSystem
Source§impl Clock for VirtualSystem
impl Clock for VirtualSystem
Source§fn now(&self) -> Instant
fn now(&self) -> Instant
Returns now in SystemState.
Panics if it is None.
Source§impl Clone for VirtualSystem
impl Clone for VirtualSystem
Source§fn clone(&self) -> VirtualSystem
fn clone(&self) -> VirtualSystem
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Close for VirtualSystem
impl Close for VirtualSystem
Source§impl Debug for VirtualSystem
impl Debug for VirtualSystem
Source§impl Default for VirtualSystem
impl Default for VirtualSystem
Source§impl Dup for VirtualSystem
impl Dup for VirtualSystem
Source§impl Exec for VirtualSystem
impl Exec for VirtualSystem
Source§fn execve(
&self,
path: &CStr,
args: &[CString],
envs: &[CString],
) -> impl Future<Output = Result<Infallible>> + use<>
fn execve( &self, path: &CStr, args: &[CString], envs: &[CString], ) -> impl Future<Output = Result<Infallible>> + use<>
Stub for the execve system call.
The execve system call cannot be simulated in the userland. This
function returns ENOSYS if the file at path is a native executable,
ENOEXEC if a non-executable file, and ENOENT otherwise.
Source§impl Exit for VirtualSystem
impl Exit for VirtualSystem
Source§fn exit(
&self,
exit_status: ExitStatus,
) -> impl Future<Output = Infallible> + use<>
fn exit( &self, exit_status: ExitStatus, ) -> impl Future<Output = Infallible> + use<>
Source§impl Fcntl for VirtualSystem
impl Fcntl for VirtualSystem
Source§fn ofd_access(&self, fd: Fd) -> Result<OfdAccess>
fn ofd_access(&self, fd: Fd) -> Result<OfdAccess>
Source§fn get_and_set_nonblocking(&self, fd: Fd, nonblocking: bool) -> Result<bool>
fn get_and_set_nonblocking(&self, fd: Fd, nonblocking: bool) -> Result<bool>
Source§impl Fork for VirtualSystem
impl Fork for VirtualSystem
Source§fn new_child_process(&self) -> Result<ChildProcessStarter<Self>>
fn new_child_process(&self) -> Result<ChildProcessStarter<Self>>
Creates a new child process.
This implementation does not create any real child process. Instead, it returns a child process starter that runs its task concurrently in the same process.
To run the concurrent task, this function needs an executor that has
been set in the SystemState. If the system state does not have an
executor, this function fails with Errno::ENOSYS.
The process ID of the child will be the maximum of existing process IDs plus 1. If there are no other processes, it will be 2.
Source§impl Fstat for VirtualSystem
impl Fstat for VirtualSystem
Source§fn fstatat(
&self,
dir_fd: Fd,
path: &CStr,
follow_symlinks: bool,
) -> Result<Stat>
fn fstatat( &self, dir_fd: Fd, path: &CStr, follow_symlinks: bool, ) -> Result<Stat>
Source§fn is_directory(&self, path: &CStr) -> bool
fn is_directory(&self, path: &CStr) -> bool
Source§fn fd_is_pipe(&self, fd: Fd) -> bool
fn fd_is_pipe(&self, fd: Fd) -> bool
Source§impl GetCwd for VirtualSystem
impl GetCwd for VirtualSystem
Source§impl GetPid for VirtualSystem
impl GetPid for VirtualSystem
Source§impl GetPw for VirtualSystem
impl GetPw for VirtualSystem
Source§impl GetRlimit for VirtualSystem
impl GetRlimit for VirtualSystem
Source§impl GetSigaction for VirtualSystem
impl GetSigaction for VirtualSystem
Source§fn get_sigaction(&self, signal: Number) -> Result<Disposition>
fn get_sigaction(&self, signal: Number) -> Result<Disposition>
Source§impl GetUid for VirtualSystem
impl GetUid for VirtualSystem
Source§impl IsExecutableFile for VirtualSystem
impl IsExecutableFile for VirtualSystem
Source§fn is_executable_file(&self, path: &CStr) -> bool
fn is_executable_file(&self, path: &CStr) -> bool
Tests whether the specified file is executable or not.
The current implementation only checks if the file has any executable bit in the permissions. The file owner and group are not considered.
Source§impl Isatty for VirtualSystem
impl Isatty for VirtualSystem
Source§impl Open for VirtualSystem
impl Open for VirtualSystem
Source§fn open(
&self,
path: &CStr,
access: OfdAccess,
flags: EnumSet<OpenFlag>,
mode: Mode,
) -> impl Future<Output = Result<Fd>> + use<>
fn open( &self, path: &CStr, access: OfdAccess, flags: EnumSet<OpenFlag>, mode: Mode, ) -> impl Future<Output = Result<Fd>> + use<>
Opens a file and returns a new file descriptor for it.
The returned future will be pending until the file is ready to be
opened. For example, if the file is a FIFO, the future will be pending
until the other end of the FIFO is opened, unless OpenFlag::NonBlock
is specified.
Source§fn open_tmpfile(&self, _parent_dir: &Path) -> Result<Fd>
fn open_tmpfile(&self, _parent_dir: &Path) -> Result<Fd>
Source§impl Pipe for VirtualSystem
impl Pipe for VirtualSystem
Source§impl Read for VirtualSystem
impl Read for VirtualSystem
Source§impl Seek for VirtualSystem
impl Seek for VirtualSystem
Source§impl Select for VirtualSystem
impl Select for VirtualSystem
Source§fn select<'a>(
&self,
readers: &'a mut Vec<Fd>,
writers: &'a mut Vec<Fd>,
timeout: Option<Duration>,
signal_mask: Option<&[Number]>,
) -> impl Future<Output = Result<c_int>> + use<'a>
fn select<'a>( &self, readers: &'a mut Vec<Fd>, writers: &'a mut Vec<Fd>, timeout: Option<Duration>, signal_mask: Option<&[Number]>, ) -> impl Future<Output = Result<c_int>> + use<'a>
Waits for a next event.
The VirtualSystem implementation for this method simulates the
blocking behavior of select by returning a future that becomes ready
when the specified FDs are ready, the timeout expires, or a signal is
delivered. However, it does not actually block the calling thread.
Instead, it relies on the caller to poll the returned future to
determine when the event occurs. This design allows the VirtualSystem
to be used in asynchronous contexts without blocking the entire thread,
while still providing the expected behavior of select.
Source§impl SendSignal for VirtualSystem
impl SendSignal for VirtualSystem
Source§fn kill(
&self,
target: Pid,
signal: Option<Number>,
) -> impl Future<Output = Result<()>> + use<>
fn kill( &self, target: Pid, signal: Option<Number>, ) -> impl Future<Output = Result<()>> + use<>
Sends a signal to the target process.
The current implementation accepts any positive signal number and None
(no signal) for signal. Negative signal numbers are rejected with
Errno::EINVAL.
This function returns a future that enables the executor to block the calling thread until the current process is ready to proceed. If the signal is sent to the current process and it causes the process to stop, the future will be ready only when the process is resumed. Similarly, if the signal causes the current process to terminate, the future will never be ready.
Source§impl SetPgid for VirtualSystem
impl SetPgid for VirtualSystem
Source§impl SetRlimit for VirtualSystem
impl SetRlimit for VirtualSystem
Source§impl ShellPath for VirtualSystem
impl ShellPath for VirtualSystem
Source§fn shell_path(&self) -> CString
fn shell_path(&self) -> CString
Returns the path to the shell.
The current implementation returns “/bin/sh”.
Source§impl Sigaction for VirtualSystem
impl Sigaction for VirtualSystem
Source§fn sigaction(
&self,
signal: Number,
disposition: Disposition,
) -> Result<Disposition>
fn sigaction( &self, signal: Number, disposition: Disposition, ) -> Result<Disposition>
Source§impl Sigmask for VirtualSystem
impl Sigmask for VirtualSystem
Source§impl Signals for VirtualSystem
impl Signals for VirtualSystem
Source§fn sigrt_range(&self) -> Option<RangeInclusive<Number>>
fn sigrt_range(&self) -> Option<RangeInclusive<Number>>
Source§const NAMED_SIGNALS: &'static [(&'static str, Option<Number>)] = _
const NAMED_SIGNALS: &'static [(&'static str, Option<Number>)] = _
Source§fn iter_sigrt(&self) -> impl DoubleEndedIterator<Item = Number> + use<Self>
fn iter_sigrt(&self) -> impl DoubleEndedIterator<Item = Number> + use<Self>
Source§fn to_signal_number<N: Into<RawNumber>>(&self, number: N) -> Option<Number>
fn to_signal_number<N: Into<RawNumber>>(&self, number: N) -> Option<Number>
Source§fn sig2str<N: Into<RawNumber>>(&self, signal: N) -> Option<Cow<'static, str>>
fn sig2str<N: Into<RawNumber>>(&self, signal: N) -> Option<Cow<'static, str>>
Source§fn str2sig(&self, name: &str) -> Option<Number>
fn str2sig(&self, name: &str) -> Option<Number>
Source§fn validate_signal(&self, number: RawNumber) -> Option<(Name, Number)>
fn validate_signal(&self, number: RawNumber) -> Option<(Name, Number)>
Source§impl Sysconf for VirtualSystem
impl Sysconf for VirtualSystem
Source§fn confstr_path(&self) -> Result<UnixString>
fn confstr_path(&self) -> Result<UnixString>
Returns the standard path for the system.
This function returns the value of SystemState::path. If it is empty,
it returns the ENOSYS error.
Source§impl TcGetPgrp for VirtualSystem
impl TcGetPgrp for VirtualSystem
Source§impl TcSetPgrp for VirtualSystem
impl TcSetPgrp for VirtualSystem
Source§impl Times for VirtualSystem
impl Times for VirtualSystem
Source§impl Umask for VirtualSystem
impl Umask for VirtualSystem
Source§impl Wait for VirtualSystem
impl Wait for VirtualSystem
Source§impl Write for VirtualSystem
impl Write for VirtualSystem
Source§fn write<'a>(
&self,
fd: Fd,
buffer: &'a [u8],
) -> impl Future<Output = Result<usize>> + use<'a>
fn write<'a>( &self, fd: Fd, buffer: &'a [u8], ) -> impl Future<Output = Result<usize>> + use<'a>
Writes data from the buffer to the file descriptor.
For pipes (FIFOs) opened in blocking mode, if the write is at most
PIPE_BUF bytes, this method blocks until enough room is available
to write all bytes atomically. For larger writes, this method writes as
many bytes as fit on each pass and loops, blocking only when the pipe is
completely full, until the entire buffer has been written. The decision
to loop is encapsulated in
OpenFileDescription::poll_write_full;
this method itself contains no file-type branching.
For non-pipe file types or non-blocking mode, this method returns after the first successful (possibly partial) write without looping.
If a signal is caught while this method is blocking, it returns
Errno::EINTR if no bytes have been written yet, or the count of
bytes written so far otherwise. The signal-precedence check runs at the
top of each poll iteration before any further write is attempted, so
when Err(Errno::EINTR) is returned no bytes have been transferred in
this call.
Auto Trait Implementations§
impl Freeze for VirtualSystem
impl !RefUnwindSafe for VirtualSystem
impl !Send for VirtualSystem
impl !Sync for VirtualSystem
impl Unpin for VirtualSystem
impl UnsafeUnpin for VirtualSystem
impl !UnwindSafe for VirtualSystem
Blanket Implementations§
Source§impl<T> SystemEx for T
impl<T> SystemEx for T
Source§fn move_fd_internal(&mut self, from: Fd) -> Result<Fd>
fn move_fd_internal(&mut self, from: Fd) -> Result<Fd>
use yash_env::io::move_fd_internal instead
MIN_INTERNAL_FD or larger. Read moreSource§fn fd_is_pipe(&self, fd: Fd) -> bool
fn fd_is_pipe(&self, fd: Fd) -> bool
use yash_env::system::Fstat::fd_is_pipe instead
Source§fn tcsetpgrp_with_block(
&mut self,
fd: Fd,
pgid: Pid,
) -> impl Future<Output = Result<()>>
fn tcsetpgrp_with_block( &mut self, fd: Fd, pgid: Pid, ) -> impl Future<Output = Result<()>>
use yash_env::job::tcsetpgrp_with_block instead
Source§fn tcsetpgrp_without_block(
&mut self,
fd: Fd,
pgid: Pid,
) -> impl Future<Output = Result<()>>
fn tcsetpgrp_without_block( &mut self, fd: Fd, pgid: Pid, ) -> impl Future<Output = Result<()>>
use yash_env::job::tcsetpgrp_without_block instead
Source§fn signal_name_from_number(&self, number: Number) -> Name
fn signal_name_from_number(&self, number: Number) -> Name
use yash_env::system::Signals::signal_name_from_number instead
Source§fn exit_or_raise(
&mut self,
exit_status: ExitStatus,
) -> impl Future<Output = Infallible>
fn exit_or_raise( &mut self, exit_status: ExitStatus, ) -> impl Future<Output = Infallible>
use yash_env::semantics::exit_or_raise instead
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