2016-08-15 05:38:32 +02:00
|
|
|
//! # Schemes
|
|
|
|
//! A scheme is a primitive for handling filesystem syscalls in Redox.
|
|
|
|
//! Schemes accept paths from the kernel for `open`, and file descriptors that they generate
|
|
|
|
//! are then passed for operations like `close`, `read`, `write`, etc.
|
|
|
|
//!
|
|
|
|
//! The kernel validates paths and file descriptors before they are passed to schemes,
|
|
|
|
//! also stripping the scheme identifier of paths if necessary.
|
|
|
|
|
2016-08-16 19:04:14 +02:00
|
|
|
use alloc::arc::Arc;
|
|
|
|
use alloc::boxed::Box;
|
|
|
|
|
|
|
|
use collections::BTreeMap;
|
|
|
|
|
2016-08-18 16:10:08 +02:00
|
|
|
use spin::{Once, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
2016-08-16 19:04:14 +02:00
|
|
|
|
2016-08-15 05:38:32 +02:00
|
|
|
use syscall::Result;
|
|
|
|
|
|
|
|
use self::debug::DebugScheme;
|
|
|
|
|
2016-08-29 11:58:31 +02:00
|
|
|
pub use self::fd::Fd;
|
|
|
|
|
2016-08-15 05:38:32 +02:00
|
|
|
/// Debug scheme
|
|
|
|
pub mod debug;
|
2016-08-29 11:58:31 +02:00
|
|
|
mod fd;
|
2016-08-15 05:38:32 +02:00
|
|
|
|
2016-08-18 16:30:45 +02:00
|
|
|
/// Scheme list type
|
2016-08-18 16:10:08 +02:00
|
|
|
pub type SchemeList = BTreeMap<Box<[u8]>, Arc<Mutex<Box<Scheme + Send>>>>;
|
|
|
|
|
2016-08-15 05:38:32 +02:00
|
|
|
/// Schemes list
|
2016-08-18 16:10:08 +02:00
|
|
|
static SCHEMES: Once<RwLock<SchemeList>> = Once::new();
|
|
|
|
|
2016-08-18 16:30:45 +02:00
|
|
|
/// Initialize schemes, called if needed
|
2016-08-18 16:10:08 +02:00
|
|
|
fn init_schemes() -> RwLock<SchemeList> {
|
|
|
|
let mut map: SchemeList = BTreeMap::new();
|
|
|
|
map.insert(Box::new(*b"debug"), Arc::new(Mutex::new(Box::new(DebugScheme))));
|
|
|
|
RwLock::new(map)
|
|
|
|
}
|
|
|
|
|
2016-08-18 16:30:45 +02:00
|
|
|
/// Get the global schemes list, const
|
2016-08-18 16:10:08 +02:00
|
|
|
pub fn schemes() -> RwLockReadGuard<'static, SchemeList> {
|
|
|
|
SCHEMES.call_once(init_schemes).read()
|
|
|
|
}
|
|
|
|
|
2016-08-18 16:30:45 +02:00
|
|
|
/// Get the global schemes list, mutable
|
2016-08-18 16:10:08 +02:00
|
|
|
pub fn schemes_mut() -> RwLockWriteGuard<'static, SchemeList> {
|
|
|
|
SCHEMES.call_once(init_schemes).write()
|
2016-08-16 19:04:14 +02:00
|
|
|
}
|
2016-08-15 05:38:32 +02:00
|
|
|
|
|
|
|
/// A scheme trait, implemented by a scheme handler
|
2016-08-14 02:21:46 +02:00
|
|
|
pub trait Scheme {
|
|
|
|
/// Open the file at `path` with `flags`.
|
2016-08-14 18:40:34 +02:00
|
|
|
///
|
2016-08-14 02:21:46 +02:00
|
|
|
/// Returns a file descriptor or an error
|
2016-08-15 05:38:32 +02:00
|
|
|
fn open(&mut self, path: &[u8], flags: usize) -> Result<usize>;
|
|
|
|
|
2016-08-29 11:58:31 +02:00
|
|
|
/// Read from some file descriptor into the `buffer`
|
2016-08-15 05:38:32 +02:00
|
|
|
///
|
|
|
|
/// Returns the number of bytes read
|
2016-08-29 11:58:31 +02:00
|
|
|
fn read(&mut self, fd: Fd, buffer: &mut [u8]) -> Result<usize>;
|
2016-08-15 05:38:32 +02:00
|
|
|
|
2016-08-29 11:58:31 +02:00
|
|
|
/// Write the `buffer` to the file descriptor
|
2016-08-15 05:38:32 +02:00
|
|
|
///
|
|
|
|
/// Returns the number of bytes written
|
2016-08-29 11:58:31 +02:00
|
|
|
fn write(&mut self, fd: Fd, buffer: &[u8]) -> Result<usize>;
|
2016-08-15 05:38:32 +02:00
|
|
|
|
2016-08-29 11:58:31 +02:00
|
|
|
/// Close the file descriptor
|
|
|
|
fn close(&mut self, fd: Fd) -> Result<()>;
|
2016-08-14 02:21:46 +02:00
|
|
|
}
|