refactor: better ProcessIo impl
This commit is contained in:
@@ -16,5 +16,6 @@ pub enum Errno {
|
||||
NotImplemented,
|
||||
OutOfMemory,
|
||||
TimedOut,
|
||||
TooManyDescriptors,
|
||||
WouldBlock,
|
||||
}
|
||||
|
||||
+17
-2
@@ -7,12 +7,27 @@ extern crate libusr;
|
||||
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
let mut buf = [0; 128];
|
||||
|
||||
loop {
|
||||
println!("Hello to stdout");
|
||||
trace!("Hello from userspace");
|
||||
let count = unsafe {
|
||||
libusr::sys::sys_read(0, buf.as_mut_ptr(), buf.len())
|
||||
};
|
||||
if count < 0 {
|
||||
trace!("Read from stdio failed");
|
||||
break;
|
||||
}
|
||||
let count = count as usize;
|
||||
|
||||
if let Ok(s) = core::str::from_utf8(&buf[..count]) {
|
||||
println!("Got string {:?}", s);
|
||||
} else {
|
||||
println!("Got string (non-utf8) {:?}", &buf[..count]);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
libusr::sys::sys_ex_nanosleep(1_000_000_000, core::ptr::null_mut());
|
||||
}
|
||||
}
|
||||
-1
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ impl<const N: usize> CharRing<N> {
|
||||
};
|
||||
|
||||
if byte == b'\n' || byte == b'\r' {
|
||||
dev.write(true, b"\r\n").ok();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -95,9 +95,9 @@ pub unsafe fn enter(initrd: Option<(usize, usize)>) -> ! {
|
||||
// Open stdout
|
||||
{
|
||||
let mut io = proc.io.lock();
|
||||
let node = io.ioctx.as_ref().unwrap().find(None, "/dev/uart0", true).unwrap();
|
||||
let node = io.ioctx().find(None, "/dev/uart0", true).unwrap();
|
||||
// TODO fd cloning?
|
||||
io.files.push(node.open().unwrap());
|
||||
io.place_file(node.open().unwrap()).unwrap();
|
||||
}
|
||||
|
||||
Process::execve(|space| elf::load_elf(space, &mut file), 0).unwrap();
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::mem::{
|
||||
};
|
||||
use crate::proc::{PROCESSES, SCHED};
|
||||
use crate::sync::IrqSafeSpinLock;
|
||||
use alloc::{vec::Vec, rc::Rc};
|
||||
use alloc::{rc::Rc, collections::BTreeMap};
|
||||
use core::cell::UnsafeCell;
|
||||
use core::fmt;
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
@@ -53,9 +53,11 @@ struct ProcessInner {
|
||||
///
|
||||
pub struct ProcessIo {
|
||||
///
|
||||
pub ioctx: Option<Ioctx>,
|
||||
ioctx: Option<Ioctx>,
|
||||
///
|
||||
pub files: Vec<File>,
|
||||
files: BTreeMap<usize, File>,
|
||||
///
|
||||
file_bitmap: u64,
|
||||
}
|
||||
|
||||
/// Structure describing an operating system process
|
||||
@@ -134,6 +136,41 @@ impl fmt::Display for Pid {
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessIo {
|
||||
///
|
||||
pub fn file(&mut self, idx: usize) -> Result<&mut File, Errno> {
|
||||
self.files.get_mut(&idx).ok_or(Errno::InvalidFile)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn ioctx(&mut self) -> &mut Ioctx {
|
||||
self.ioctx.as_mut().unwrap()
|
||||
}
|
||||
|
||||
///
|
||||
pub fn place_file(&mut self, file: File) -> Result<usize, Errno> {
|
||||
for bit in 0..64 {
|
||||
if self.file_bitmap & (1 << bit) == 0 {
|
||||
if self.files.insert(bit, file).is_some() {
|
||||
panic!("Open file bitmap is broken");
|
||||
}
|
||||
self.file_bitmap |= 1 << bit;
|
||||
return Ok(bit);
|
||||
}
|
||||
}
|
||||
Err(Errno::TooManyDescriptors)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
files: BTreeMap::new(),
|
||||
file_bitmap: 0,
|
||||
ioctx: None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Process {
|
||||
const USTACK_VIRT_TOP: usize = 0x100000000;
|
||||
const USTACK_PAGES: usize = 4;
|
||||
@@ -223,10 +260,7 @@ impl Process {
|
||||
let id = Pid::new_kernel();
|
||||
let res = Rc::new(Self {
|
||||
ctx: UnsafeCell::new(Context::kernel(entry as usize, arg)),
|
||||
io: IrqSafeSpinLock::new(ProcessIo {
|
||||
ioctx: None,
|
||||
files: Vec::new(),
|
||||
}),
|
||||
io: IrqSafeSpinLock::new(ProcessIo::new()),
|
||||
inner: IrqSafeSpinLock::new(ProcessInner {
|
||||
id,
|
||||
exit: None,
|
||||
|
||||
@@ -115,25 +115,23 @@ pub unsafe fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
|
||||
let node = io.ioctx.as_ref().unwrap().find(None, path, true)?;
|
||||
let node = io.ioctx().find(None, path, true)?;
|
||||
// TODO check access
|
||||
io.files.push(node.open()?);
|
||||
|
||||
Ok(io.files.len() - 1)
|
||||
io.place_file(node.open()?)
|
||||
}
|
||||
abi::SYS_READ => {
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
let buf = validate_user_ptr(args[1], args[2])?;
|
||||
|
||||
io.files[args[0]].read(buf)
|
||||
io.file(args[0])?.read(buf)
|
||||
}
|
||||
abi::SYS_WRITE => {
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
let buf = validate_user_ptr(args[1], args[2])?;
|
||||
|
||||
io.files[args[0]].write(buf)
|
||||
io.file(args[0])?.write(buf)
|
||||
}
|
||||
|
||||
// Extra system calls
|
||||
|
||||
Reference in New Issue
Block a user