Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
redox-os
kernel
Commits
d331f72f
Verified
Commit
d331f72f
authored
Feb 14, 2021
by
Jeremy Soller
Browse files
Use UTF-8 for all paths
parent
8fcd375b
Changes
28
Hide whitespace changes
Inline
Side-by-side
Cargo.lock
View file @
d331f72f
...
...
@@ -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.6
6
"
version = "1.0.6
7
"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.
1.1
0"
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
.5
4
"
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.6
6
(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.6
7
(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.1
3
(registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1
4
(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.1
3
"
version = "0.4.1
4
"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.
1.1
0 (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.6
6
(registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.6
7
(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.6
6
(registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.6
7
(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.6
6
(registry+https://github.com/rust-lang/crates.io-index)" = "
4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48
"
"checksum cfg-if 0.
1.1
0 (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.6
7
(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.1
3
(registry+https://github.com/rust-lang/crates.io-index)" = "
fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2
"
"checksum log 0.4.1
4
(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"
...
...
Cargo.toml
View file @
d331f72f
[package]
name
=
"kernel"
version
=
"0.
1
.5
4
"
version
=
"0.
2
.5"
build
=
"build.rs"
edition
=
"2018"
...
...
rmm
@
7fd12184
Compare
132d91d3
...
7fd12184
Subproject commit
132d91d3aaa624d1bc8709555a64ff289f7d5e4f
Subproject commit
7fd1218465b58bd88ecdaeaf63683019ad74ed41
src/context/context.rs
View file @
d331f72f
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
...
...
src/lib.rs
View file @
d331f72f
...
...
@@ -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'
)
{
...
...
src/scheme/acpi.rs
View file @
d331f72f
...
...
@@ -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.
...
...
src/scheme/debug.rs
View file @
d331f72f
...
...
@@ -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
));
}
...
...
src/scheme/event.rs
View file @
d331f72f
...
...
@@ -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
)));
...
...
src/scheme/initfs.rs
View file @
d331f72f
...
...
@@ -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
()
{
...
...
src/scheme/irq.rs
View file @
d331f72f
...
...
@@ -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
))
}
...
...
src/scheme/itimer.rs
View file @
d331f72f
...
...
@@ -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
=>
(),
...
...
src/scheme/live.rs
View file @
d331f72f
...
...
@@ -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"
,
...
...
src/scheme/memory.rs
View file @
d331f72f
...
...
@@ -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
)
}
...
...
src/scheme/mod.rs
View file @
d331f72f
...
...
@@ -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_s
lice
(),
id
)
.is_none
());
assert!
(
names
.insert
(
name
.to_
string
()
.into_boxed_s
tr
(),
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
));
...
...
src/scheme/proc.rs
View file @
d331f72f
...
...
@@ -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
();
...
...
src/scheme/root.rs
View file @
d331f72f
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_s
lice
();
let
path_box
=
path
.to_string
()
.into_boxed_s
tr
();
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
&g