From b18e322c3f51d636847464a81d0f5a2c84d350ac Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jeremy@system76.com> Date: Fri, 28 Dec 2018 21:53:40 -0700 Subject: [PATCH] WIP: itimer and sigprocmask --- Cargo.lock | 4 +- src/scheme/itimer.rs | 110 +++++++++++++++++++++++++++++++++++++++++ src/scheme/mod.rs | 5 ++ src/syscall/debug.rs | 6 +++ src/syscall/mod.rs | 13 +++++ src/syscall/process.rs | 5 ++ syscall | 2 +- 7 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 src/scheme/itimer.rs diff --git a/Cargo.lock b/Cargo.lock index 8eafacfd..a243fc86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,7 +178,7 @@ dependencies = [ "goblin 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "raw-cpuid 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.45", + "redox_syscall 0.1.49", "slab_allocator 0.3.1", "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "x86 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -279,7 +279,7 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.45" +version = "0.1.49" [[package]] name = "regex" diff --git a/src/scheme/itimer.rs b/src/scheme/itimer.rs new file mode 100644 index 00000000..2eaae089 --- /dev/null +++ b/src/scheme/itimer.rs @@ -0,0 +1,110 @@ +use alloc::collections::BTreeMap; +use core::{mem, slice, str}; +use core::sync::atomic::{AtomicUsize, Ordering}; +use spin::RwLock; + +use syscall::data::ITimerSpec; +use syscall::error::*; +use syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC}; +use syscall::scheme::Scheme; + +pub struct ITimerScheme { + next_id: AtomicUsize, + handles: RwLock<BTreeMap<usize, usize>> +} + +impl ITimerScheme { + pub fn new() -> ITimerScheme { + ITimerScheme { + next_id: AtomicUsize::new(0), + handles: RwLock::new(BTreeMap::new()) + } + } +} + +impl Scheme for ITimerScheme { + fn open(&self, path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> { + let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?; + + let clock = path_str.parse::<usize>().or(Err(Error::new(ENOENT)))?; + + match clock { + CLOCK_REALTIME => (), + CLOCK_MONOTONIC => (), + _ => return Err(Error::new(ENOENT)) + } + + let id = self.next_id.fetch_add(1, Ordering::SeqCst); + self.handles.write().insert(id, clock); + + Ok(id) + } + + fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> { + let clock = { + let handles = self.handles.read(); + *handles.get(&id).ok_or(Error::new(EBADF))? + }; + + let time_buf = unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut ITimerSpec, buf.len()/mem::size_of::<ITimerSpec>()) }; + + let mut i = 0; + while i < time_buf.len() { + time_buf[i] = ITimerSpec::default(); + i += 1; + } + + Ok(i * mem::size_of::<ITimerSpec>()) + } + + fn write(&self, id: usize, buf: &[u8]) -> Result<usize> { + let clock = { + let handles = self.handles.read(); + *handles.get(&id).ok_or(Error::new(EBADF))? + }; + + let time_buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *const ITimerSpec, buf.len()/mem::size_of::<ITimerSpec>()) }; + + let mut i = 0; + while i < time_buf.len() { + let time = time_buf[i]; + println!("{}: {:?}", i, time); + i += 1; + } + + Ok(i * mem::size_of::<ITimerSpec>()) + } + + fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> { + Ok(0) + } + + fn fevent(&self, id: usize, _flags: usize) -> Result<usize> { + let handles = self.handles.read(); + handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(id)) + } + + fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> { + let clock = { + let handles = self.handles.read(); + *handles.get(&id).ok_or(Error::new(EBADF))? + }; + + let mut i = 0; + let scheme_path = format!("time:{}", clock).into_bytes(); + while i < buf.len() && i < scheme_path.len() { + buf[i] = scheme_path[i]; + i += 1; + } + Ok(i) + } + + fn fsync(&self, id: usize) -> Result<usize> { + let handles = self.handles.read(); + handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0)) + } + + fn close(&self, id: usize) -> Result<usize> { + self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0)) + } +} diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs index 882ea78c..1abacd75 100644 --- a/src/scheme/mod.rs +++ b/src/scheme/mod.rs @@ -19,6 +19,7 @@ use self::debug::DebugScheme; use self::event::EventScheme; use self::initfs::InitFsScheme; use self::irq::IrqScheme; +use self::itimer::ITimerScheme; use self::memory::MemoryScheme; use self::pipe::PipeScheme; use self::root::RootScheme; @@ -37,6 +38,9 @@ pub mod initfs; /// `irq:` - allows userspace handling of IRQs pub mod irq; +/// `itimer:` - support for getitimer and setitimer +pub mod itimer; + /// When compiled with "live" feature - `disk:` - embedded filesystem for live disk #[cfg(feature="live")] pub mod live; @@ -115,6 +119,7 @@ impl SchemeList { self.insert(ns, Box::new(*b""), |scheme_id| Arc::new(Box::new(RootScheme::new(ns, scheme_id)))).unwrap(); self.insert(ns, Box::new(*b"event"), |_| Arc::new(Box::new(EventScheme))).unwrap(); + self.insert(ns, Box::new(*b"itimer"), |_| Arc::new(Box::new(ITimerScheme::new()))).unwrap(); self.insert(ns, Box::new(*b"memory"), |_| Arc::new(Box::new(MemoryScheme::new()))).unwrap(); self.insert(ns, Box::new(*b"sys"), |_| Arc::new(Box::new(SysScheme::new()))).unwrap(); self.insert(ns, Box::new(*b"time"), |scheme_id| Arc::new(Box::new(TimeScheme::new(scheme_id)))).unwrap(); diff --git a/src/syscall/debug.rs b/src/syscall/debug.rs index 7f746c68..70cf9d5c 100644 --- a/src/syscall/debug.rs +++ b/src/syscall/debug.rs @@ -254,6 +254,12 @@ pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) - d, e ), + SYS_SIGPROCMASK => format!( + "sigprocmask({}, {:?}, {:?})", + b, + validate_slice(c as *const [u64; 2], 1), + validate_slice(d as *const [u64; 2], 1) + ), SYS_MKNS => format!( "mkns({:?})", validate_slice(b as *const [usize; 2], c) diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index 5528e69b..3f97a4ef 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -125,6 +125,19 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u }, e ), + SYS_SIGPROCMASK => sigprocmask( + b, + if c == 0 { + None + } else { + Some(validate_slice(c as *const [u64; 2], 1).map(|s| &s[0])?) + }, + if d == 0 { + None + } else { + Some(validate_slice_mut(d as *mut [u64; 2], 1).map(|s| &mut s[0])?) + } + ), SYS_SIGRETURN => sigreturn(), SYS_PIPE2 => pipe2(validate_slice_mut(b as *mut usize, 2)?, c), SYS_PHYSALLOC => physalloc(b), diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 65c6a7f9..403cb282 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -1176,6 +1176,11 @@ pub fn sigaction(sig: usize, act_opt: Option<&SigAction>, oldact_opt: Option<&mu } } +pub fn sigprocmask(how: usize, mask_opt: Option<&[u64; 2]>, oldmask_opt: Option<&mut [u64; 2]>) -> Result<usize> { + println!("sigprocmask {}, {:?}, {:?}", how, mask_opt, oldmask_opt); + Ok(0) +} + pub fn sigreturn() -> Result<usize> { { let contexts = context::contexts(); diff --git a/syscall b/syscall index 31b7ae8e..6909fb1c 160000 --- a/syscall +++ b/syscall @@ -1 +1 @@ -Subproject commit 31b7ae8eef2b108e453c2f9b154ca516be900c11 +Subproject commit 6909fb1c32d2c4dd75c0967ab06b894c8f7ed308 -- GitLab