Verified Commit d331f72f authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Use UTF-8 for all paths

parent 8fcd375b
......@@ -17,17 +17,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.4.2"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
version = "1.0.66"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.10"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
......@@ -35,7 +35,7 @@ name = "fdt"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/thomhuds/fdt.git#baca9b0070c281dc99521ee901efcb10e5f84218"
dependencies = [
"byteorder 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -49,19 +49,19 @@ dependencies = [
[[package]]
name = "kernel"
version = "0.1.54"
version = "0.2.5"
dependencies = [
"bitfield 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)",
"fdt 0.1.0 (git+https://gitlab.redox-os.org/thomhuds/fdt.git)",
"goblin 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"linked_list_allocator 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-cpuid 8.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.2.4",
"redox_syscall 0.2.7",
"rmm 0.1.0",
"rustc-cfg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -96,10 +96,10 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.13"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -135,7 +135,7 @@ version = "7.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -145,13 +145,13 @@ version = "8.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.2.4"
version = "0.2.7"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -241,15 +241,15 @@ dependencies = [
"checksum bit_field 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
"checksum bitfield 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum byteorder 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
"checksum cc 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum byteorder 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
"checksum cc 1.0.67 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
"checksum cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
"checksum fdt 0.1.0 (git+https://gitlab.redox-os.org/thomhuds/fdt.git)" = "<none>"
"checksum goblin 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d20fd25aa456527ce4f544271ae4fea65d2eda4a6561ea56f39fb3ee4f7e3884"
"checksum linked_list_allocator 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "47de1a43fad0250ee197e9e124e5b5deab3d7b39d4428ae8a6d741ceb340c362"
"checksum linked_list_allocator 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "822add9edb1860698b79522510da17bef885171f75aa395cff099d770c609c24"
"checksum lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
"checksum log 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2"
"checksum log 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
"checksum paste 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
"checksum paste-impl 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
......
[package]
name = "kernel"
version = "0.1.54"
version = "0.2.5"
build = "build.rs"
edition = "2018"
......
Subproject commit 132d91d3aaa624d1bc8709555a64ff289f7d5e4f
Subproject commit 7fd1218465b58bd88ecdaeaf63683019ad74ed41
use alloc::{
boxed::Box,
collections::VecDeque,
string::String,
string::{String, ToString},
sync::Arc,
vec::Vec,
};
......@@ -237,7 +237,7 @@ pub struct Context {
/// The name of the context
pub name: Arc<RwLock<Box<str>>>,
/// The current working directory
pub cwd: Arc<RwLock<Vec<u8>>>,
pub cwd: Arc<RwLock<String>>,
/// The open files in the scheme
pub files: Arc<RwLock<Vec<Option<FileDescriptor>>>>,
/// Signal actions
......@@ -293,7 +293,7 @@ impl Context {
tls: None,
grants: Arc::new(RwLock::new(UserGrants::default())),
name: Arc::new(RwLock::new(String::new().into_boxed_str())),
cwd: Arc::new(RwLock::new(Vec::new())),
cwd: Arc::new(RwLock::new(String::new())),
files: Arc::new(RwLock::new(Vec::new())),
actions: Arc::new(RwLock::new(vec![(
SigAction {
......@@ -313,35 +313,34 @@ impl Context {
/// This function will turn "foo" into "scheme:/path/foo"
/// "/foo" will turn into "scheme:/foo"
/// "bar:/foo" will be used directly, as it is already absolute
pub fn canonicalize(&self, path: &[u8]) -> Vec<u8> {
let mut canon = if path.iter().position(|&b| b == b':').is_none() {
pub fn canonicalize(&self, path: &str) -> String {
let mut canon = if path.find(':').is_none() {
let cwd = self.cwd.read();
let mut canon = if !path.starts_with(b"/") {
let mut canon = if !path.starts_with('/') {
let mut c = cwd.clone();
if ! c.ends_with(b"/") {
c.push(b'/');
if ! c.ends_with('/') {
c.push('/');
}
c
} else {
cwd[..cwd.iter().position(|&b| b == b':').map_or(1, |i| i + 1)].to_vec()
cwd[..cwd.find(':').map_or(1, |i| i + 1)].to_string()
};
canon.extend_from_slice(&path);
canon.push_str(&path);
canon
} else {
path.to_vec()
path.to_string()
};
// NOTE: assumes the scheme does not include anything like "../" or "./"
let mut result = {
let parts = canon.split(|&c| c == b'/')
.filter(|&part| part != b".")
let parts = canon.split('/')
.rev()
.scan(0, |nskip, part| {
if part == b"." {
if part == "." {
Some(None)
} else if part == b".." {
} else if part == ".." {
*nskip += 1;
Some(None)
} else if *nskip > 0 {
......@@ -357,18 +356,17 @@ impl Context {
parts
.iter()
.rev()
.fold(Vec::new(), |mut vec, &part| {
vec.extend_from_slice(part);
vec.push(b'/');
vec
.fold(String::new(), |mut string, &part| {
string.push_str(part);
string.push('/');
string
})
};
result.pop(); // remove extra '/'
// replace with the root of the scheme if it's empty
if result.is_empty() {
let pos = canon.iter()
.position(|&b| b == b':')
let pos = canon.find(':')
.map_or(canon.len(), |p| p + 1);
canon.truncate(pos);
canon
......
......@@ -168,24 +168,24 @@ static mut INIT_ENV: &[u8] = &[];
/// Initialize userspace by running the initfs:bin/init process
/// This function will also set the CWD to initfs:bin and open debug: as stdio
pub extern fn userspace_init() {
let path = b"initfs:/bin/init";
let path = "initfs:/bin/init";
let env = unsafe { INIT_ENV };
if let Err(err) = syscall::chdir(b"initfs:") {
if let Err(err) = syscall::chdir("initfs:") {
info!("Failed to enter initfs ({}).", err);
info!("Perhaps the kernel was compiled with an incorrect INITFS_FOLDER \
environment variable value?");
panic!("Unexpected error while trying to enter initfs:.");
}
assert_eq!(syscall::open(b"debug:", syscall::flag::O_RDONLY).map(FileHandle::into), Ok(0));
assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(1));
assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(2));
assert_eq!(syscall::open("debug:", syscall::flag::O_RDONLY).map(FileHandle::into), Ok(0));
assert_eq!(syscall::open("debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(1));
assert_eq!(syscall::open("debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(2));
let fd = syscall::open(path, syscall::flag::O_RDONLY).expect("failed to open init");
let mut args = Vec::new();
args.push(path.to_vec().into_boxed_slice());
args.push(path.as_bytes().to_vec().into_boxed_slice());
let mut vars = Vec::new();
for var in env.split(|b| *b == b'\n') {
......
......@@ -217,13 +217,12 @@ fn serialize_table_filename(
}
impl Scheme for AcpiScheme {
fn open(&self, path: &[u8], flags: usize, opener_uid: u32, _opener_gid: u32) -> Result<usize> {
fn open(&self, path: &str, flags: usize, opener_uid: u32, _opener_gid: u32) -> Result<usize> {
if opener_uid != 0 {
return Err(Error::new(EACCES));
}
let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;
let path_str = path_str.trim_start_matches('/');
let path_str = path.trim_start_matches('/');
// TODO: Use some kind of component iterator.
......
......@@ -57,7 +57,7 @@ impl DebugScheme {
}
impl Scheme for DebugScheme {
fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<usize> {
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid != 0 {
return Err(Error::new(EPERM));
}
......
......@@ -9,7 +9,7 @@ use crate::syscall::scheme::Scheme;
pub struct EventScheme;
impl Scheme for EventScheme {
fn open(&self, _path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
fn open(&self, _path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
let id = next_queue_id();
queues_mut().insert(id, Arc::new(EventQueue::new(id)));
......
......@@ -41,9 +41,8 @@ impl InitFsScheme {
}
impl Scheme for InitFsScheme {
fn open(&self, path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
let path_utf8 = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;
let path_trimmed = path_utf8.trim_matches('/');
fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
let path_trimmed = path.trim_matches('/');
//Have to iterate to get the path without allocation
for entry in self.files.iter() {
......
......@@ -139,11 +139,10 @@ const fn vector_to_irq(vector: u8) -> u8 {
}
impl Scheme for IrqScheme {
fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<usize> {
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid != 0 { return Err(Error::new(EACCES)) }
let path_str = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;
let path_str = path_str.trim_start_matches('/');
let path_str = path.trim_start_matches('/');
let handle: Handle = if path_str.is_empty() {
if flags & O_DIRECTORY == 0 && flags & O_STAT == 0 { return Err(Error::new(EISDIR)) }
......
......@@ -23,10 +23,8 @@ impl ITimerScheme {
}
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)))?;
fn open(&self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
let clock = path.parse::<usize>().or(Err(Error::new(ENOENT)))?;
match clock {
CLOCK_REALTIME => (),
......
......@@ -52,7 +52,7 @@ impl DiskScheme {
}
impl Scheme for DiskScheme {
fn open(&self, _path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
fn open(&self, _path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.write().insert(id, Handle {
path: b"0",
......
......@@ -15,7 +15,7 @@ impl MemoryScheme {
}
}
impl Scheme for MemoryScheme {
fn open(&self, _path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
fn open(&self, _path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
Ok(0)
}
......
......@@ -6,10 +6,13 @@
//! The kernel validates paths and file descriptors before they are passed to schemes,
//! also stripping the scheme identifier of paths if necessary.
use alloc::sync::Arc;
use alloc::boxed::Box;
use alloc::collections::BTreeMap;
use alloc::vec::Vec;
use alloc::{
boxed::Box,
collections::BTreeMap,
string::ToString,
sync::Arc,
vec::Vec,
};
use core::sync::atomic::AtomicUsize;
use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard};
......@@ -92,11 +95,11 @@ int_like!(SchemeId, AtomicSchemeId, usize, AtomicUsize);
int_like!(FileHandle, AtomicFileHandle, usize, AtomicUsize);
pub struct SchemeIter<'a> {
inner: Option<::alloc::collections::btree_map::Iter<'a, Box<[u8]>, SchemeId>>
inner: Option<::alloc::collections::btree_map::Iter<'a, Box<str>, SchemeId>>
}
impl<'a> Iterator for SchemeIter<'a> {
type Item = (&'a Box<[u8]>, &'a SchemeId);
type Item = (&'a Box<str>, &'a SchemeId);
fn next(&mut self) -> Option<Self::Item> {
self.inner.as_mut().and_then(|iter| iter.next())
......@@ -106,7 +109,7 @@ impl<'a> Iterator for SchemeIter<'a> {
/// Scheme list type
pub struct SchemeList {
map: BTreeMap<SchemeId, Arc<dyn Scheme + Send + Sync>>,
names: BTreeMap<SchemeNamespace, BTreeMap<Box<[u8]>, SchemeId>>,
names: BTreeMap<SchemeNamespace, BTreeMap<Box<str>, SchemeId>>,
next_ns: usize,
next_id: usize
}
......@@ -133,7 +136,7 @@ impl SchemeList {
//TODO: Only memory: is in the null namespace right now. It should be removed when
//anonymous mmap's are implemented
self.insert(ns, Box::new(*b"memory"), |_| Arc::new(MemoryScheme::new())).unwrap();
self.insert(ns, "memory", |_| Arc::new(MemoryScheme::new())).unwrap();
}
/// Initialize a new namespace
......@@ -142,12 +145,12 @@ impl SchemeList {
self.next_ns += 1;
self.names.insert(ns, BTreeMap::new());
self.insert(ns, Box::new(*b""), |scheme_id| Arc::new(RootScheme::new(ns, scheme_id))).unwrap();
self.insert(ns, Box::new(*b"event"), |_| Arc::new(EventScheme)).unwrap();
self.insert(ns, Box::new(*b"itimer"), |_| Arc::new(ITimerScheme::new())).unwrap();
self.insert(ns, Box::new(*b"memory"), |_| Arc::new(MemoryScheme::new())).unwrap();
self.insert(ns, Box::new(*b"sys"), |_| Arc::new(SysScheme::new())).unwrap();
self.insert(ns, Box::new(*b"time"), |scheme_id| Arc::new(TimeScheme::new(scheme_id))).unwrap();
self.insert(ns, "", |scheme_id| Arc::new(RootScheme::new(ns, scheme_id))).unwrap();
self.insert(ns, "event", |_| Arc::new(EventScheme)).unwrap();
self.insert(ns, "itimer", |_| Arc::new(ITimerScheme::new())).unwrap();
self.insert(ns, "memory", |_| Arc::new(MemoryScheme::new())).unwrap();
self.insert(ns, "sys", |_| Arc::new(SysScheme::new())).unwrap();
self.insert(ns, "time", |scheme_id| Arc::new(TimeScheme::new(scheme_id))).unwrap();
ns
}
......@@ -159,23 +162,23 @@ impl SchemeList {
// These schemes should only be available on the root
#[cfg(feature = "acpi")] {
self.insert(ns, Box::new(*b"acpi"), |_| Arc::new(AcpiScheme::new())).unwrap();
self.insert(ns, "acpi", |_| Arc::new(AcpiScheme::new())).unwrap();
}
self.insert(ns, Box::new(*b"debug"), |scheme_id| Arc::new(DebugScheme::new(scheme_id))).unwrap();
self.insert(ns, Box::new(*b"initfs"), |_| Arc::new(InitFsScheme::new())).unwrap();
self.insert(ns, Box::new(*b"irq"), |scheme_id| Arc::new(IrqScheme::new(scheme_id))).unwrap();
self.insert(ns, Box::new(*b"proc"), |scheme_id| Arc::new(ProcScheme::new(scheme_id))).unwrap();
self.insert(ns, Box::new(*b"serio"), |scheme_id| Arc::new(SerioScheme::new(scheme_id))).unwrap();
self.insert(ns, "debug", |scheme_id| Arc::new(DebugScheme::new(scheme_id))).unwrap();
self.insert(ns, "initfs", |_| Arc::new(InitFsScheme::new())).unwrap();
self.insert(ns, "irq", |scheme_id| Arc::new(IrqScheme::new(scheme_id))).unwrap();
self.insert(ns, "proc", |scheme_id| Arc::new(ProcScheme::new(scheme_id))).unwrap();
self.insert(ns, "serio", |scheme_id| Arc::new(SerioScheme::new(scheme_id))).unwrap();
#[cfg(feature = "live")] {
self.insert(ns, Box::new(*b"disk/live"), |_| Arc::new(self::live::DiskScheme::new())).unwrap();
self.insert(ns, "disk/live", |_| Arc::new(self::live::DiskScheme::new())).unwrap();
}
// Pipe is special and needs to be in the root namespace
self.insert(ns, Box::new(*b"pipe"), |scheme_id| Arc::new(PipeScheme::new(scheme_id))).unwrap();
self.insert(ns, "pipe", |scheme_id| Arc::new(PipeScheme::new(scheme_id))).unwrap();
}
pub fn make_ns(&mut self, from: SchemeNamespace, names: &[&[u8]]) -> Result<SchemeNamespace> {
pub fn make_ns(&mut self, from: SchemeNamespace, names: &[&str]) -> Result<SchemeNamespace> {
// Create an empty namespace
let to = self.new_ns();
......@@ -188,7 +191,7 @@ impl SchemeList {
};
if let Some(ref mut names) = self.names.get_mut(&to) {
assert!(names.insert(name.to_vec().into_boxed_slice(), id).is_none());
assert!(names.insert(name.to_string().into_boxed_str(), id).is_none());
} else {
panic!("scheme namespace not found");
}
......@@ -212,7 +215,7 @@ impl SchemeList {
self.map.get(&id)
}
pub fn get_name(&self, ns: SchemeNamespace, name: &[u8]) -> Option<(SchemeId, &Arc<dyn Scheme + Send + Sync>)> {
pub fn get_name(&self, ns: SchemeNamespace, name: &str) -> Option<(SchemeId, &Arc<dyn Scheme + Send + Sync>)> {
if let Some(names) = self.names.get(&ns) {
if let Some(&id) = names.get(name) {
return self.get(id).map(|scheme| (id, scheme));
......@@ -222,11 +225,11 @@ impl SchemeList {
}
/// Create a new scheme.
pub fn insert<F>(&mut self, ns: SchemeNamespace, name: Box<[u8]>, scheme_fn: F) -> Result<SchemeId>
pub fn insert<F>(&mut self, ns: SchemeNamespace, name: &str, scheme_fn: F) -> Result<SchemeId>
where F: Fn(SchemeId) -> Arc<dyn Scheme + Send + Sync>
{
if let Some(names) = self.names.get(&ns) {
if names.contains_key(&name) {
if names.contains_key(name) {
return Err(Error::new(EEXIST));
}
}
......@@ -252,7 +255,7 @@ impl SchemeList {
assert!(self.map.insert(id, scheme).is_none());
if let Some(ref mut names) = self.names.get_mut(&ns) {
assert!(names.insert(name, id).is_none());
assert!(names.insert(name.to_string().into_boxed_str(), id).is_none());
} else {
// Nonexistent namespace, posssibly null namespace
return Err(Error::new(ENODEV));
......
......@@ -24,6 +24,7 @@ use core::{
cmp,
mem,
slice,
str,
sync::atomic::{AtomicUsize, Ordering},
};
use spin::RwLock;
......@@ -208,8 +209,7 @@ impl ProcScheme {
}
impl Scheme for ProcScheme {
fn open(&self, path: &[u8], flags: usize, uid: u32, gid: u32) -> Result<usize> {
let path = core::str::from_utf8(path).map_err(|_| Error::new(EINVAL))?;
fn open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
let mut parts = path.splitn(2, '/');
let pid = parts.next()
.and_then(|s| s.parse().ok())
......@@ -310,8 +310,10 @@ impl Scheme for ProcScheme {
handle.info
};
let mut path = format!("{}/", info.pid.into()).into_bytes();
path.extend_from_slice(buf);
let buf_str = str::from_utf8(buf).map_err(|_| Error::new(EINVAL))?;
let mut path = format!("{}/", info.pid.into());
path.push_str(buf_str);
let (uid, gid) = {
let contexts = context::contexts();
......
use alloc::sync::Arc;
use alloc::boxed::Box;
use alloc::collections::BTreeMap;
use alloc::vec::Vec;
use alloc::{
boxed::Box,
collections::BTreeMap,
string::ToString,
sync::Arc,
vec::Vec,
};
use core::str;
use core::sync::atomic::{AtomicUsize, Ordering};
use spin::{Mutex, RwLock};
......@@ -67,9 +70,8 @@ impl RootScheme {
}
impl Scheme for RootScheme {
fn open(&self, path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result<usize> {
let path_utf8 = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;
let path_trimmed = path_utf8.trim_matches('/');
fn open(&self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
let path = path.trim_matches('/');
//TODO: Make this follow standards for flags and errors
if flags & O_CREAT == O_CREAT {
......@@ -83,10 +85,10 @@ impl Scheme for RootScheme {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let inner = {
let path_box = path_trimmed.as_bytes().to_vec().into_boxed_slice();
let path_box = path.to_string().into_boxed_str();
let mut schemes = scheme::schemes_mut();
let inner = Arc::new(UserInner::new(self.scheme_id, id, path_box.clone(), flags, context));
schemes.insert(self.scheme_ns, path_box, |scheme_id| {
let inner = Arc::new(UserInner::new(self.scheme_id, id, path_box, flags, context));
schemes.insert(self.scheme_ns, path, |scheme_id| {
inner.scheme_id.store(scheme_id, Ordering::SeqCst);
Arc::new(UserScheme::new(Arc::downgrade(&inner)))
})?;
......@@ -99,7 +101,7 @@ impl Scheme for RootScheme {
} else {
Err(Error::new(EACCES))
}
} else if path_trimmed.is_empty() {
} else if path.is_empty() {
let scheme_ns = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
......@@ -111,7 +113,7 @@ impl Scheme for RootScheme {
{
let schemes = scheme::schemes();
for (name, _scheme_id) in schemes.iter_name(scheme_ns) {
data.extend_from_slice(name);
data.extend_from_slice(name.as_bytes());
data.push(b'\n');
}
}
......@@ -126,7 +128,7 @@ impl Scheme for RootScheme {
Ok(id)
} else {
let inner = Arc::new(
path_trimmed.as_bytes().to_vec().into_boxed_slice()
path.as_bytes().to_vec().into_boxed_slice()
);
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
......@@ -135,9 +137,8 @@ impl Scheme for RootScheme {
}
}
fn unlink(&self, path: &[u8], uid: u32, _gid: u32) -> Result<usize> {
let path_utf8 = str::from_utf8(path).or(Err(Error::new(ENOENT)))?;
let path_trimmed = path_utf8.trim_matches('/');
fn unlink(&self, path: &str, uid: u32, _gid: u32) -> Result<usize> {