2016-09-20 16:47:16 +02:00
|
|
|
use alloc::arc::Arc;
|
|
|
|
use alloc::boxed::Box;
|
|
|
|
use collections::BTreeMap;
|
2016-11-04 13:49:44 +01:00
|
|
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
2016-09-20 16:47:16 +02:00
|
|
|
use spin::RwLock;
|
|
|
|
|
2016-09-20 22:50:04 +02:00
|
|
|
use context;
|
2016-09-21 00:23:28 +02:00
|
|
|
use syscall::error::*;
|
|
|
|
use syscall::scheme::Scheme;
|
2016-11-17 04:54:38 +01:00
|
|
|
use scheme::{self, SchemeNamespace, SchemeId};
|
2016-09-20 16:47:16 +02:00
|
|
|
use scheme::user::{UserInner, UserScheme};
|
|
|
|
|
|
|
|
pub struct RootScheme {
|
2016-11-17 04:54:38 +01:00
|
|
|
scheme_ns: SchemeNamespace,
|
|
|
|
scheme_id: SchemeId,
|
2016-09-20 16:47:16 +02:00
|
|
|
next_id: AtomicUsize,
|
|
|
|
handles: RwLock<BTreeMap<usize, Arc<UserInner>>>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RootScheme {
|
2016-11-17 04:54:38 +01:00
|
|
|
pub fn new(scheme_ns: SchemeNamespace, scheme_id: SchemeId) -> RootScheme {
|
2016-09-20 16:47:16 +02:00
|
|
|
RootScheme {
|
2016-11-17 04:54:38 +01:00
|
|
|
scheme_ns: scheme_ns,
|
|
|
|
scheme_id: scheme_id,
|
2016-09-20 16:47:16 +02:00
|
|
|
next_id: AtomicUsize::new(0),
|
|
|
|
handles: RwLock::new(BTreeMap::new())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Scheme for RootScheme {
|
2016-10-20 20:31:39 +02:00
|
|
|
fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<usize> {
|
Orbital (#16)
* Port previous ethernet scheme
* Add ipd
* Fix initfs rebuilds, use QEMU user networking addresses in ipd
* Add tcp/udp, netutils, dns, and network config
* Add fsync to network driver
* Add dns, router, subnet by default
* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks
* Add orbital server, WIP
* Add futex
* Add orbutils and orbital
* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad
* Add orbital assets
* Update orbital
* Update to add login manager
* Add blocking primitives, block for most things except waitpid, update orbital
* Wait in waitpid and IRQ, improvements for other waits
* Fevent in root scheme
* WIP: Switch to using fevent
* Reorganize
* Event based e1000d driver
* Superuser-only access to some network schemes, display, and disk
* Superuser root and irq schemes
* Fix orbital
2016-10-14 01:21:42 +02:00
|
|
|
if uid == 0 {
|
|
|
|
let context = {
|
|
|
|
let contexts = context::contexts();
|
|
|
|
let context = contexts.current().ok_or(Error::new(ESRCH))?;
|
|
|
|
Arc::downgrade(&context)
|
|
|
|
};
|
|
|
|
|
|
|
|
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
|
|
|
|
|
|
|
let inner = {
|
|
|
|
let mut schemes = scheme::schemes_mut();
|
2016-11-17 04:54:38 +01:00
|
|
|
let inner = Arc::new(UserInner::new(self.scheme_id, id, flags, context));
|
|
|
|
schemes.insert(self.scheme_ns, path.to_vec().into_boxed_slice(), |scheme_id| {
|
|
|
|
inner.scheme_id.store(scheme_id, Ordering::SeqCst);
|
|
|
|
Arc::new(Box::new(UserScheme::new(Arc::downgrade(&inner))))
|
|
|
|
})?;
|
Orbital (#16)
* Port previous ethernet scheme
* Add ipd
* Fix initfs rebuilds, use QEMU user networking addresses in ipd
* Add tcp/udp, netutils, dns, and network config
* Add fsync to network driver
* Add dns, router, subnet by default
* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks
* Add orbital server, WIP
* Add futex
* Add orbutils and orbital
* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad
* Add orbital assets
* Update orbital
* Update to add login manager
* Add blocking primitives, block for most things except waitpid, update orbital
* Wait in waitpid and IRQ, improvements for other waits
* Fevent in root scheme
* WIP: Switch to using fevent
* Reorganize
* Event based e1000d driver
* Superuser-only access to some network schemes, display, and disk
* Superuser root and irq schemes
* Fix orbital
2016-10-14 01:21:42 +02:00
|
|
|
inner
|
|
|
|
};
|
|
|
|
|
|
|
|
self.handles.write().insert(id, inner);
|
|
|
|
|
|
|
|
Ok(id)
|
|
|
|
} else {
|
|
|
|
Err(Error::new(EACCES))
|
|
|
|
}
|
2016-09-20 16:47:16 +02:00
|
|
|
}
|
|
|
|
|
2016-10-26 21:19:56 +02:00
|
|
|
fn dup(&self, file: usize, _buf: &[u8]) -> Result<usize> {
|
2016-09-20 17:21:54 +02:00
|
|
|
let mut handles = self.handles.write();
|
2016-09-20 16:47:16 +02:00
|
|
|
let inner = {
|
2016-09-21 00:23:28 +02:00
|
|
|
let inner = handles.get(&file).ok_or(Error::new(EBADF))?;
|
2016-09-20 16:47:16 +02:00
|
|
|
inner.clone()
|
|
|
|
};
|
|
|
|
|
|
|
|
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
|
2016-09-20 17:21:54 +02:00
|
|
|
handles.insert(id, inner);
|
2016-09-20 16:47:16 +02:00
|
|
|
|
|
|
|
Ok(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read(&self, file: usize, buf: &mut [u8]) -> Result<usize> {
|
|
|
|
let inner = {
|
|
|
|
let handles = self.handles.read();
|
2016-09-21 00:23:28 +02:00
|
|
|
let inner = handles.get(&file).ok_or(Error::new(EBADF))?;
|
2016-09-20 16:47:16 +02:00
|
|
|
inner.clone()
|
|
|
|
};
|
|
|
|
|
|
|
|
inner.read(buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write(&self, file: usize, buf: &[u8]) -> Result<usize> {
|
|
|
|
let inner = {
|
|
|
|
let handles = self.handles.read();
|
2016-09-21 00:23:28 +02:00
|
|
|
let inner = handles.get(&file).ok_or(Error::new(EBADF))?;
|
2016-09-20 16:47:16 +02:00
|
|
|
inner.clone()
|
|
|
|
};
|
|
|
|
|
|
|
|
inner.write(buf)
|
|
|
|
}
|
|
|
|
|
2016-10-26 21:19:56 +02:00
|
|
|
fn fevent(&self, file: usize, flags: usize) -> Result<usize> {
|
|
|
|
let inner = {
|
|
|
|
let handles = self.handles.read();
|
|
|
|
let inner = handles.get(&file).ok_or(Error::new(EBADF))?;
|
|
|
|
inner.clone()
|
|
|
|
};
|
|
|
|
|
|
|
|
inner.fevent(flags)
|
Orbital (#16)
* Port previous ethernet scheme
* Add ipd
* Fix initfs rebuilds, use QEMU user networking addresses in ipd
* Add tcp/udp, netutils, dns, and network config
* Add fsync to network driver
* Add dns, router, subnet by default
* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks
* Add orbital server, WIP
* Add futex
* Add orbutils and orbital
* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad
* Add orbital assets
* Update orbital
* Update to add login manager
* Add blocking primitives, block for most things except waitpid, update orbital
* Wait in waitpid and IRQ, improvements for other waits
* Fevent in root scheme
* WIP: Switch to using fevent
* Reorganize
* Event based e1000d driver
* Superuser-only access to some network schemes, display, and disk
* Superuser root and irq schemes
* Fix orbital
2016-10-14 01:21:42 +02:00
|
|
|
}
|
|
|
|
|
2016-10-26 21:19:56 +02:00
|
|
|
fn fsync(&self, file: usize) -> Result<usize> {
|
|
|
|
let inner = {
|
|
|
|
let handles = self.handles.read();
|
|
|
|
let inner = handles.get(&file).ok_or(Error::new(EBADF))?;
|
|
|
|
inner.clone()
|
|
|
|
};
|
|
|
|
|
|
|
|
inner.fsync()
|
2016-09-20 16:47:16 +02:00
|
|
|
}
|
|
|
|
|
2016-09-21 00:23:28 +02:00
|
|
|
fn close(&self, file: usize) -> Result<usize> {
|
|
|
|
self.handles.write().remove(&file).ok_or(Error::new(EBADF)).and(Ok(0))
|
2016-09-20 16:47:16 +02:00
|
|
|
}
|
|
|
|
}
|