diff --git a/kernel/src/init.rs b/kernel/src/init.rs index 79e7459..0b5f408 100644 --- a/kernel/src/init.rs +++ b/kernel/src/init.rs @@ -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 { diff --git a/kernel/src/proc/io.rs b/kernel/src/proc/io.rs new file mode 100644 index 0000000..ed37cb8 --- /dev/null +++ b/kernel/src/proc/io.rs @@ -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, + files: BTreeMap, +} + +impl ProcessIo { + /// Clones this I/O context + pub fn fork(&self) -> Result { + // 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 { + 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 { + 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() + } +} diff --git a/kernel/src/proc/mod.rs b/kernel/src/proc/mod.rs index 1876305..42f084f 100644 --- a/kernel/src/proc/mod.rs +++ b/kernel/src/proc/mod.rs @@ -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; diff --git a/kernel/src/proc/process.rs b/kernel/src/proc/process.rs index 42127ab..027338e 100644 --- a/kernel/src/proc/process.rs +++ b/kernel/src/proc/process.rs @@ -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, } -/// Process I/O context. Contains file tables, root/cwd info etc. -pub struct ProcessIo { - ioctx: Option, - files: BTreeMap, -} - /// 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 { - // 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 { - 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 { - 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() diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 8dc1973..b893466 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -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;