Replace syscall::Scheme with KernelScheme.
This commit is contained in:
@@ -20,7 +20,7 @@ use crate::context::memory::AddrSpace;
|
||||
use crate::ipi::{ipi, IpiKind, IpiTarget};
|
||||
use crate::paging::{RmmA, RmmArch};
|
||||
use crate::memory::{RaiiFrame, Frame};
|
||||
use crate::scheme::{SchemeNamespace, FileHandle};
|
||||
use crate::scheme::{SchemeNamespace, FileHandle, CallerCtx};
|
||||
use crate::sync::WaitMap;
|
||||
|
||||
use crate::syscall::data::SigAction;
|
||||
@@ -472,6 +472,9 @@ impl Context {
|
||||
0
|
||||
); 128]))
|
||||
}
|
||||
pub fn caller_ctx(&self) -> CallerCtx {
|
||||
CallerCtx { pid: self.id.into(), uid: self.euid, gid: self.egid }
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper struct for borrowing the syscall head or tail buf.
|
||||
|
||||
+6
-7
@@ -32,7 +32,7 @@ pub struct FileDescriptor {
|
||||
impl FileDescription {
|
||||
/// Try closing a file, although at this point the description will be destroyed anyway, if
|
||||
/// doing so fails.
|
||||
pub fn try_close(self) -> Result<usize> {
|
||||
pub fn try_close(self) -> Result<()> {
|
||||
event::unregister_file(self.scheme, self.number);
|
||||
|
||||
let scheme = Arc::clone(
|
||||
@@ -44,11 +44,10 @@ impl FileDescription {
|
||||
}
|
||||
|
||||
impl FileDescriptor {
|
||||
pub fn close(self) -> Result<usize> {
|
||||
let Ok(file) = Arc::try_unwrap(self.description) else {
|
||||
return Ok(0);
|
||||
};
|
||||
|
||||
file.into_inner().try_close()
|
||||
pub fn close(self) -> Result<()> {
|
||||
if let Ok(file) = Arc::try_unwrap(self.description) {
|
||||
file.into_inner().try_close()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+12
-13
@@ -20,10 +20,11 @@ use crate::syscall::flag::{
|
||||
O_ACCMODE, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, O_STAT, O_SYMLINK,
|
||||
SEEK_SET, SEEK_CUR, SEEK_END,
|
||||
};
|
||||
use crate::syscall::scheme::Scheme;
|
||||
use crate::syscall::error::{Error, Result};
|
||||
use crate::syscall::usercopy::{UserSliceRo, UserSliceWo};
|
||||
|
||||
use super::{KernelScheme, CallerCtx, OpenResult};
|
||||
|
||||
/// A scheme used to access the RSDT or XSDT, which is needed for e.g. `acpid` to function.
|
||||
pub struct AcpiScheme;
|
||||
|
||||
@@ -113,11 +114,11 @@ impl AcpiScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for AcpiScheme {
|
||||
fn open(&self, path: &str, flags: usize, opener_uid: u32, _opener_gid: u32) -> Result<usize> {
|
||||
impl KernelScheme for AcpiScheme {
|
||||
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let path = path.trim_start_matches('/');
|
||||
|
||||
if opener_uid != 0 {
|
||||
if ctx.uid != 0 {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
if flags & O_CREAT == O_CREAT {
|
||||
@@ -161,9 +162,9 @@ impl Scheme for AcpiScheme {
|
||||
stat: flags & O_STAT == O_STAT,
|
||||
});
|
||||
|
||||
Ok(fd)
|
||||
Ok(OpenResult::SchemeLocal(fd))
|
||||
}
|
||||
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
|
||||
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<usize> {
|
||||
let mut handles = HANDLES.write();
|
||||
let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
@@ -194,7 +195,7 @@ impl Scheme for AcpiScheme {
|
||||
|
||||
handle.offset = new_offset;
|
||||
|
||||
Ok(new_offset as isize)
|
||||
Ok(new_offset)
|
||||
}
|
||||
// TODO
|
||||
fn fevent(&self, id: usize, _flags: EventFlags) -> Result<EventFlags> {
|
||||
@@ -207,14 +208,12 @@ impl Scheme for AcpiScheme {
|
||||
|
||||
Ok(EventFlags::empty())
|
||||
}
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
if HANDLES.write().remove(&id).is_none() {
|
||||
return Err(Error::new(EBADF));
|
||||
}
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl crate::scheme::KernelScheme for AcpiScheme {
|
||||
fn kwrite(&self, _id: usize, _buf: UserSliceRo) -> Result<usize> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
@@ -260,7 +259,7 @@ impl crate::scheme::KernelScheme for AcpiScheme {
|
||||
|
||||
Ok(bytes_copied)
|
||||
}
|
||||
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<()> {
|
||||
let handles = HANDLES.read();
|
||||
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
@@ -286,6 +285,6 @@ impl crate::scheme::KernelScheme for AcpiScheme {
|
||||
},
|
||||
})?;
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+20
-35
@@ -1,12 +1,11 @@
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use spin::{Once, RwLock};
|
||||
|
||||
use crate::arch::debug::Writer;
|
||||
use crate::event;
|
||||
use crate::scheme::*;
|
||||
use crate::sync::WaitQueue;
|
||||
use crate::syscall::flag::{EventFlags, EVENT_READ, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK};
|
||||
use crate::syscall::scheme::Scheme;
|
||||
use crate::syscall::usercopy::UserSliceRo;
|
||||
use crate::syscall::usercopy::UserSliceWo;
|
||||
|
||||
@@ -22,19 +21,7 @@ struct Handle {
|
||||
flags: usize,
|
||||
}
|
||||
|
||||
static HANDLES: Once<RwLock<BTreeMap<usize, Handle>>> = Once::new();
|
||||
|
||||
fn init_handles() -> RwLock<BTreeMap<usize, Handle>> {
|
||||
RwLock::new(BTreeMap::new())
|
||||
}
|
||||
|
||||
fn handles() -> RwLockReadGuard<'static, BTreeMap<usize, Handle>> {
|
||||
HANDLES.call_once(init_handles).read()
|
||||
}
|
||||
|
||||
fn handles_mut() -> RwLockWriteGuard<'static, BTreeMap<usize, Handle>> {
|
||||
HANDLES.call_once(init_handles).write()
|
||||
}
|
||||
static HANDLES: RwLock<BTreeMap<usize, Handle>> = RwLock::new(BTreeMap::new());
|
||||
|
||||
/// Add to the input queue
|
||||
pub fn debug_input(data: u8) {
|
||||
@@ -47,7 +34,7 @@ pub fn debug_notify() {
|
||||
return;
|
||||
};
|
||||
|
||||
for (id, _handle) in handles().iter() {
|
||||
for (id, _handle) in HANDLES.read().iter() {
|
||||
event::trigger(scheme_id, *id, EVENT_READ);
|
||||
}
|
||||
}
|
||||
@@ -61,9 +48,9 @@ impl DebugScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for DebugScheme {
|
||||
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
|
||||
if uid != 0 {
|
||||
impl KernelScheme for DebugScheme {
|
||||
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
if ctx.uid != 0 {
|
||||
return Err(Error::new(EPERM));
|
||||
}
|
||||
|
||||
@@ -71,16 +58,16 @@ impl Scheme for DebugScheme {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
|
||||
let id = NEXT_ID.fetch_add(1, Ordering::SeqCst);
|
||||
handles_mut().insert(id, Handle {
|
||||
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||
HANDLES.write().insert(id, Handle {
|
||||
flags: flags & ! O_ACCMODE
|
||||
});
|
||||
|
||||
Ok(id)
|
||||
Ok(OpenResult::SchemeLocal(id))
|
||||
}
|
||||
|
||||
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
|
||||
let mut handles = handles_mut();
|
||||
let mut handles = HANDLES.write();
|
||||
if let Some(handle) = handles.get_mut(&id) {
|
||||
match cmd {
|
||||
F_GETFL => Ok(handle.flags),
|
||||
@@ -97,36 +84,34 @@ impl Scheme for DebugScheme {
|
||||
|
||||
fn fevent(&self, id: usize, _flags: EventFlags) -> Result<EventFlags> {
|
||||
let _handle = {
|
||||
let handles = handles();
|
||||
let handles = HANDLES.read();
|
||||
*handles.get(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
Ok(EventFlags::empty())
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize) -> Result<usize> {
|
||||
fn fsync(&self, id: usize) -> Result<()> {
|
||||
let _handle = {
|
||||
let handles = handles();
|
||||
let handles = HANDLES.read();
|
||||
*handles.get(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Close the file `number`
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
let _handle = {
|
||||
let mut handles = handles_mut();
|
||||
let mut handles = HANDLES.write();
|
||||
handles.remove(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl crate::scheme::KernelScheme for DebugScheme {
|
||||
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
let handle = {
|
||||
let handles = handles();
|
||||
let handles = HANDLES.read();
|
||||
*handles.get(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
@@ -136,7 +121,7 @@ impl crate::scheme::KernelScheme for DebugScheme {
|
||||
|
||||
fn kwrite(&self, id: usize, buf: UserSliceRo) -> Result<usize> {
|
||||
let _handle = {
|
||||
let handles = handles();
|
||||
let handles = HANDLES.read();
|
||||
*handles.get(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
@@ -156,7 +141,7 @@ impl crate::scheme::KernelScheme for DebugScheme {
|
||||
}
|
||||
fn kfpath(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
let _handle = {
|
||||
let handles = handles();
|
||||
let handles = HANDLES.read();
|
||||
*handles.get(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
|
||||
+9
-11
@@ -4,20 +4,20 @@ use core::mem;
|
||||
use crate::event::{EventQueue, EventQueueId, next_queue_id, queues, queues_mut};
|
||||
use crate::syscall::data::Event;
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::scheme::Scheme;
|
||||
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
|
||||
|
||||
use super::{KernelScheme, CallerCtx, OpenResult};
|
||||
|
||||
pub struct EventScheme;
|
||||
|
||||
impl Scheme for EventScheme {
|
||||
fn open(&self, _path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
impl KernelScheme for EventScheme {
|
||||
fn kopen(&self, _path: &str, _flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let id = next_queue_id();
|
||||
queues_mut().insert(id, Arc::new(EventQueue::new(id)));
|
||||
|
||||
Ok(id.into())
|
||||
Ok(OpenResult::SchemeLocal(id.get()))
|
||||
}
|
||||
|
||||
|
||||
fn fcntl(&self, id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
|
||||
let id = EventQueueId::from(id);
|
||||
|
||||
@@ -25,19 +25,17 @@ impl Scheme for EventScheme {
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize) -> Result<usize> {
|
||||
fn fsync(&self, id: usize) -> Result<()> {
|
||||
let id = EventQueueId::from(id);
|
||||
|
||||
let handles = queues();
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(()))
|
||||
}
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
let id = EventQueueId::from(id);
|
||||
queues_mut().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
queues_mut().remove(&id).ok_or(Error::new(EBADF)).and(Ok(()))
|
||||
}
|
||||
}
|
||||
impl crate::scheme::KernelScheme for EventScheme {
|
||||
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
let id = EventQueueId::from(id);
|
||||
|
||||
|
||||
+17
-17
@@ -16,9 +16,10 @@ use crate::scheme::SchemeId;
|
||||
use crate::syscall::data::Stat;
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::flag::{EventFlags, EVENT_READ, O_DIRECTORY, O_CREAT, O_STAT, MODE_CHR, MODE_DIR};
|
||||
use crate::syscall::scheme::{calc_seek_offset_usize, Scheme};
|
||||
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
|
||||
|
||||
use super::{OpenResult, CallerCtx, calc_seek_offset};
|
||||
|
||||
pub static IRQ_SCHEME_ID: Once<SchemeId> = Once::new();
|
||||
|
||||
/// IRQ queues
|
||||
@@ -146,9 +147,9 @@ const fn vector_to_irq(vector: u8) -> u8 {
|
||||
vector - 32
|
||||
}
|
||||
|
||||
impl Scheme for IrqScheme {
|
||||
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
|
||||
if uid != 0 { return Err(Error::new(EACCES)) }
|
||||
impl crate::scheme::KernelScheme for IrqScheme {
|
||||
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
if ctx.uid != 0 { return Err(Error::new(EACCES)) }
|
||||
|
||||
let path_str = path.trim_start_matches('/');
|
||||
|
||||
@@ -213,21 +214,21 @@ impl Scheme for IrqScheme {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
};
|
||||
let fd = self.next_fd.fetch_add(1, Ordering::SeqCst);
|
||||
let fd = self.next_fd.fetch_add(1, Ordering::Relaxed);
|
||||
HANDLES.write().as_mut().unwrap().insert(fd, handle);
|
||||
Ok(fd)
|
||||
Ok(OpenResult::SchemeLocal(fd))
|
||||
}
|
||||
|
||||
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
|
||||
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<usize> {
|
||||
let handles_guard = HANDLES.read();
|
||||
let handle = handles_guard.as_ref().unwrap().get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
match handle {
|
||||
&Handle::Avail(_, ref buf, ref offset) | &Handle::TopLevel(ref buf, ref offset) => {
|
||||
let cur_offset = offset.load(Ordering::SeqCst);
|
||||
let new_offset = calc_seek_offset_usize(cur_offset, pos, whence, buf.len())?;
|
||||
let new_offset = calc_seek_offset(cur_offset, pos, whence, buf.len())?;
|
||||
offset.store(new_offset as usize, Ordering::SeqCst);
|
||||
Ok(new_offset)
|
||||
Ok(new_offset as usize)
|
||||
}
|
||||
_ => Err(Error::new(ESPIPE)),
|
||||
}
|
||||
@@ -243,11 +244,11 @@ impl Scheme for IrqScheme {
|
||||
}
|
||||
|
||||
|
||||
fn fsync(&self, _file: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
fn fsync(&self, _file: usize) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
let handles_guard = HANDLES.read();
|
||||
let handle = handles_guard.as_ref().unwrap().get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
@@ -256,10 +257,8 @@ impl Scheme for IrqScheme {
|
||||
set_reserved(LogicalCpuId::BSP, irq_to_vector(handle_irq), false);
|
||||
}
|
||||
}
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl crate::scheme::KernelScheme for IrqScheme {
|
||||
fn kwrite(&self, file: usize, buffer: UserSliceRo) -> Result<usize> {
|
||||
let handles_guard = HANDLES.read();
|
||||
let handle = handles_guard.as_ref().unwrap().get(&file).ok_or(Error::new(EBADF))?;
|
||||
@@ -283,7 +282,7 @@ impl crate::scheme::KernelScheme for IrqScheme {
|
||||
}
|
||||
}
|
||||
|
||||
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<()> {
|
||||
let handles_guard = HANDLES.read();
|
||||
let handle = handles_guard.as_ref().unwrap().get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
@@ -321,7 +320,8 @@ impl crate::scheme::KernelScheme for IrqScheme {
|
||||
..Default::default()
|
||||
},
|
||||
})?;
|
||||
Ok(0)
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn kfpath(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
let handles_guard = HANDLES.read();
|
||||
|
||||
+10
-11
@@ -6,9 +6,10 @@ use spin::RwLock;
|
||||
use crate::syscall::data::ITimerSpec;
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC, EventFlags};
|
||||
use crate::syscall::scheme::Scheme;
|
||||
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
|
||||
|
||||
use super::{KernelScheme, CallerCtx, OpenResult};
|
||||
|
||||
pub struct ITimerScheme {
|
||||
next_id: AtomicUsize,
|
||||
handles: RwLock<BTreeMap<usize, usize>>
|
||||
@@ -23,8 +24,8 @@ impl ITimerScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for ITimerScheme {
|
||||
fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
impl KernelScheme for ITimerScheme {
|
||||
fn kopen(&self, path: &str, _flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let clock = path.parse::<usize>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
match clock {
|
||||
@@ -33,10 +34,10 @@ impl Scheme for ITimerScheme {
|
||||
_ => return Err(Error::new(ENOENT))
|
||||
}
|
||||
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||
self.handles.write().insert(id, clock);
|
||||
|
||||
Ok(id)
|
||||
Ok(OpenResult::SchemeLocal(id))
|
||||
}
|
||||
|
||||
fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
|
||||
@@ -48,16 +49,14 @@ impl Scheme for ITimerScheme {
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(EventFlags::empty()))
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize) -> Result<usize> {
|
||||
fn fsync(&self, id: usize) -> Result<()> {
|
||||
let handles = self.handles.read();
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(()))
|
||||
}
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(()))
|
||||
}
|
||||
}
|
||||
impl crate::scheme::KernelScheme for ITimerScheme {
|
||||
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
let _clock = {
|
||||
let handles = self.handles.read();
|
||||
|
||||
+9
-12
@@ -15,10 +15,9 @@ use crate::paging::entry::EntryFlags;
|
||||
use crate::syscall::data::{Map, StatVfs};
|
||||
use crate::syscall::flag::MapFlags;
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::scheme::Scheme;
|
||||
use crate::syscall::usercopy::UserSliceWo;
|
||||
|
||||
use super::KernelScheme;
|
||||
use super::{KernelScheme, CallerCtx, OpenResult};
|
||||
|
||||
pub struct MemoryScheme;
|
||||
|
||||
@@ -118,8 +117,8 @@ impl MemoryScheme {
|
||||
|
||||
}
|
||||
}
|
||||
impl Scheme for MemoryScheme {
|
||||
fn open(&self, path: &str, _flags: usize, uid: u32, _gid: u32) -> Result<usize> {
|
||||
impl KernelScheme for MemoryScheme {
|
||||
fn kopen(&self, path: &str, _flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let intended_handle = match path.trim_start_matches('/') {
|
||||
"" => Handle::Anonymous,
|
||||
"physical" | "physical@wb" => Handle::PhysicalWb,
|
||||
@@ -129,22 +128,20 @@ impl Scheme for MemoryScheme {
|
||||
_ => return Err(Error::new(ENOENT)),
|
||||
};
|
||||
|
||||
if uid != 0 && !matches!(intended_handle, Handle::Anonymous) {
|
||||
if ctx.uid != 0 && !matches!(intended_handle, Handle::Anonymous) {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
Ok(intended_handle as usize)
|
||||
Ok(OpenResult::SchemeLocal(intended_handle as usize))
|
||||
}
|
||||
|
||||
fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn close(&self, _id: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
fn close(&self, _id: usize) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl KernelScheme for MemoryScheme {
|
||||
fn kfmap(&self, id: usize, addr_space: &Arc<RwLock<AddrSpace>>, map: &Map, _consume: bool) -> Result<usize> {
|
||||
match Handle::from_raw(id).ok_or(Error::new(EBADF))? {
|
||||
Handle::Anonymous => Self::fmap_anonymous(addr_space, map),
|
||||
@@ -163,7 +160,7 @@ impl KernelScheme for MemoryScheme {
|
||||
};
|
||||
dst.copy_common_bytes_from_slice(src.as_bytes())
|
||||
}
|
||||
fn kfstatvfs(&self, _file: usize, dst: UserSliceWo) -> Result<usize> {
|
||||
fn kfstatvfs(&self, _file: usize, dst: UserSliceWo) -> Result<()> {
|
||||
let used = used_frames() as u64;
|
||||
let free = free_frames() as u64;
|
||||
|
||||
@@ -175,6 +172,6 @@ impl KernelScheme for MemoryScheme {
|
||||
};
|
||||
dst.copy_exactly(&stat)?;
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+54
-11
@@ -13,14 +13,13 @@ use alloc::{
|
||||
sync::Arc,
|
||||
vec::Vec,
|
||||
};
|
||||
use syscall::{CallerCtx, MunmapFlags, SendFdFlags};
|
||||
use syscall::{MunmapFlags, SendFdFlags, EventFlags, SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
use core::sync::atomic::AtomicUsize;
|
||||
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use crate::context::file::FileDescription;
|
||||
use crate::context::{memory::AddrSpace, file::FileDescriptor};
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::scheme::Scheme;
|
||||
use crate::syscall::usercopy::{UserSliceRo, UserSliceWo};
|
||||
|
||||
#[cfg(all(feature = "acpi", any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
@@ -299,7 +298,11 @@ pub fn schemes_mut() -> RwLockWriteGuard<'static, SchemeList> {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub trait KernelScheme: Scheme + Send + Sync + 'static {
|
||||
pub trait KernelScheme: Send + Sync + 'static {
|
||||
fn kopen(&self, path: &str, flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
|
||||
fn as_filetable(&self, number: usize) -> Result<Arc<RwLock<Vec<Option<FileDescriptor>>>>> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
@@ -317,9 +320,6 @@ pub trait KernelScheme: Scheme + Send + Sync + 'static {
|
||||
Err(Error::new(EOPNOTSUPP))
|
||||
}
|
||||
|
||||
fn kopen(&self, path: &str, flags: usize, caller: CallerCtx) -> Result<OpenResult> {
|
||||
self.open(path, flags, caller.uid, caller.gid).map(OpenResult::SchemeLocal)
|
||||
}
|
||||
fn kdup(&self, old_id: usize, buf: UserSliceRo, _caller: CallerCtx) -> Result<OpenResult> {
|
||||
Err(Error::new(EOPNOTSUPP))
|
||||
}
|
||||
@@ -335,10 +335,10 @@ pub trait KernelScheme: Scheme + Send + Sync + 'static {
|
||||
fn kfutimens(&self, id: usize, buf: UserSliceRo) -> Result<usize> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<()> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
fn kfstatvfs(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
fn kfstatvfs(&self, id: usize, buf: UserSliceWo) -> Result<()> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
|
||||
@@ -346,6 +346,40 @@ pub trait KernelScheme: Scheme + Send + Sync + 'static {
|
||||
Err(Error::new(EOPNOTSUPP))
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize) -> Result<()> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
fn ftruncate(&self, id: usize, len: usize) -> Result<()> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<usize> {
|
||||
Err(Error::new(ESPIPE))
|
||||
}
|
||||
fn fchmod(&self, id: usize, new_mode: u16) -> Result<()> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
fn fchown(&self, id: usize, new_uid: u32, new_gid: u32) -> Result<()> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
fn fevent(&self, id: usize, flags: EventFlags) -> Result<EventFlags> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
fn frename(&self, id: usize, new_path: &str, caller_ctx: CallerCtx) -> Result<()> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
fn rmdir(&self, path: &str, ctx: CallerCtx) -> Result<()> {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
fn unlink(&self, path: &str, ctx: CallerCtx) -> Result<()> {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
|
||||
// TODO: This demonstrates why we need to transition away from a dyn trait.
|
||||
fn as_user_inner(&self) -> Option<Result<Arc<UserInner>>> { None }
|
||||
}
|
||||
@@ -355,9 +389,18 @@ pub enum OpenResult {
|
||||
SchemeLocal(usize),
|
||||
External(Arc<RwLock<FileDescription>>),
|
||||
}
|
||||
pub struct CallerCtx {
|
||||
pub pid: usize,
|
||||
pub uid: u32,
|
||||
pub gid: u32,
|
||||
}
|
||||
|
||||
pub fn current_caller_ctx() -> Result<CallerCtx> {
|
||||
match crate::context::current()?.read() {
|
||||
ref context => Ok(CallerCtx { pid: context.id.into(), uid: context.euid, gid: context.egid }),
|
||||
pub fn calc_seek_offset(cur_pos: usize, rel_pos: isize, whence: usize, len: usize) -> Result<usize> {
|
||||
match whence {
|
||||
SEEK_SET => usize::try_from(rel_pos).map_err(|_| Error::new(EINVAL)),
|
||||
SEEK_CUR => cur_pos.checked_add_signed(rel_pos).ok_or(Error::new(EOVERFLOW)),
|
||||
SEEK_END => len.checked_add_signed(rel_pos).ok_or(Error::new(EOVERFLOW)),
|
||||
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
}
|
||||
}
|
||||
|
||||
+20
-25
@@ -10,11 +10,10 @@ use crate::scheme::SchemeId;
|
||||
use crate::sync::WaitCondition;
|
||||
use crate::syscall::error::{Error, Result, EAGAIN, EBADF, EINTR, EINVAL, ENOENT, EPIPE, ESPIPE};
|
||||
use crate::syscall::flag::{EventFlags, EVENT_READ, EVENT_WRITE, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK, MODE_FIFO};
|
||||
use crate::syscall::scheme::{CallerCtx, Scheme};
|
||||
use crate::syscall::data::Stat;
|
||||
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
|
||||
|
||||
use super::{KernelScheme, OpenResult};
|
||||
use super::{KernelScheme, OpenResult, CallerCtx};
|
||||
|
||||
// TODO: Preallocate a number of scheme IDs, since there can only be *one* root namespace, and
|
||||
// therefore only *one* pipe scheme.
|
||||
@@ -65,8 +64,7 @@ impl PipeScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for PipeScheme {
|
||||
|
||||
impl KernelScheme for PipeScheme {
|
||||
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
|
||||
let (is_writer_not_reader, key) = from_raw_id(id);
|
||||
let pipe = Arc::clone(PIPES.read().get(&key).ok_or(Error::new(EBADF))?);
|
||||
@@ -106,11 +104,11 @@ impl Scheme for PipeScheme {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
|
||||
fn fsync(&self, _id: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
fn fsync(&self, _id: usize) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
let (is_write_not_read, key) = from_raw_id(id);
|
||||
|
||||
let pipe = Arc::clone(PIPES.read().get(&key).ok_or(Error::new(EBADF))?);
|
||||
@@ -136,26 +134,12 @@ impl Scheme for PipeScheme {
|
||||
let _ = PIPES.write().remove(&key);
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn seek(&self, _id: usize, _pos: isize, _whence: usize) -> Result<isize> {
|
||||
fn seek(&self, _id: usize, _pos: isize, _whence: usize) -> Result<usize> {
|
||||
Err(Error::new(ESPIPE))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Pipe {
|
||||
read_flags: AtomicUsize, // fcntl read flags
|
||||
write_flags: AtomicUsize, // fcntl write flags
|
||||
read_condition: WaitCondition, // signals whether there are available bytes to read
|
||||
write_condition: WaitCondition, // signals whether there is room for additional bytes
|
||||
queue: Mutex<VecDeque<u8>>,
|
||||
reader_is_alive: AtomicBool, // starts set, unset when reader closes
|
||||
writer_is_alive: AtomicBool, // starts set, unset when writer closes
|
||||
has_run_dup: AtomicBool,
|
||||
}
|
||||
|
||||
impl KernelScheme for PipeScheme {
|
||||
fn kdup(&self, old_id: usize, user_buf: UserSliceRo, _ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let (is_writer_not_reader, key) = from_raw_id(old_id);
|
||||
|
||||
@@ -277,12 +261,23 @@ impl KernelScheme for PipeScheme {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn kfstat(&self, _id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
fn kfstat(&self, _id: usize, buf: UserSliceWo) -> Result<()> {
|
||||
buf.copy_exactly(&Stat {
|
||||
st_mode: MODE_FIFO | 0o666,
|
||||
..Default::default()
|
||||
})?;
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Pipe {
|
||||
read_flags: AtomicUsize, // fcntl read flags
|
||||
write_flags: AtomicUsize, // fcntl write flags
|
||||
read_condition: WaitCondition, // signals whether there are available bytes to read
|
||||
write_condition: WaitCondition, // signals whether there is room for additional bytes
|
||||
queue: Mutex<VecDeque<u8>>,
|
||||
reader_is_alive: AtomicBool, // starts set, unset when reader closes
|
||||
writer_is_alive: AtomicBool, // starts set, unset when writer closes
|
||||
has_run_dup: AtomicBool,
|
||||
}
|
||||
|
||||
+8
-11
@@ -11,7 +11,6 @@ use crate::{
|
||||
data::{GrantDesc, Map, PtraceEvent, SigAction, Stat},
|
||||
error::*,
|
||||
flag::*,
|
||||
scheme::{CallerCtx, Scheme},
|
||||
self, usercopy::{UserSliceWo, UserSliceRo},
|
||||
}, LogicalCpuId, LogicalCpuSet,
|
||||
};
|
||||
@@ -31,7 +30,7 @@ use core::{
|
||||
};
|
||||
use spin::{Once, RwLock};
|
||||
|
||||
use super::OpenResult;
|
||||
use super::{OpenResult, CallerCtx};
|
||||
|
||||
fn read_from(dst: UserSliceWo, src: &[u8], offset: &mut usize) -> Result<usize> {
|
||||
let avail_src = src.get(*offset..).unwrap_or(&[]);
|
||||
@@ -514,8 +513,8 @@ impl ProcScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for ProcScheme {
|
||||
fn open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
|
||||
impl KernelScheme for ProcScheme {
|
||||
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let mut parts = path.splitn(2, '/');
|
||||
let pid_str = parts.next()
|
||||
.ok_or(Error::new(ENOENT))?;
|
||||
@@ -530,7 +529,7 @@ impl Scheme for ProcScheme {
|
||||
ContextId::new(pid_str.parse().map_err(|_| Error::new(ENOENT))?)
|
||||
};
|
||||
|
||||
self.open_inner(pid, parts.next(), flags, uid, gid)
|
||||
self.open_inner(pid, parts.next(), flags, ctx.uid, ctx.gid).map(OpenResult::SchemeLocal)
|
||||
}
|
||||
|
||||
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
|
||||
@@ -557,7 +556,7 @@ impl Scheme for ProcScheme {
|
||||
}
|
||||
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
let mut handle = self.handles.write().remove(&id).ok_or(Error::new(EBADF))?;
|
||||
handle.continue_ignored_children();
|
||||
|
||||
@@ -617,10 +616,8 @@ impl Scheme for ProcScheme {
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl KernelScheme for ProcScheme {
|
||||
fn as_addrspace(&self, number: usize) -> Result<Arc<RwLock<AddrSpace>>> {
|
||||
if let Operation::AddrSpace { ref addrspace } = self.handles.read().get(&number).ok_or(Error::new(EBADF))?.info.operation {
|
||||
Ok(Arc::clone(addrspace))
|
||||
@@ -1094,7 +1091,7 @@ impl KernelScheme for ProcScheme {
|
||||
|
||||
buf.copy_common_bytes_from_slice(path.as_bytes())
|
||||
}
|
||||
fn kfstat(&self, id: usize, buffer: UserSliceWo) -> Result<usize> {
|
||||
fn kfstat(&self, id: usize, buffer: UserSliceWo) -> Result<()> {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
@@ -1108,7 +1105,7 @@ impl KernelScheme for ProcScheme {
|
||||
..Stat::default()
|
||||
})?;
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Dup is currently used to implement clone() and execve().
|
||||
|
||||
+44
-61
@@ -13,11 +13,12 @@ use crate::context;
|
||||
use crate::syscall::data::Stat;
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::flag::{EventFlags, O_CREAT, MODE_FILE, MODE_DIR};
|
||||
use crate::syscall::scheme::{calc_seek_offset_usize, Scheme};
|
||||
use crate::scheme::{self, SchemeNamespace, SchemeId};
|
||||
use crate::scheme::user::{UserInner, UserScheme};
|
||||
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
|
||||
|
||||
use super::{KernelScheme, CallerCtx, OpenResult, calc_seek_offset};
|
||||
|
||||
struct FolderInner {
|
||||
data: Box<[u8]>,
|
||||
pos: Mutex<usize>
|
||||
@@ -34,9 +35,9 @@ impl FolderInner {
|
||||
Ok(bytes_read)
|
||||
}
|
||||
|
||||
fn seek(&self, pos: isize, whence: usize) -> Result<isize> {
|
||||
fn seek(&self, pos: isize, whence: usize) -> Result<usize> {
|
||||
let mut seek = self.pos.lock();
|
||||
let new_offset = calc_seek_offset_usize(*seek, pos, whence, self.data.len())?;
|
||||
let new_offset = calc_seek_offset(*seek, pos, whence, self.data.len())?;
|
||||
*seek = new_offset as usize;
|
||||
Ok(new_offset)
|
||||
}
|
||||
@@ -67,13 +68,13 @@ impl RootScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for RootScheme {
|
||||
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
|
||||
let path = path.trim_matches('/');
|
||||
impl KernelScheme for RootScheme {
|
||||
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let path = path.trim_start_matches('/');
|
||||
|
||||
//TODO: Make this follow standards for flags and errors
|
||||
if flags & O_CREAT == O_CREAT {
|
||||
if uid != 0 {
|
||||
if ctx.uid != 0 {
|
||||
return Err(Error::new(EACCES));
|
||||
};
|
||||
|
||||
@@ -103,7 +104,7 @@ impl Scheme for RootScheme {
|
||||
|
||||
self.handles.write().insert(id, Handle::Scheme(inner));
|
||||
|
||||
Ok(id)
|
||||
Ok(OpenResult::SchemeLocal(id))
|
||||
} else if path.is_empty() {
|
||||
let scheme_ns = {
|
||||
let contexts = context::contexts();
|
||||
@@ -126,47 +127,46 @@ impl Scheme for RootScheme {
|
||||
pos: Mutex::new(0)
|
||||
});
|
||||
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||
self.handles.write().insert(id, Handle::Folder(inner));
|
||||
Ok(id)
|
||||
Ok(OpenResult::SchemeLocal(id))
|
||||
} else {
|
||||
let inner = Arc::new(
|
||||
path.as_bytes().to_vec().into_boxed_slice()
|
||||
);
|
||||
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||
self.handles.write().insert(id, Handle::File(inner));
|
||||
Ok(id)
|
||||
Ok(OpenResult::SchemeLocal(id))
|
||||
}
|
||||
}
|
||||
|
||||
fn unlink(&self, path: &str, uid: u32, _gid: u32) -> Result<usize> {
|
||||
fn unlink(&self, path: &str, ctx: CallerCtx) -> Result<()> {
|
||||
let path = path.trim_matches('/');
|
||||
|
||||
if uid == 0 {
|
||||
let inner = {
|
||||
let handles = self.handles.read();
|
||||
handles.iter().find_map(|(_id, handle)| {
|
||||
match handle {
|
||||
Handle::Scheme(inner) => {
|
||||
if path == inner.name.as_ref() {
|
||||
return Some(inner.clone());
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
None
|
||||
}).ok_or(Error::new(ENOENT))?
|
||||
};
|
||||
|
||||
inner.unmount()
|
||||
} else {
|
||||
Err(Error::new(EACCES))
|
||||
if ctx.uid != 0 {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
let inner = {
|
||||
let handles = self.handles.read();
|
||||
handles.iter().find_map(|(_id, handle)| {
|
||||
match handle {
|
||||
Handle::Scheme(inner) => {
|
||||
if path == inner.name.as_ref() {
|
||||
return Some(inner.clone());
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
None
|
||||
}).ok_or(Error::new(ENOENT))?
|
||||
};
|
||||
|
||||
inner.unmount()
|
||||
}
|
||||
|
||||
|
||||
fn seek(&self, file: usize, pos: isize, whence: usize) -> Result<isize> {
|
||||
fn seek(&self, file: usize, pos: isize, whence: usize) -> Result<usize> {
|
||||
let handle = {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&file).ok_or(Error::new(EBADF))?;
|
||||
@@ -206,45 +206,30 @@ impl Scheme for RootScheme {
|
||||
}
|
||||
}
|
||||
|
||||
fn fpath(&self, file: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
fn kfpath(&self, file: usize, mut buf: UserSliceWo) -> Result<usize> {
|
||||
let handle = {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&file).ok_or(Error::new(EBADF))?;
|
||||
handle.clone()
|
||||
};
|
||||
|
||||
let mut i = 0;
|
||||
let scheme_path = b":";
|
||||
while i < buf.len() && i < scheme_path.len() {
|
||||
buf[i] = scheme_path[i];
|
||||
i += 1;
|
||||
}
|
||||
let mut bytes_copied = buf.copy_common_bytes_from_slice(b":")?;
|
||||
buf = buf.advance(bytes_copied).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
match handle {
|
||||
Handle::Scheme(inner) => {
|
||||
let name = inner.name.as_bytes();
|
||||
let mut j = 0;
|
||||
while i < buf.len() && j < name.len() {
|
||||
buf[i] = name[j];
|
||||
i += 1;
|
||||
j += 1;
|
||||
}
|
||||
bytes_copied += buf.copy_common_bytes_from_slice(inner.name.as_bytes())?;
|
||||
},
|
||||
Handle::File(inner) => {
|
||||
let mut j = 0;
|
||||
while i < buf.len() && j < inner.len() {
|
||||
buf[i] = inner[j];
|
||||
i += 1;
|
||||
j += 1;
|
||||
}
|
||||
bytes_copied += buf.copy_common_bytes_from_slice(&inner)?;
|
||||
},
|
||||
Handle::Folder(_) => ()
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
Ok(bytes_copied)
|
||||
}
|
||||
|
||||
fn fsync(&self, file: usize) -> Result<usize> {
|
||||
fn fsync(&self, file: usize) -> Result<()> {
|
||||
let handle = {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&file).ok_or(Error::new(EBADF))?;
|
||||
@@ -264,7 +249,7 @@ impl Scheme for RootScheme {
|
||||
}
|
||||
}
|
||||
|
||||
fn close(&self, file: usize) -> Result<usize> {
|
||||
fn close(&self, file: usize) -> Result<()> {
|
||||
let handle = self.handles.write().remove(&file).ok_or(Error::new(EBADF))?;
|
||||
match handle {
|
||||
Handle::Scheme(inner) => {
|
||||
@@ -272,10 +257,8 @@ impl Scheme for RootScheme {
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl crate::scheme::KernelScheme for RootScheme {
|
||||
fn kread(&self, file: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
let handle = {
|
||||
let handles = self.handles.read();
|
||||
@@ -316,7 +299,7 @@ impl crate::scheme::KernelScheme for RootScheme {
|
||||
}
|
||||
}
|
||||
|
||||
fn kfstat(&self, file: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
fn kfstat(&self, file: usize, buf: UserSliceWo) -> Result<()> {
|
||||
let handle = {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&file).ok_or(Error::new(EBADF))?;
|
||||
@@ -347,7 +330,7 @@ impl crate::scheme::KernelScheme for RootScheme {
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-11
@@ -9,7 +9,6 @@ use crate::event;
|
||||
use crate::scheme::*;
|
||||
use crate::sync::WaitQueue;
|
||||
use crate::syscall::flag::{EventFlags, EVENT_READ, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK};
|
||||
use crate::syscall::scheme::Scheme;
|
||||
use crate::syscall::usercopy::UserSliceWo;
|
||||
|
||||
static SCHEME_ID: Once<SchemeId> = Once::new();
|
||||
@@ -49,9 +48,9 @@ impl SerioScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for SerioScheme {
|
||||
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
|
||||
if uid != 0 {
|
||||
impl KernelScheme for SerioScheme {
|
||||
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
if ctx.uid != 0 {
|
||||
return Err(Error::new(EPERM));
|
||||
}
|
||||
|
||||
@@ -68,7 +67,7 @@ impl Scheme for SerioScheme {
|
||||
flags: flags & ! O_ACCMODE
|
||||
});
|
||||
|
||||
Ok(id)
|
||||
Ok(OpenResult::SchemeLocal(id))
|
||||
}
|
||||
|
||||
fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
|
||||
@@ -96,26 +95,24 @@ impl Scheme for SerioScheme {
|
||||
Ok(EventFlags::empty())
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize) -> Result<usize> {
|
||||
fn fsync(&self, id: usize) -> Result<()> {
|
||||
let _handle = {
|
||||
let handles = HANDLES.read();
|
||||
*handles.get(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Close the file `number`
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
let _handle = {
|
||||
let mut handles = HANDLES.write();
|
||||
handles.remove(&id).ok_or(Error::new(EBADF))?
|
||||
};
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl crate::scheme::KernelScheme for SerioScheme {
|
||||
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
let handle = {
|
||||
let handles = HANDLES.read();
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt::Write;
|
||||
use core::str;
|
||||
|
||||
use crate::context;
|
||||
use crate::scheme;
|
||||
use crate::syscall::error::Result;
|
||||
@@ -33,7 +31,7 @@ pub fn resource() -> Result<Vec<u8>> {
|
||||
|
||||
let description = file.description.read();
|
||||
|
||||
let scheme = {
|
||||
let _scheme = {
|
||||
let schemes = scheme::schemes();
|
||||
match schemes.get(description.scheme) {
|
||||
Some(scheme) => scheme.clone(),
|
||||
@@ -44,6 +42,7 @@ pub fn resource() -> Result<Vec<u8>> {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
let mut fpath = [0; 4096];
|
||||
match scheme.fpath(description.number, &mut fpath) {
|
||||
Ok(path_len) => {
|
||||
@@ -54,6 +53,7 @@ pub fn resource() -> Result<Vec<u8>> {
|
||||
let _ = writeln!(string, "{:>6}: {:>8} {:>8} {:>08X}: {}", fd, description.scheme.get(), description.number, description.flags, err);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-17
@@ -7,10 +7,11 @@ use spin::RwLock;
|
||||
use crate::syscall::data::Stat;
|
||||
use crate::syscall::error::{Error, EBADF, ENOENT, Result};
|
||||
use crate::syscall::flag::{MODE_DIR, MODE_FILE};
|
||||
use crate::syscall::scheme::{calc_seek_offset_usize, Scheme};
|
||||
use crate::arch::interrupt;
|
||||
use crate::syscall::usercopy::UserSliceWo;
|
||||
|
||||
use super::{KernelScheme, CallerCtx, OpenResult, calc_seek_offset};
|
||||
|
||||
mod block;
|
||||
mod context;
|
||||
mod cpu;
|
||||
@@ -74,8 +75,8 @@ impl SysScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for SysScheme {
|
||||
fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
impl KernelScheme for SysScheme {
|
||||
fn kopen(&self, path: &str, _flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let path = path.trim_matches('/');
|
||||
|
||||
if path.is_empty() {
|
||||
@@ -87,19 +88,19 @@ impl Scheme for SysScheme {
|
||||
data.extend_from_slice(entry.0.as_bytes());
|
||||
}
|
||||
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||
self.handles.write().insert(id, Handle {
|
||||
path: "",
|
||||
data,
|
||||
mode: MODE_DIR | 0o444,
|
||||
seek: 0
|
||||
});
|
||||
return Ok(id)
|
||||
return Ok(OpenResult::SchemeLocal(id))
|
||||
} else {
|
||||
//Have to iterate to get the path without allocation
|
||||
for entry in self.files.iter() {
|
||||
if entry.0 == &path {
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||
let data = entry.1()?;
|
||||
self.handles.write().insert(id, Handle {
|
||||
path: entry.0,
|
||||
@@ -107,7 +108,7 @@ impl Scheme for SysScheme {
|
||||
mode: MODE_FILE | 0o444,
|
||||
seek: 0
|
||||
});
|
||||
return Ok(id)
|
||||
return Ok(OpenResult::SchemeLocal(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,24 +116,22 @@ impl Scheme for SysScheme {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
|
||||
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
|
||||
fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<usize> {
|
||||
let mut handles = self.handles.write();
|
||||
let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
let new_offset = calc_seek_offset_usize(handle.seek, pos, whence, handle.data.len())?;
|
||||
let new_offset = calc_seek_offset(handle.seek, pos, whence, handle.data.len())?;
|
||||
handle.seek = new_offset as usize;
|
||||
Ok(new_offset)
|
||||
}
|
||||
|
||||
fn fsync(&self, _id: usize) -> Result<usize> {
|
||||
Ok(0)
|
||||
fn fsync(&self, _id: usize) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(()))
|
||||
}
|
||||
}
|
||||
impl crate::scheme::KernelScheme for SysScheme {
|
||||
fn kfpath(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
@@ -159,7 +158,7 @@ impl crate::scheme::KernelScheme for SysScheme {
|
||||
Ok(byte_count)
|
||||
}
|
||||
|
||||
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
fn kfstat(&self, id: usize, buf: UserSliceWo) -> Result<()> {
|
||||
let handles = self.handles.read();
|
||||
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
@@ -171,6 +170,6 @@ impl crate::scheme::KernelScheme for SysScheme {
|
||||
..Default::default()
|
||||
})?;
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+12
-13
@@ -8,10 +8,11 @@ use crate::scheme::SchemeId;
|
||||
use crate::syscall::data::TimeSpec;
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::flag::{CLOCK_REALTIME, CLOCK_MONOTONIC, EventFlags};
|
||||
use crate::syscall::scheme::Scheme;
|
||||
use crate::syscall::usercopy::{UserSliceWo, UserSliceRo};
|
||||
use crate::time;
|
||||
|
||||
use super::{KernelScheme, CallerCtx, OpenResult};
|
||||
|
||||
pub struct TimeScheme {
|
||||
scheme_id: SchemeId,
|
||||
next_id: AtomicUsize,
|
||||
@@ -28,9 +29,9 @@ impl TimeScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for TimeScheme {
|
||||
fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
let clock = path.parse::<usize>().or(Err(Error::new(ENOENT)))?;
|
||||
impl KernelScheme for TimeScheme {
|
||||
fn kopen(&self, path: &str, _flags: usize, _ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let clock = path.parse::<usize>().map_err(|_| Error::new(ENOENT))?;
|
||||
|
||||
match clock {
|
||||
CLOCK_REALTIME => (),
|
||||
@@ -38,10 +39,10 @@ impl Scheme for TimeScheme {
|
||||
_ => return Err(Error::new(ENOENT))
|
||||
}
|
||||
|
||||
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
||||
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
|
||||
self.handles.write().insert(id, clock);
|
||||
|
||||
Ok(id)
|
||||
Ok(OpenResult::SchemeLocal(id))
|
||||
}
|
||||
|
||||
fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
|
||||
@@ -53,16 +54,14 @@ impl Scheme for TimeScheme {
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(EventFlags::empty()))
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize) -> Result<usize> {
|
||||
let handles = self.handles.read();
|
||||
handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
fn fsync(&self, id: usize) -> Result<()> {
|
||||
self.handles.read().get(&id).ok_or(Error::new(EBADF))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn close(&self, id: usize) -> Result<usize> {
|
||||
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(0))
|
||||
fn close(&self, id: usize) -> Result<()> {
|
||||
self.handles.write().remove(&id).ok_or(Error::new(EBADF)).and(Ok(()))
|
||||
}
|
||||
}
|
||||
impl crate::scheme::KernelScheme for TimeScheme {
|
||||
fn kread(&self, id: usize, buf: UserSliceWo) -> Result<usize> {
|
||||
let clock = {
|
||||
let handles = self.handles.read();
|
||||
|
||||
+45
-55
@@ -3,12 +3,11 @@ use alloc::sync::{Arc, Weak};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::vec::Vec;
|
||||
use syscall::{SKMSG_FRETURNFD, CallerCtx, SKMSG_PROVIDE_MMAP, MAP_FIXED_NOREPLACE, MunmapFlags, SKMSG_FOBTAINFD, FobtainFdFlags, SendFdFlags};
|
||||
use syscall::{SKMSG_FRETURNFD, SKMSG_PROVIDE_MMAP, MAP_FIXED_NOREPLACE, MunmapFlags, SKMSG_FOBTAINFD, FobtainFdFlags, SendFdFlags};
|
||||
use core::mem::size_of;
|
||||
use core::num::NonZeroUsize;
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
use core::{mem, usize};
|
||||
use core::convert::TryFrom;
|
||||
use spin::{Mutex, RwLock};
|
||||
|
||||
use crate::context::context::HardBlockedReason;
|
||||
@@ -25,10 +24,9 @@ use crate::syscall::data::{Map, Packet};
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::flag::{EventFlags, EVENT_READ, O_NONBLOCK, PROT_READ, PROT_WRITE, MapFlags};
|
||||
use crate::syscall::number::*;
|
||||
use crate::syscall::scheme::Scheme;
|
||||
use crate::syscall::usercopy::{UserSlice, UserSliceWo, UserSliceRo};
|
||||
|
||||
use super::{FileHandle, OpenResult, KernelScheme, current_caller_ctx};
|
||||
use super::{FileHandle, OpenResult, KernelScheme, CallerCtx};
|
||||
|
||||
pub struct UserInner {
|
||||
root_id: SchemeId,
|
||||
@@ -74,7 +72,7 @@ impl UserInner {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unmount(&self) -> Result<usize> {
|
||||
pub fn unmount(&self) -> Result<()> {
|
||||
// First, block new requests and prepare to return EOF
|
||||
self.unmounting.store(true, Ordering::SeqCst);
|
||||
|
||||
@@ -85,7 +83,7 @@ impl UserInner {
|
||||
event::trigger(self.root_id, self.handle_id, EVENT_READ);
|
||||
|
||||
//TODO: wait for all todo and done to be processed?
|
||||
Ok(0)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn next_id(&self) -> u64 {
|
||||
@@ -96,7 +94,8 @@ impl UserInner {
|
||||
}
|
||||
|
||||
pub fn call(&self, a: usize, b: usize, c: usize, d: usize) -> Result<usize> {
|
||||
match self.call_extended(current_caller_ctx()?, None, [a, b, c, d])? {
|
||||
let ctx = context::current()?.read().caller_ctx();
|
||||
match self.call_extended(ctx, None, [a, b, c, d])? {
|
||||
Response::Regular(code) => Error::demux(code),
|
||||
Response::Fd(_) => {
|
||||
if a & SYS_RET_FILE == SYS_RET_FILE {
|
||||
@@ -555,8 +554,8 @@ impl UserInner {
|
||||
Ok(EventFlags::empty())
|
||||
}
|
||||
|
||||
pub fn fsync(&self) -> Result<usize> {
|
||||
Ok(0)
|
||||
pub fn fsync(&self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fmap_inner(&self, dst_addr_space: Arc<RwLock<AddrSpace>>, file: usize, map: &Map) -> Result<usize> {
|
||||
@@ -758,45 +757,41 @@ impl UserScheme {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_open_res(res: OpenResult) -> Result<usize> {
|
||||
match res {
|
||||
OpenResult::SchemeLocal(num) => Ok(num),
|
||||
OpenResult::External(_) => {
|
||||
log::warn!("Used Scheme::open when forwarding fd!");
|
||||
Err(Error::new(EIO))
|
||||
impl KernelScheme for UserScheme {
|
||||
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let address = inner.copy_and_capture_tail(path.as_bytes())?;
|
||||
match inner.call_extended(ctx, None, [SYS_OPEN, address.base(), address.len(), flags])? {
|
||||
Response::Regular(code) => Error::demux(code).map(OpenResult::SchemeLocal),
|
||||
Response::Fd(desc) => Ok(OpenResult::External(desc)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Scheme for UserScheme {
|
||||
fn open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
|
||||
self.kopen(path, flags, CallerCtx { uid, gid, pid: context::context_id().into() }).and_then(handle_open_res)
|
||||
}
|
||||
|
||||
fn rmdir(&self, path: &str, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
fn rmdir(&self, path: &str, _ctx: CallerCtx) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let address = inner.copy_and_capture_tail(path.as_bytes())?;
|
||||
inner.call(SYS_RMDIR, address.base(), address.len(), 0)
|
||||
inner.call(SYS_RMDIR, address.base(), address.len(), 0)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unlink(&self, path: &str, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
fn unlink(&self, path: &str, _ctx: CallerCtx) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let address = inner.copy_and_capture_tail(path.as_bytes())?;
|
||||
inner.call(SYS_UNLINK, address.base(), address.len(), 0)
|
||||
inner.call(SYS_UNLINK, address.base(), address.len(), 0)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn seek(&self, file: usize, position: isize, whence: usize) -> Result<isize> {
|
||||
fn seek(&self, file: usize, position: isize, whence: usize) -> Result<usize> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let new_offset = inner.call(SYS_LSEEK, file, position as usize, whence)?;
|
||||
isize::try_from(new_offset).or_else(|_| Err(Error::new(EOVERFLOW)))
|
||||
inner.call(SYS_LSEEK, file, position as usize, whence)
|
||||
}
|
||||
|
||||
fn fchmod(&self, file: usize, mode: u16) -> Result<usize> {
|
||||
fn fchmod(&self, file: usize, mode: u16) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
inner.call(SYS_FCHMOD, file, mode as usize, 0)
|
||||
inner.call(SYS_FCHMOD, file, mode as usize, 0)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fchown(&self, file: usize, uid: u32, gid: u32) -> Result<usize> {
|
||||
fn fchown(&self, file: usize, uid: u32, gid: u32) -> Result<()> {
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
@@ -809,7 +804,8 @@ impl Scheme for UserScheme {
|
||||
}
|
||||
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
inner.call(SYS_FCHOWN, file, uid as usize, gid as usize)
|
||||
inner.call(SYS_FCHOWN, file, uid as usize, gid as usize)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fcntl(&self, file: usize, cmd: usize, arg: usize) -> Result<usize> {
|
||||
@@ -867,35 +863,29 @@ impl Scheme for UserScheme {
|
||||
}
|
||||
*/
|
||||
|
||||
fn frename(&self, file: usize, path: &str, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
fn frename(&self, file: usize, path: &str, _ctx: CallerCtx) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let address = inner.copy_and_capture_tail(path.as_bytes())?;
|
||||
inner.call(SYS_FRENAME, file, address.base(), address.len())
|
||||
inner.call(SYS_FRENAME, file, address.base(), address.len())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fsync(&self, file: usize) -> Result<usize> {
|
||||
fn fsync(&self, file: usize) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
inner.call(SYS_FSYNC, file, 0, 0)
|
||||
inner.call(SYS_FSYNC, file, 0, 0)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ftruncate(&self, file: usize, len: usize) -> Result<usize> {
|
||||
fn ftruncate(&self, file: usize, len: usize) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
inner.call(SYS_FTRUNCATE, file, len, 0)
|
||||
inner.call(SYS_FTRUNCATE, file, len, 0)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn close(&self, file: usize) -> Result<usize> {
|
||||
fn close(&self, file: usize) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
inner.call(SYS_CLOSE, file, 0, 0)
|
||||
}
|
||||
}
|
||||
impl KernelScheme for UserScheme {
|
||||
fn kopen(&self, path: &str, flags: usize, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let address = inner.copy_and_capture_tail(path.as_bytes())?;
|
||||
match inner.call_extended(ctx, None, [SYS_OPEN, address.base(), address.len(), flags])? {
|
||||
Response::Regular(code) => Error::demux(code).map(OpenResult::SchemeLocal),
|
||||
Response::Fd(desc) => Ok(OpenResult::External(desc)),
|
||||
}
|
||||
inner.call(SYS_CLOSE, file, 0, 0)?;
|
||||
Ok(())
|
||||
}
|
||||
fn kdup(&self, file: usize, buf: UserSliceRo, ctx: CallerCtx) -> Result<OpenResult> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
@@ -939,19 +929,19 @@ impl KernelScheme for UserScheme {
|
||||
address.release()?;
|
||||
result
|
||||
}
|
||||
fn kfstat(&self, file: usize, stat: UserSliceWo) -> Result<usize> {
|
||||
fn kfstat(&self, file: usize, stat: UserSliceWo) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let address = inner.capture_user(stat)?;
|
||||
let result = inner.call(SYS_FSTAT, file, address.base(), address.len());
|
||||
address.release()?;
|
||||
result
|
||||
result.map(|_| ())
|
||||
}
|
||||
fn kfstatvfs(&self, file: usize, stat: UserSliceWo) -> Result<usize> {
|
||||
fn kfstatvfs(&self, file: usize, stat: UserSliceWo) -> Result<()> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
let address = inner.capture_user(stat)?;
|
||||
let result = inner.call(SYS_FSTATVFS, file, address.base(), address.len());
|
||||
address.release()?;
|
||||
result
|
||||
result.map(|_| ())
|
||||
}
|
||||
fn kfmap(&self, file: usize, addr_space: &Arc<RwLock<AddrSpace>>, map: &Map, _consume: bool) -> Result<usize> {
|
||||
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
|
||||
|
||||
+23
-23
@@ -7,11 +7,10 @@ use crate::context::file::{FileDescriptor, FileDescription};
|
||||
use crate::context;
|
||||
use crate::context::memory::{PageSpan, AddrSpace};
|
||||
use crate::paging::{PAGE_SIZE, VirtualAddress, Page};
|
||||
use crate::scheme::{self, FileHandle, OpenResult, current_caller_ctx, KernelScheme, SchemeId};
|
||||
use crate::scheme::{self, FileHandle, OpenResult, KernelScheme, SchemeId, CallerCtx};
|
||||
use crate::syscall::data::Stat;
|
||||
use crate::syscall::error::*;
|
||||
use crate::syscall::flag::*;
|
||||
use crate::syscall::scheme::CallerCtx;
|
||||
|
||||
use super::usercopy::{UserSlice, UserSliceWo, UserSliceRo};
|
||||
|
||||
@@ -87,9 +86,9 @@ pub fn open(raw_path: UserSliceRo, flags: usize) -> Result<FileHandle> {
|
||||
}
|
||||
|
||||
/// rmdir syscall
|
||||
pub fn rmdir(raw_path: UserSliceRo) -> Result<usize> {
|
||||
let (uid, gid, scheme_ns) = match context::current()?.read() {
|
||||
ref context => (context.euid, context.egid, context.ens),
|
||||
pub fn rmdir(raw_path: UserSliceRo) -> Result<()> {
|
||||
let (scheme_ns, caller_ctx) = match context::current()?.read() {
|
||||
ref context => (context.ens, context.caller_ctx()),
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -107,13 +106,13 @@ pub fn rmdir(raw_path: UserSliceRo) -> Result<usize> {
|
||||
let (_scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
|
||||
Arc::clone(scheme)
|
||||
};
|
||||
scheme.rmdir(reference, uid, gid)
|
||||
scheme.rmdir(reference, caller_ctx)
|
||||
}
|
||||
|
||||
/// Unlink syscall
|
||||
pub fn unlink(raw_path: UserSliceRo) -> Result<usize> {
|
||||
let (uid, gid, scheme_ns) = match context::current()?.read() {
|
||||
ref context => (context.euid, context.egid, context.ens),
|
||||
pub fn unlink(raw_path: UserSliceRo) -> Result<()> {
|
||||
let (scheme_ns, caller_ctx) = match context::current()?.read() {
|
||||
ref context => (context.ens, context.caller_ctx()),
|
||||
};
|
||||
/*
|
||||
let mut path_buf = BorrowedHtBuf::head()?;
|
||||
@@ -130,11 +129,11 @@ pub fn unlink(raw_path: UserSliceRo) -> Result<usize> {
|
||||
let (_scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
|
||||
Arc::clone(scheme)
|
||||
};
|
||||
scheme.unlink(reference, uid, gid)
|
||||
scheme.unlink(reference, caller_ctx)
|
||||
}
|
||||
|
||||
/// Close syscall
|
||||
pub fn close(fd: FileHandle) -> Result<usize> {
|
||||
pub fn close(fd: FileHandle) -> Result<()> {
|
||||
let file = {
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
@@ -146,8 +145,9 @@ pub fn close(fd: FileHandle) -> Result<usize> {
|
||||
}
|
||||
|
||||
fn duplicate_file(fd: FileHandle, user_buf: UserSliceRo) -> Result<FileDescriptor> {
|
||||
let file = context::current()?.read()
|
||||
.get_file(fd).ok_or(Error::new(EBADF))?;
|
||||
let (file, caller_ctx) = match context::current()?.read() {
|
||||
ref context => (context.get_file(fd).ok_or(Error::new(EBADF))?, context.caller_ctx()),
|
||||
};
|
||||
|
||||
if user_buf.is_empty() {
|
||||
Ok(FileDescriptor {
|
||||
@@ -164,7 +164,7 @@ fn duplicate_file(fd: FileHandle, user_buf: UserSliceRo) -> Result<FileDescripto
|
||||
Arc::clone(scheme)
|
||||
};
|
||||
|
||||
match scheme.kdup(description.number, user_buf, current_caller_ctx()?)? {
|
||||
match scheme.kdup(description.number, user_buf, caller_ctx)? {
|
||||
OpenResult::SchemeLocal(number) => Arc::new(RwLock::new(FileDescription {
|
||||
namespace: description.namespace,
|
||||
scheme: description.scheme,
|
||||
@@ -309,9 +309,9 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize) -> Result<usize> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn frename(fd: FileHandle, raw_path: UserSliceRo) -> Result<usize> {
|
||||
let (file, uid, gid, scheme_ns) = match context::current()?.read() {
|
||||
ref context => (context.get_file(fd).ok_or(Error::new(EBADF))?, context.euid, context.egid, context.ens),
|
||||
pub fn frename(fd: FileHandle, raw_path: UserSliceRo) -> Result<()> {
|
||||
let (file, caller_ctx, scheme_ns) = match context::current()?.read() {
|
||||
ref context => (context.get_file(fd).ok_or(Error::new(EBADF))?, CallerCtx { uid: context.euid, gid: context.egid, pid: context.id.get() }, context.ens),
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -332,15 +332,15 @@ pub fn frename(fd: FileHandle, raw_path: UserSliceRo) -> Result<usize> {
|
||||
|
||||
let description = file.description.read();
|
||||
|
||||
if scheme_id == description.scheme {
|
||||
scheme.frename(description.number, reference, uid, gid)
|
||||
} else {
|
||||
Err(Error::new(EXDEV))
|
||||
if scheme_id != description.scheme {
|
||||
return Err(Error::new(EXDEV));
|
||||
}
|
||||
|
||||
scheme.frename(description.number, reference, caller_ctx)
|
||||
}
|
||||
|
||||
/// File status
|
||||
pub fn fstat(fd: FileHandle, user_buf: UserSliceWo) -> Result<usize> {
|
||||
pub fn fstat(fd: FileHandle, user_buf: UserSliceWo) -> Result<()> {
|
||||
file_op_generic_ext(fd, |scheme, scheme_id, _, number| {
|
||||
scheme.kfstat(number, user_buf)?;
|
||||
|
||||
@@ -350,7 +350,7 @@ pub fn fstat(fd: FileHandle, user_buf: UserSliceWo) -> Result<usize> {
|
||||
let st_dev = scheme_id.get().try_into().map_err(|_| Error::new(EOVERFLOW))?;
|
||||
user_buf.advance(memoffset::offset_of!(Stat, st_dev)).and_then(|b| b.limit(8)).ok_or(Error::new(EIO))?.copy_from_slice(&u64::to_ne_bytes(st_dev))?;
|
||||
|
||||
Ok(0)
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -16,7 +16,6 @@ pub use self::syscall::{
|
||||
io,
|
||||
number,
|
||||
ptrace_event,
|
||||
scheme,
|
||||
};
|
||||
|
||||
pub use self::driver::*;
|
||||
@@ -91,8 +90,8 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack
|
||||
SYS_ARG_MSLICE => match a {
|
||||
SYS_READ => file_op_generic(fd, |scheme, _, number| scheme.kread(number, UserSlice::wo(c, d)?)),
|
||||
SYS_FPATH => file_op_generic(fd, |scheme, _, number| scheme.kfpath(number, UserSlice::wo(c, d)?)),
|
||||
SYS_FSTAT => fstat(fd, UserSlice::wo(c, d)?),
|
||||
SYS_FSTATVFS => file_op_generic(fd, |scheme, _, number| scheme.kfstatvfs(number, UserSlice::wo(c, d)?)),
|
||||
SYS_FSTAT => fstat(fd, UserSlice::wo(c, d)?).map(|()| 0),
|
||||
SYS_FSTATVFS => file_op_generic(fd, |scheme, _, number| scheme.kfstatvfs(number, UserSlice::wo(c, d)?).map(|()| 0)),
|
||||
|
||||
_ => return Err(Error::new(ENOSYS)),
|
||||
},
|
||||
@@ -106,18 +105,19 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
SYS_SENDFD => sendfd(fd, FileHandle::from(c), d, e as u64),
|
||||
|
||||
SYS_LSEEK => file_op_generic(fd, |scheme, _, number| Ok(scheme.seek(number, c as isize, d)? as usize)),
|
||||
SYS_FCHMOD => file_op_generic(fd, |scheme, _, number| scheme.fchmod(number, c as u16)),
|
||||
SYS_FCHOWN => file_op_generic(fd, |scheme, _, number| scheme.fchown(number, c as u32, d as u32)),
|
||||
SYS_LSEEK => file_op_generic(fd, |scheme, _, number| scheme.seek(number, c as isize, d)),
|
||||
SYS_FCHMOD => file_op_generic(fd, |scheme, _, number| scheme.fchmod(number, c as u16).map(|()| 0)),
|
||||
SYS_FCHOWN => file_op_generic(fd, |scheme, _, number| scheme.fchown(number, c as u32, d as u32).map(|()| 0)),
|
||||
SYS_FCNTL => fcntl(fd, c, d),
|
||||
SYS_FEVENT => file_op_generic(fd, |scheme, _, number| Ok(scheme.fevent(number, EventFlags::from_bits_truncate(c))?.bits())),
|
||||
SYS_FRENAME => frename(fd, UserSlice::ro(c, d)?),
|
||||
SYS_FRENAME => frename(fd, UserSlice::ro(c, d)?).map(|()| 0),
|
||||
SYS_FUNMAP => funmap(b, c),
|
||||
|
||||
SYS_FSYNC => file_op_generic(fd, |scheme, _, number| scheme.fsync(number)),
|
||||
SYS_FTRUNCATE => file_op_generic(fd, |scheme, _, number| scheme.ftruncate(number, c)),
|
||||
SYS_FSYNC => file_op_generic(fd, |scheme, _, number| scheme.fsync(number).map(|()| 0)),
|
||||
// TODO: 64-bit lengths on 32-bit platforms
|
||||
SYS_FTRUNCATE => file_op_generic(fd, |scheme, _, number| scheme.ftruncate(number, c).map(|()| 0)),
|
||||
|
||||
SYS_CLOSE => close(fd),
|
||||
SYS_CLOSE => close(fd).map(|()| 0),
|
||||
|
||||
_ => return Err(Error::new(ENOSYS)),
|
||||
}
|
||||
@@ -125,8 +125,8 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack
|
||||
},
|
||||
SYS_CLASS_PATH => match a {
|
||||
SYS_OPEN => open(UserSlice::ro(b, c)?, d).map(FileHandle::into),
|
||||
SYS_RMDIR => rmdir(UserSlice::ro(b, c)?),
|
||||
SYS_UNLINK => unlink(UserSlice::ro(b, c)?),
|
||||
SYS_RMDIR => rmdir(UserSlice::ro(b, c)?).map(|()| 0),
|
||||
SYS_UNLINK => unlink(UserSlice::ro(b, c)?).map(|()| 0),
|
||||
_ => Err(Error::new(ENOSYS))
|
||||
},
|
||||
_ => match a {
|
||||
|
||||
Reference in New Issue
Block a user