refactor: split ProcessIo into own mod
This commit is contained in:
+1
-1
@@ -33,7 +33,7 @@ pub extern "C" fn init_fn(_arg: usize) -> ! {
|
||||
let node = ioctx.find(None, "/init", true).unwrap();
|
||||
let file = node.open(OpenFlags::O_RDONLY | OpenFlags::O_EXEC).unwrap();
|
||||
|
||||
proc.set_ioctx(ioctx);
|
||||
proc.io.lock().set_ioctx(ioctx);
|
||||
|
||||
// Open stdin/stdout/stderr
|
||||
{
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
//! Process file descriptors and I/O context
|
||||
use alloc::collections::BTreeMap;
|
||||
use error::Errno;
|
||||
use vfs::{FileRef, Ioctx};
|
||||
|
||||
/// Process I/O context. Contains file tables, root/cwd info etc.
|
||||
pub struct ProcessIo {
|
||||
ioctx: Option<Ioctx>,
|
||||
files: BTreeMap<usize, FileRef>,
|
||||
}
|
||||
|
||||
impl ProcessIo {
|
||||
/// Clones this I/O context
|
||||
pub fn fork(&self) -> Result<ProcessIo, Errno> {
|
||||
// TODO
|
||||
let mut dst = ProcessIo::new();
|
||||
for (&fd, entry) in self.files.iter() {
|
||||
dst.files.insert(fd, entry.clone());
|
||||
}
|
||||
dst.ioctx = self.ioctx.clone();
|
||||
Ok(dst)
|
||||
}
|
||||
|
||||
/// Returns [File] struct referred to by file descriptor `idx`
|
||||
pub fn file(&mut self, idx: usize) -> Result<FileRef, Errno> {
|
||||
self.files.get(&idx).cloned().ok_or(Errno::InvalidFile)
|
||||
}
|
||||
|
||||
/// Returns [Ioctx] structure reference of this I/O context
|
||||
pub fn ioctx(&mut self) -> &mut Ioctx {
|
||||
self.ioctx.as_mut().unwrap()
|
||||
}
|
||||
|
||||
/// Allocates a file descriptor and associates a [File] struct with it
|
||||
pub fn place_file(&mut self, file: FileRef) -> Result<usize, Errno> {
|
||||
for idx in 0..64 {
|
||||
if self.files.get(&idx).is_none() {
|
||||
self.files.insert(idx, file);
|
||||
return Ok(idx);
|
||||
}
|
||||
}
|
||||
Err(Errno::TooManyDescriptors)
|
||||
}
|
||||
|
||||
/// Performs [File] close and releases its associated file descriptor `idx`
|
||||
pub fn close_file(&mut self, idx: usize) -> Result<(), Errno> {
|
||||
let res = self.files.remove(&idx);
|
||||
assert!(res.is_some());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Constructs a new I/O context
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
files: BTreeMap::new(),
|
||||
ioctx: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Assigns a descriptor number to an open file. If the number is not available,
|
||||
/// returns [Errno::AlreadyExists].
|
||||
pub fn set_file(&mut self, idx: usize, file: FileRef) -> Result<(), Errno> {
|
||||
if self.files.get(&idx).is_none() {
|
||||
self.files.insert(idx, file);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Errno::AlreadyExists)
|
||||
}
|
||||
}
|
||||
|
||||
/// Changes process I/O context: root and cwd
|
||||
pub fn set_ioctx(&mut self, ioctx: Ioctx) {
|
||||
self.ioctx.replace(ioctx);
|
||||
}
|
||||
|
||||
pub(super) fn handle_cloexec(&mut self) {
|
||||
self.files.retain(|_, entry| !entry.borrow().is_cloexec());
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ProcessIo {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ use alloc::collections::BTreeMap;
|
||||
pub mod elf;
|
||||
pub mod process;
|
||||
pub use process::{Pid, Process, ProcessRef, State as ProcessState};
|
||||
pub mod io;
|
||||
pub use io::ProcessIo;
|
||||
|
||||
pub mod wait;
|
||||
|
||||
|
||||
@@ -5,15 +5,13 @@ use crate::mem::{
|
||||
phys::{self, PageUsage},
|
||||
virt::{MapAttributes, Space},
|
||||
};
|
||||
use crate::proc::{PROCESSES, SCHED};
|
||||
use crate::proc::{ProcessIo, PROCESSES, SCHED};
|
||||
use crate::sync::IrqSafeSpinLock;
|
||||
use alloc::{collections::BTreeMap, rc::Rc};
|
||||
use alloc::rc::Rc;
|
||||
use core::cell::UnsafeCell;
|
||||
use core::fmt;
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
use error::Errno;
|
||||
use vfs::FileRef;
|
||||
use vfs::Ioctx;
|
||||
|
||||
pub use crate::arch::platform::context::{self, Context};
|
||||
|
||||
@@ -51,12 +49,6 @@ struct ProcessInner {
|
||||
exit: Option<ExitCode>,
|
||||
}
|
||||
|
||||
/// Process I/O context. Contains file tables, root/cwd info etc.
|
||||
pub struct ProcessIo {
|
||||
ioctx: Option<Ioctx>,
|
||||
files: BTreeMap<usize, FileRef>,
|
||||
}
|
||||
|
||||
/// Structure describing an operating system process
|
||||
#[allow(dead_code)]
|
||||
pub struct Process {
|
||||
@@ -138,85 +130,10 @@ impl fmt::Display for Pid {
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessIo {
|
||||
/// Clones this I/O context
|
||||
pub fn fork(&self) -> Result<ProcessIo, Errno> {
|
||||
// TODO
|
||||
let mut dst = ProcessIo::new();
|
||||
for (&fd, entry) in self.files.iter() {
|
||||
dst.files.insert(fd, entry.clone());
|
||||
}
|
||||
dst.ioctx = self.ioctx.clone();
|
||||
Ok(dst)
|
||||
}
|
||||
|
||||
/// Returns [File] struct referred to by file descriptor `idx`
|
||||
pub fn file(&mut self, idx: usize) -> Result<FileRef, Errno> {
|
||||
self.files.get(&idx).cloned().ok_or(Errno::InvalidFile)
|
||||
}
|
||||
|
||||
/// Returns [Ioctx] structure reference of this I/O context
|
||||
pub fn ioctx(&mut self) -> &mut Ioctx {
|
||||
self.ioctx.as_mut().unwrap()
|
||||
}
|
||||
|
||||
/// Allocates a file descriptor and associates a [File] struct with it
|
||||
pub fn place_file(&mut self, file: FileRef) -> Result<usize, Errno> {
|
||||
for idx in 0..64 {
|
||||
if self.files.get(&idx).is_none() {
|
||||
self.files.insert(idx, file);
|
||||
return Ok(idx);
|
||||
}
|
||||
}
|
||||
Err(Errno::TooManyDescriptors)
|
||||
}
|
||||
|
||||
/// Performs [File] close and releases its associated file descriptor `idx`
|
||||
pub fn close_file(&mut self, idx: usize) -> Result<(), Errno> {
|
||||
let res = self.files.remove(&idx);
|
||||
assert!(res.is_some());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Constructs a new I/O context
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
files: BTreeMap::new(),
|
||||
ioctx: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Assigns a descriptor number to an open file. If the number is not available,
|
||||
/// returns [Errno::AlreadyExists].
|
||||
pub fn set_file(&mut self, idx: usize, file: FileRef) -> Result<(), Errno> {
|
||||
if self.files.get(&idx).is_none() {
|
||||
self.files.insert(idx, file);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Errno::AlreadyExists)
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_cloexec(&mut self) {
|
||||
self.files.retain(|_, entry| !entry.borrow().is_cloexec());
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ProcessIo {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Process {
|
||||
const USTACK_VIRT_TOP: usize = 0x100000000;
|
||||
const USTACK_PAGES: usize = 4;
|
||||
|
||||
/// Changes process I/O context: root and cwd
|
||||
pub fn set_ioctx(&self, ioctx: Ioctx) {
|
||||
self.io.lock().ioctx = Some(ioctx);
|
||||
}
|
||||
|
||||
/// Returns currently executing process
|
||||
pub fn current() -> ProcessRef {
|
||||
SCHED.current_process()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use crate::arch::platform::exception::ExceptionFrame;
|
||||
use crate::debug::Level;
|
||||
use crate::proc::{elf, process::ProcessIo, wait, Pid, Process};
|
||||
use crate::proc::{elf, ProcessIo, wait, Pid, Process};
|
||||
use core::mem::size_of;
|
||||
use core::ops::DerefMut;
|
||||
use core::time::Duration;
|
||||
|
||||
Reference in New Issue
Block a user