refactor: split ProcessIo into own mod

This commit is contained in:
2021-11-05 14:06:20 +02:00
parent 8de432b726
commit e8e8032adb
5 changed files with 91 additions and 87 deletions
+1 -1
View File
@@ -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
{
+85
View File
@@ -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()
}
}
+2
View File
@@ -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;
+2 -85
View File
@@ -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()
+1 -1
View File
@@ -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;