Merge branch 'scheme_utils' into 'main'

Introduce scheme-utils crate and HandleMap type

See merge request redox-os/base!223
This commit is contained in:
Jeremy Soller
2026-04-13 14:49:06 -06:00
38 changed files with 381 additions and 570 deletions
Generated
+24
View File
@@ -14,6 +14,7 @@ dependencies = [
"redox-scheme",
"redox_event",
"redox_syscall 0.7.3",
"scheme-utils",
"spin",
]
@@ -50,6 +51,7 @@ dependencies = [
"redox_syscall 0.7.3",
"ron",
"rustc-hash",
"scheme-utils",
"serde",
"thiserror 2.0.18",
]
@@ -180,6 +182,7 @@ dependencies = [
"libredox",
"redox-scheme",
"redox_syscall 0.7.3",
"scheme-utils",
]
[[package]]
@@ -562,6 +565,7 @@ dependencies = [
"partitionlib",
"redox-scheme",
"redox_syscall 0.7.3",
"scheme-utils",
]
[[package]]
@@ -578,6 +582,7 @@ dependencies = [
"redox-ioctl",
"redox-scheme",
"redox_syscall 0.7.3",
"scheme-utils",
]
[[package]]
@@ -588,6 +593,7 @@ dependencies = [
"libredox",
"redox-scheme",
"redox_syscall 0.7.3",
"scheme-utils",
]
[[package]]
@@ -743,6 +749,7 @@ dependencies = [
"redox-scheme",
"redox_event",
"redox_syscall 0.7.3",
"scheme-utils",
]
[[package]]
@@ -1047,6 +1054,7 @@ dependencies = [
"redox-scheme",
"redox_event",
"redox_syscall 0.7.3",
"scheme-utils",
"spin",
]
@@ -1110,6 +1118,7 @@ dependencies = [
"orbclient",
"redox-scheme",
"redox_syscall 0.7.3",
"scheme-utils",
]
[[package]]
@@ -1134,6 +1143,7 @@ dependencies = [
"redox-scheme",
"redox_event",
"redox_syscall 0.7.3",
"scheme-utils",
]
[[package]]
@@ -1250,6 +1260,7 @@ dependencies = [
"libredox",
"redox-scheme",
"redox_syscall 0.7.3",
"scheme-utils",
]
[[package]]
@@ -1473,6 +1484,7 @@ dependencies = [
"plain",
"redox-scheme",
"redox_syscall 0.7.3",
"scheme-utils",
"serde",
]
@@ -1618,6 +1630,7 @@ dependencies = [
"libredox",
"redox-scheme",
"redox_syscall 0.7.3",
"scheme-utils",
"slab",
]
@@ -1706,6 +1719,7 @@ dependencies = [
"raw-cpuid",
"redox-scheme",
"redox_syscall 0.7.3",
"scheme-utils",
"sha2",
]
@@ -1815,6 +1829,7 @@ dependencies = [
"redox-scheme",
"redox_event",
"redox_syscall 0.7.3",
"scheme-utils",
"smoltcp",
]
@@ -1982,9 +1997,18 @@ dependencies = [
"redox-scheme",
"redox_event",
"redox_syscall 0.7.3",
"scheme-utils",
"spin",
]
[[package]]
name = "scheme-utils"
version = "0.0.0"
dependencies = [
"libredox",
"redox_syscall 0.7.3",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
+1
View File
@@ -14,6 +14,7 @@ members = [
"ptyd",
"ramfs",
"randd",
"scheme-utils",
"zerod",
"drivers/common",
+1
View File
@@ -11,6 +11,7 @@ redox_syscall = { workspace = true, features = ["std"] }
libc.workspace = true
libredox = { workspace = true, features = ["mkns"] }
redox-scheme.workspace = true
scheme-utils = { path = "../scheme-utils" }
anyhow.workspace = true
ioslice = "0.6.0"
+9 -18
View File
@@ -1,5 +1,6 @@
use redox_scheme::{CallerCtx, OpenResult};
use std::collections::{BTreeMap, VecDeque};
use scheme_utils::HandleMap;
use std::collections::VecDeque;
use std::str;
use syscall::error::{Error, Result, EACCES, EBADF, EINVAL, ENOENT, EWOULDBLOCK};
@@ -20,16 +21,14 @@ enum Handle {
}
pub struct AudioScheme {
next_id: usize,
handles: BTreeMap<usize, Handle>,
handles: HandleMap<Handle>,
volume: i32,
}
impl AudioScheme {
pub fn new() -> Self {
AudioScheme {
next_id: 0,
handles: BTreeMap::new(),
handles: HandleMap::new(),
volume: 50,
}
}
@@ -66,10 +65,7 @@ impl AudioScheme {
impl SchemeSync for AudioScheme {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.insert(Handle::SchemeRoot))
}
fn openat(
&mut self,
@@ -79,10 +75,7 @@ impl SchemeSync for AudioScheme {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<OpenResult> {
if !matches!(
self.handles.get(&dirfd).ok_or(Error::new(EBADF))?,
Handle::SchemeRoot
) {
if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
@@ -97,9 +90,7 @@ impl SchemeSync for AudioScheme {
_ => return Err(Error::new(ENOENT)),
};
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, handle);
let id = self.handles.insert(handle);
Ok(OpenResult::ThisScheme { number: id, flags })
}
@@ -113,7 +104,7 @@ impl SchemeSync for AudioScheme {
_ctx: &CallerCtx,
) -> Result<usize> {
//TODO: check flags for readable
match self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
match self.handles.get_mut(id)? {
Handle::Audio { buffer: _ } => {
//TODO: audio input?
Err(Error::new(EBADF))
@@ -143,7 +134,7 @@ impl SchemeSync for AudioScheme {
_ctx: &CallerCtx,
) -> Result<usize> {
//TODO: check flags for writable
match self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
match self.handles.get_mut(id)? {
Handle::Audio { ref mut buffer } => {
if buffer.len() >= HANDLE_BUFFER_SIZE {
Err(Error::new(EWOULDBLOCK))
+1
View File
@@ -27,6 +27,7 @@ common = { path = "../common" }
daemon = { path = "../../daemon" }
libredox.workspace = true
redox-scheme.workspace = true
scheme-utils = { path = "../../scheme-utils" }
[lints]
workspace = true
+20 -35
View File
@@ -7,7 +7,7 @@ use parking_lot::RwLockReadGuard;
use redox_scheme::scheme::SchemeSync;
use redox_scheme::{CallerCtx, OpenResult, SendFdRequest, Socket};
use ron::de::SpannedError;
use std::collections::BTreeMap;
use scheme_utils::HandleMap;
use std::convert::{TryFrom, TryInto};
use std::str::FromStr;
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
@@ -25,8 +25,7 @@ use crate::acpi::{AcpiContext, AmlSymbols, SdtSignature};
pub struct AcpiScheme<'acpi, 'sock> {
ctx: &'acpi AcpiContext,
handles: BTreeMap<usize, Handle<'acpi>>,
next_fd: usize,
handles: HandleMap<Handle<'acpi>>,
pci_fd: Option<Fd>,
socket: &'sock Socket,
}
@@ -77,8 +76,7 @@ impl<'acpi, 'sock> AcpiScheme<'acpi, 'sock> {
pub fn new(ctx: &'acpi AcpiContext, socket: &'sock Socket) -> Self {
Self {
ctx,
handles: BTreeMap::new(),
next_fd: 0,
handles: HandleMap::new(),
pci_fd: None,
socket,
}
@@ -161,18 +159,11 @@ fn parse_table(table: &[u8]) -> Option<SdtSignature> {
impl SchemeSync for AcpiScheme<'_, '_> {
fn scheme_root(&mut self) -> Result<usize> {
let fd = self.next_fd;
self.next_fd += 1;
self.handles.insert(
fd,
Handle {
stat: false,
kind: HandleKind::SchemeRoot,
allowed_to_eval: false,
},
);
Ok(fd)
Ok(self.handles.insert(Handle {
stat: false,
kind: HandleKind::SchemeRoot,
allowed_to_eval: false,
}))
}
fn openat(
&mut self,
@@ -182,7 +173,7 @@ impl SchemeSync for AcpiScheme<'_, '_> {
_fcntl_flags: u32,
ctx: &CallerCtx,
) -> Result<OpenResult> {
let handle = self.handles.get(&dirfd).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(dirfd)?;
let path = path.trim_start_matches('/');
@@ -265,17 +256,11 @@ impl SchemeSync for AcpiScheme<'_, '_> {
return Err(Error::new(EINVAL));
}
let fd = self.next_fd;
self.next_fd += 1;
self.handles.insert(
fd,
Handle {
stat: flag_stat,
kind,
allowed_to_eval,
},
);
let fd = self.handles.insert(Handle {
stat: flag_stat,
kind,
allowed_to_eval,
});
Ok(OpenResult::ThisScheme {
number: fd,
@@ -284,7 +269,7 @@ impl SchemeSync for AcpiScheme<'_, '_> {
}
fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(id)?;
stat.st_size = handle
.kind
@@ -311,7 +296,7 @@ impl SchemeSync for AcpiScheme<'_, '_> {
) -> Result<usize> {
let offset: usize = offset.try_into().map_err(|_| Error::new(EINVAL))?;
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get_mut(id)?;
if handle.stat {
return Err(Error::new(EBADF));
@@ -343,7 +328,7 @@ impl SchemeSync for AcpiScheme<'_, '_> {
mut buf: DirentBuf<&'buf mut [u8]>,
opaque_offset: u64,
) -> Result<DirentBuf<&'buf mut [u8]>> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EOPNOTSUPP))?;
let handle = self.handles.get_mut(id)?;
match &handle.kind {
HandleKind::TopLevel => {
@@ -430,7 +415,7 @@ impl SchemeSync for AcpiScheme<'_, '_> {
_metadata: &[u64],
_ctx: &CallerCtx,
) -> Result<usize> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get_mut(id)?;
if !handle.allowed_to_eval {
return Err(Error::new(EPERM));
}
@@ -474,7 +459,7 @@ impl SchemeSync for AcpiScheme<'_, '_> {
let id = sendfd_request.id();
let num_fds = sendfd_request.num_fds();
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(id)?;
if !matches!(handle.kind, HandleKind::RegisterPci) {
return Err(Error::new(EACCES));
}
@@ -506,6 +491,6 @@ impl SchemeSync for AcpiScheme<'_, '_> {
}
fn on_close(&mut self, id: usize) {
self.handles.remove(&id);
self.handles.remove(id);
}
}
+1
View File
@@ -15,6 +15,7 @@ spin.workspace = true
daemon = { path = "../../../daemon" }
pcid = { path = "../../pcid" }
redox-scheme.workspace = true
scheme-utils = { path = "../../../scheme-utils" }
[lints]
workspace = true
+9 -16
View File
@@ -1,12 +1,10 @@
#![allow(dead_code)]
use std::collections::BTreeMap;
use std::sync::atomic::{AtomicUsize, Ordering};
use common::io::Pio;
use redox_scheme::scheme::SchemeSync;
use redox_scheme::CallerCtx;
use redox_scheme::OpenResult;
use scheme_utils::HandleMap;
use syscall::error::{Error, Result, EACCES, EBADF, EINVAL, ENOENT};
use syscall::schemev2::NewFdFlags;
use syscall::EWOULDBLOCK;
@@ -156,8 +154,7 @@ pub struct Ac97 {
bus: BusRegs,
bdl: Dma<[BufferDescriptor; NUM_SUB_BUFFS]>,
buf: Dma<[u8; NUM_SUB_BUFFS * SUB_BUFF_SIZE]>,
handles: Mutex<BTreeMap<usize, Handle>>,
next_id: AtomicUsize,
handles: Mutex<HandleMap<Handle>>,
}
impl Ac97 {
@@ -173,8 +170,7 @@ impl Ac97 {
//TODO: PhysBox::new_in_32bit_space(buf_size)?
)?
.assume_init(),
handles: Mutex::new(BTreeMap::new()),
next_id: AtomicUsize::new(0),
handles: Mutex::new(HandleMap::new()),
};
module.init()?;
@@ -264,9 +260,7 @@ impl Ac97 {
impl SchemeSync for Ac97 {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.lock().insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.lock().insert(Handle::SchemeRoot))
}
fn openat(
&mut self,
@@ -278,14 +272,13 @@ impl SchemeSync for Ac97 {
) -> Result<OpenResult> {
{
let handles = self.handles.lock();
let handle = handles.get(&dirfd).ok_or(Error::new(EBADF))?;
let handle = handles.get(dirfd)?;
if !matches!(handle, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
}
if ctx.uid == 0 {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.lock().insert(id, Handle::Todo);
let id = self.handles.lock().insert(Handle::Todo);
Ok(OpenResult::ThisScheme {
number: id,
flags: NewFdFlags::empty(),
@@ -305,7 +298,7 @@ impl SchemeSync for Ac97 {
) -> Result<usize> {
{
let mut handles = self.handles.lock();
let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = handles.get_mut(id)?;
if !matches!(handle, Handle::Todo) {
return Err(Error::new(EBADF));
}
@@ -335,7 +328,7 @@ impl SchemeSync for Ac97 {
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
{
let mut handles = self.handles.lock();
let handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = handles.get_mut(id)?;
if !matches!(handle, Handle::Todo) {
return Err(Error::new(EBADF));
}
@@ -351,6 +344,6 @@ impl SchemeSync for Ac97 {
}
fn on_close(&mut self, id: usize) {
let _ = self.handles.lock().remove(&id);
self.handles.lock().remove(id);
}
}
+1
View File
@@ -16,6 +16,7 @@ common = { path = "../../common" }
daemon = { path = "../../../daemon" }
pcid = { path = "../../pcid" }
redox-scheme.workspace = true
scheme-utils = { path = "../../../scheme-utils" }
[lints]
workspace = true
+10 -16
View File
@@ -1,10 +1,8 @@
#![allow(dead_code)]
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::fmt::Write;
use std::str;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::Poll;
use std::thread;
use std::time::Duration;
@@ -15,6 +13,7 @@ use common::timeout::Timeout;
use redox_scheme::scheme::SchemeSync;
use redox_scheme::CallerCtx;
use redox_scheme::OpenResult;
use scheme_utils::HandleMap;
use syscall::error::{Error, Result, EACCES, EBADF, EIO, ENODEV, EWOULDBLOCK};
use spin::Mutex;
@@ -150,8 +149,7 @@ pub struct IntelHDA {
buffs: Vec<Vec<StreamBuffer>>,
int_counter: usize,
handles: Mutex<BTreeMap<usize, Handle>>,
next_id: AtomicUsize,
handles: Mutex<HandleMap<Handle>>,
}
impl IntelHDA {
@@ -203,8 +201,7 @@ impl IntelHDA {
buffs: Vec::<Vec<StreamBuffer>>::new(),
int_counter: 0,
handles: Mutex::new(BTreeMap::new()),
next_id: AtomicUsize::new(0),
handles: Mutex::new(HandleMap::new()),
};
module.init()?;
@@ -986,9 +983,7 @@ impl Drop for IntelHDA {
impl SchemeSync for IntelHDA {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.lock().insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.lock().insert(Handle::SchemeRoot))
}
fn openat(
&mut self,
@@ -1000,7 +995,7 @@ impl SchemeSync for IntelHDA {
) -> Result<OpenResult> {
{
let handles = self.handles.lock();
let handle = handles.get(&dirfd).ok_or(Error::new(EBADF))?;
let handle = handles.get(dirfd)?;
if !matches!(handle, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
@@ -1026,8 +1021,7 @@ impl SchemeSync for IntelHDA {
"codec" => Handle::StrBuf(self.dump_codec(0).into_bytes()),
_ => Handle::Todo,
};
let id = self.next_id.fetch_add(1, Ordering::Relaxed);
self.handles.lock().insert(id, handle);
let id = self.handles.lock().insert(handle);
// TODO: always positioned?
Ok(OpenResult::ThisScheme {
@@ -1045,7 +1039,7 @@ impl SchemeSync for IntelHDA {
_ctx: &CallerCtx,
) -> Result<usize> {
let handles = self.handles.lock();
let Some(Handle::StrBuf(strbuf)) = handles.get(&id) else {
let Handle::StrBuf(strbuf) = handles.get(id)? else {
return Err(Error::new(EBADF));
};
@@ -1068,7 +1062,7 @@ impl SchemeSync for IntelHDA {
) -> Result<usize> {
let index = {
let mut handles = self.handles.lock();
match handles.get_mut(&id).ok_or(Error::new(EBADF))? {
match handles.get_mut(id)? {
Handle::Todo => 0,
_ => return Err(Error::new(EBADF)),
}
@@ -1084,7 +1078,7 @@ impl SchemeSync for IntelHDA {
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let mut handles = self.handles.lock();
let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let _handle = handles.get_mut(id)?;
let mut i = 0;
let scheme_path = b"/scheme/audiohw";
@@ -1096,6 +1090,6 @@ impl SchemeSync for IntelHDA {
}
fn on_close(&mut self, id: usize) {
let _ = self.handles.lock().remove(&id);
self.handles.lock().remove(id);
}
}
+1
View File
@@ -14,6 +14,7 @@ redox_event.workspace = true
redox_syscall.workspace = true
spin.workspace = true
redox-scheme.workspace = true
scheme-utils = { path = "../../../scheme-utils" }
[lints]
workspace = true
+8 -14
View File
@@ -1,7 +1,5 @@
#![allow(dead_code)]
use std::collections::BTreeMap;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::{thread, time};
use common::io::{Io, Pio, ReadOnly, WriteOnly};
@@ -9,6 +7,7 @@ use common::io::{Io, Pio, ReadOnly, WriteOnly};
use redox_scheme::scheme::SchemeSync;
use redox_scheme::CallerCtx;
use redox_scheme::OpenResult;
use scheme_utils::HandleMap;
use syscall::error::{Error, Result, EACCES, EBADF, ENODEV};
use syscall::schemev2::NewFdFlags;
@@ -24,8 +23,7 @@ enum Handle {
#[allow(dead_code)]
pub struct Sb16 {
handles: Mutex<BTreeMap<usize, Handle>>,
next_id: AtomicUsize,
handles: Mutex<HandleMap<Handle>>,
pub(crate) irqs: Vec<u8>,
dmas: Vec<u8>,
// Regs
@@ -41,8 +39,7 @@ pub struct Sb16 {
impl Sb16 {
pub unsafe fn new(addr: u16) -> Result<Self> {
let mut module = Sb16 {
handles: Mutex::new(BTreeMap::new()),
next_id: AtomicUsize::new(0),
handles: Mutex::new(HandleMap::new()),
irqs: Vec::new(),
dmas: Vec::new(),
// Regs
@@ -187,9 +184,7 @@ impl Sb16 {
impl SchemeSync for Sb16 {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.lock().insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.lock().insert(Handle::SchemeRoot))
}
fn openat(
&mut self,
@@ -201,14 +196,13 @@ impl SchemeSync for Sb16 {
) -> Result<OpenResult> {
{
let handles = self.handles.lock();
let handle = handles.get(&dirfd).ok_or(Error::new(EBADF))?;
let handle = handles.get(dirfd)?;
if !matches!(handle, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
}
if ctx.uid == 0 {
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.lock().insert(id, Handle::Todo);
let id = self.handles.lock().insert(Handle::Todo);
Ok(OpenResult::ThisScheme {
number: id,
flags: NewFdFlags::empty(),
@@ -232,7 +226,7 @@ impl SchemeSync for Sb16 {
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let mut handles = self.handles.lock();
let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let _handle = handles.get_mut(id)?;
let mut i = 0;
let scheme_path = b"/scheme/audiohw";
@@ -244,6 +238,6 @@ impl SchemeSync for Sb16 {
}
fn on_close(&mut self, id: usize) {
let _ = self.handles.lock().remove(&id);
self.handles.lock().remove(id);
}
}
@@ -11,6 +11,7 @@ edid.workspace = true #TODO: edid is abandoned, fork it and maintain?
log.workspace = true
redox-ioctl.workspace = true
redox-scheme.workspace = true
scheme-utils = { path = "../../../scheme-utils" }
redox_syscall.workspace = true
libredox.workspace = true
+13 -21
View File
@@ -1,6 +1,6 @@
#![feature(macro_metavar_expr)]
use std::collections::{BTreeMap, HashMap};
use std::collections::HashMap;
use std::fmt::Debug;
use std::fs::File;
use std::io::{self, Write};
@@ -18,8 +18,9 @@ use inputd::{DisplayHandle, VtEventKind};
use libredox::Fd;
use redox_scheme::scheme::{register_scheme_inner, SchemeState, SchemeSync};
use redox_scheme::{CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket};
use scheme_utils::HandleMap;
use syscall::schemev2::NewFdFlags;
use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EBADF, EINVAL, ENOENT, EOPNOTSUPP};
use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EINVAL, ENOENT, EOPNOTSUPP};
use crate::kms::connector::{KmsConnectorDriver, KmsConnectorState};
use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects};
@@ -155,8 +156,7 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
disable_graphical_debug,
socket,
objects,
next_id: 0,
handles: BTreeMap::new(),
handles: HandleMap::new(),
active_vt: 0,
vts: HashMap::new(),
};
@@ -264,8 +264,7 @@ struct GraphicsSchemeInner<T: GraphicsAdapter> {
disable_graphical_debug: Option<File>,
socket: Socket,
objects: KmsObjects<T>,
next_id: usize,
handles: BTreeMap<usize, Handle<T>>,
handles: HandleMap<Handle<T>>,
active_vt: usize,
vts: HashMap<usize, VtState<T>>,
@@ -381,10 +380,7 @@ const MAP_FAKE_OFFSET_MULTIPLIER: usize = 0x10_000_000;
impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.insert(Handle::SchemeRoot))
}
fn openat(
&mut self,
@@ -394,10 +390,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<OpenResult> {
if !matches!(
self.handles.get(&dirfd).ok_or(Error::new(EBADF))?,
Handle::SchemeRoot
) {
if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
if path.is_empty() {
@@ -423,16 +416,15 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
} else {
return Err(Error::new(EINVAL));
};
self.next_id += 1;
self.handles.insert(self.next_id, handle);
let id = self.handles.insert(handle);
Ok(OpenResult::ThisScheme {
number: self.next_id,
number: id,
flags: NewFdFlags::empty(),
})
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> syscall::Result<usize> {
let path = match self.handles.get(&id).ok_or(Error::new(EBADF))? {
let path = match self.handles.get(id)? {
Handle::V2 {
vt,
next_id: _,
@@ -461,7 +453,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
id_index(i) | (1 << 13)
}
match self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
match self.handles.get_mut(id)? {
Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)),
Handle::V2 {
vt,
@@ -969,7 +961,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
_ctx: &CallerCtx,
) -> syscall::Result<usize> {
// log::trace!("KSMSG MMAP {} {:?} {} {}", id, _flags, _offset, _size);
let (framebuffer, offset) = match self.handles.get(&id).ok_or(Error::new(EINVAL))? {
let (framebuffer, offset) = match self.handles.get(id)? {
Handle::V2 {
vt: _,
next_id: _,
@@ -990,6 +982,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
fn on_close(&mut self, id: usize) {
self.handles.remove(&id);
self.handles.remove(id);
}
}
+1
View File
@@ -12,6 +12,7 @@ ransid.workspace = true
redox_event.workspace = true
redox_syscall.workspace = true
redox-scheme.workspace = true
scheme-utils = { path = "../../../scheme-utils" }
common = { path = "../../common" }
console-draw = { path = "../console-draw" }
+19 -36
View File
@@ -4,6 +4,7 @@ use std::os::fd::AsRawFd;
use event::{EventQueue, UserData};
use redox_scheme::scheme::SchemeSync;
use redox_scheme::{CallerCtx, OpenResult};
use scheme_utils::HandleMap;
use syscall::schemev2::NewFdFlags;
use syscall::{Error, EventFlags, Result, EACCES, EAGAIN, EBADF, ENOENT, O_NONBLOCK};
@@ -41,8 +42,7 @@ pub enum Handle {
pub struct FbconScheme {
pub vts: BTreeMap<VtIndex, TextScreen>,
next_id: usize,
pub handles: BTreeMap<usize, Handle>,
pub handles: HandleMap<Handle>,
}
impl FbconScheme {
@@ -63,26 +63,21 @@ impl FbconScheme {
FbconScheme {
vts,
next_id: 0,
handles: BTreeMap::new(),
handles: HandleMap::new(),
}
}
fn get_vt_handle_mut(&mut self, id: usize) -> Result<&mut FdHandle> {
match self.handles.get_mut(&id) {
Some(Handle::Vt(handle)) => Ok(handle),
Some(Handle::SchemeRoot) => Err(Error::new(EBADF)),
None => Err(Error::new(EBADF)),
match self.handles.get_mut(id)? {
Handle::Vt(handle) => Ok(handle),
Handle::SchemeRoot => Err(Error::new(EBADF)),
}
}
}
impl SchemeSync for FbconScheme {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.insert(Handle::SchemeRoot))
}
fn openat(
@@ -93,27 +88,18 @@ impl SchemeSync for FbconScheme {
fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<OpenResult> {
if !matches!(
self.handles.get(&dirfd).ok_or(Error::new(EBADF))?,
Handle::SchemeRoot
) {
if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
let vt_i = VtIndex(path_str.parse::<usize>().map_err(|_| Error::new(ENOENT))?);
if self.vts.contains_key(&vt_i) {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(
id,
Handle::Vt(FdHandle {
vt_i,
flags: flags | fcntl_flags as usize,
events: EventFlags::empty(),
notified_read: false,
}),
);
let id = self.handles.insert(Handle::Vt(FdHandle {
vt_i,
flags: flags | fcntl_flags as usize,
events: EventFlags::empty(),
notified_read: false,
}));
Ok(OpenResult::ThisScheme {
number: id,
@@ -159,9 +145,7 @@ impl SchemeSync for FbconScheme {
}
fn fcntl(&mut self, id: usize, _cmd: usize, _arg: usize, _ctx: &CallerCtx) -> Result<usize> {
if !self.handles.get(&id).is_some() {
return Err(Error::new(EBADF));
};
self.handles.get(id)?;
Ok(0)
}
@@ -173,10 +157,9 @@ impl SchemeSync for FbconScheme {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
let handle = match self.handles.get(&id) {
Some(Handle::Vt(handle)) => Ok(handle),
Some(Handle::SchemeRoot) => Err(Error::new(EBADF)),
None => Err(Error::new(EBADF)),
let handle = match self.handles.get(id)? {
Handle::Vt(handle) => Ok(handle),
Handle::SchemeRoot => Err(Error::new(EBADF)),
}?;
if let Some(screen) = self.vts.get_mut(&handle.vt_i) {
@@ -212,6 +195,6 @@ impl SchemeSync for FbconScheme {
}
fn on_close(&mut self, id: usize) {
let _ = self.handles.remove(&id);
self.handles.remove(id);
}
}
+1
View File
@@ -15,6 +15,7 @@ libredox.workspace = true
common = { path = "../common" }
daemon = { path = "../../daemon" }
redox-scheme.workspace = true
scheme-utils = { path = "../../scheme-utils" }
[lints]
workspace = true
+13 -24
View File
@@ -13,7 +13,7 @@
use core::mem::size_of;
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet};
use std::collections::BTreeSet;
use std::mem::transmute;
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -24,6 +24,7 @@ use redox_scheme::scheme::{SchemeState, SchemeSync};
use redox_scheme::{CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket};
use orbclient::{Event, EventOption};
use scheme_utils::HandleMap;
use syscall::schemev2::NewFdFlags;
use syscall::{Error as SysError, EventFlags, EACCES, EBADF, EEXIST, EINVAL};
@@ -57,9 +58,8 @@ enum Handle {
}
struct InputScheme {
handles: BTreeMap<usize, Handle>,
handles: HandleMap<Handle>,
next_id: AtomicUsize,
next_vt_id: AtomicUsize,
display: Option<String>,
@@ -76,9 +76,8 @@ struct InputScheme {
impl InputScheme {
fn new() -> Self {
Self {
handles: BTreeMap::new(),
handles: HandleMap::new(),
next_id: AtomicUsize::new(0),
next_vt_id: AtomicUsize::new(2), // VT 1 is reserved for the bootlog
display: None,
@@ -150,9 +149,7 @@ impl InputScheme {
impl SchemeSync for InputScheme {
fn scheme_root(&mut self) -> syscall::Result<usize> {
let fd = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.insert(fd, Handle::SchemeRoot);
Ok(fd)
Ok(self.handles.insert(Handle::SchemeRoot))
}
fn openat(
@@ -163,10 +160,7 @@ impl SchemeSync for InputScheme {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> syscall::Result<OpenResult> {
if !matches!(
self.handles.get(&dirfd).ok_or(SysError::new(EINVAL))?,
Handle::SchemeRoot
) {
if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) {
return Err(SysError::new(EACCES));
}
@@ -266,8 +260,7 @@ impl SchemeSync for InputScheme {
log::debug!("{path} channel has been opened");
let fd = self.next_id.fetch_add(1, Ordering::SeqCst);
self.handles.insert(fd, handle_ty);
let fd = self.handles.insert(handle_ty);
Ok(OpenResult::ThisScheme {
number: fd,
flags: NewFdFlags::empty(),
@@ -275,7 +268,7 @@ impl SchemeSync for InputScheme {
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> syscall::Result<usize> {
let handle = self.handles.get(&id).ok_or(SysError::new(EINVAL))?;
let handle = self.handles.get(id)?;
if let Handle::Consumer { vt, .. } = handle {
let display = self.display.as_ref().ok_or(SysError::new(EINVAL))?;
@@ -298,7 +291,7 @@ impl SchemeSync for InputScheme {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> syscall::Result<usize> {
let handle = self.handles.get_mut(&id).ok_or(SysError::new(EINVAL))?;
let handle = self.handles.get_mut(id)?;
match handle {
Handle::Consumer {
@@ -360,7 +353,7 @@ impl SchemeSync for InputScheme {
) -> syscall::Result<usize> {
self.has_new_events = true;
let handle = self.handles.get_mut(&id).ok_or(SysError::new(EINVAL))?;
let handle = self.handles.get_mut(id)?;
match handle {
Handle::Control => {
@@ -445,7 +438,7 @@ impl SchemeSync for InputScheme {
}
}
let handle = self.handles.get_mut(&id).ok_or(SysError::new(EINVAL))?;
let handle = self.handles.get_mut(id)?;
assert!(matches!(handle, Handle::Producer));
let buf = unsafe {
@@ -485,9 +478,7 @@ impl SchemeSync for InputScheme {
flags: syscall::EventFlags,
_ctx: &CallerCtx,
) -> syscall::Result<syscall::EventFlags> {
let handle = self.handles.get_mut(&id).ok_or(SysError::new(EINVAL))?;
match handle {
match self.handles.get_mut(id)? {
Handle::Consumer {
ref mut events,
ref mut notified,
@@ -515,9 +506,7 @@ impl SchemeSync for InputScheme {
}
fn on_close(&mut self, id: usize) {
let handle = self.handles.remove(&id).unwrap();
match handle {
match self.handles.remove(id).unwrap() {
Handle::Consumer { vt, .. } => {
self.vts.remove(&vt);
if self.active_vt == Some(vt) {
+1
View File
@@ -8,6 +8,7 @@ edition = "2021"
libredox.workspace = true
daemon = { path = "../../../daemon" }
redox-scheme.workspace = true
scheme-utils = { path = "../../../scheme-utils" }
redox_syscall = { workspace = true, features = ["std"] }
[lints]
+14 -26
View File
@@ -1,4 +1,3 @@
use std::collections::BTreeMap;
use std::{cmp, io};
use libredox::flag::O_NONBLOCK;
@@ -7,6 +6,7 @@ use redox_scheme::{
scheme::{IntoTag, Op, SchemeResponse, SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket,
};
use scheme_utils::HandleMap;
use syscall::schemev2::NewFdFlags;
use syscall::{
Error, EventFlags, Result, Stat, EACCES, EAGAIN, EBADF, EINTR, EINVAL, EWOULDBLOCK, MODE_FILE,
@@ -208,8 +208,7 @@ impl<T: NetworkAdapter> NetworkScheme<T> {
struct NetworkSchemeInner<T: NetworkAdapter> {
adapter: T,
scheme_name: String,
next_id: usize,
handles: BTreeMap<usize, Handle>,
handles: HandleMap<Handle>,
}
enum Handle {
@@ -223,18 +222,14 @@ impl<T: NetworkAdapter> NetworkSchemeInner<T> {
Self {
adapter,
scheme_name,
next_id: 0,
handles: BTreeMap::new(),
handles: HandleMap::new(),
}
}
}
impl<T: NetworkAdapter> SchemeSync for NetworkSchemeInner<T> {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.insert(Handle::SchemeRoot))
}
fn openat(
@@ -245,10 +240,7 @@ impl<T: NetworkAdapter> SchemeSync for NetworkSchemeInner<T> {
_fcntl_flags: u32,
ctx: &CallerCtx,
) -> Result<OpenResult> {
if !matches!(
self.handles.get(&fd).ok_or(Error::new(EINVAL))?,
Handle::SchemeRoot
) {
if !matches!(self.handles.get(fd)?, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
if ctx.uid != 0 {
@@ -261,12 +253,8 @@ impl<T: NetworkAdapter> SchemeSync for NetworkSchemeInner<T> {
_ => return Err(Error::new(EINVAL)),
};
self.next_id += 1;
self.handles.insert(self.next_id, handle);
Ok(OpenResult::ThisScheme {
number: self.next_id,
flags,
})
let id = self.handles.insert(handle);
Ok(OpenResult::ThisScheme { number: id, flags })
}
fn read(
@@ -277,7 +265,7 @@ impl<T: NetworkAdapter> SchemeSync for NetworkSchemeInner<T> {
fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get_mut(id)?;
match *handle {
Handle::Data => {}
@@ -310,7 +298,7 @@ impl<T: NetworkAdapter> SchemeSync for NetworkSchemeInner<T> {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(id)?;
match handle {
Handle::Data => {}
@@ -322,12 +310,12 @@ impl<T: NetworkAdapter> SchemeSync for NetworkSchemeInner<T> {
}
fn fevent(&mut self, id: usize, _flags: EventFlags, _ctx: &CallerCtx) -> Result<EventFlags> {
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let _handle = self.handles.get(id)?;
Ok(EventFlags::empty())
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(id)?;
const PREFIX: &[u8] = b"/scheme/";
let len = cmp::min(PREFIX.len(), buf.len());
@@ -362,7 +350,7 @@ impl<T: NetworkAdapter> SchemeSync for NetworkSchemeInner<T> {
}
fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(id)?;
match handle {
Handle::Data { .. } => {
@@ -379,11 +367,11 @@ impl<T: NetworkAdapter> SchemeSync for NetworkSchemeInner<T> {
}
fn fsync(&mut self, id: usize, _ctx: &CallerCtx) -> Result<()> {
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let _handle = self.handles.get(id)?;
Ok(())
}
fn on_close(&mut self, id: usize) {
self.handles.remove(&id);
self.handles.remove(id);
}
}
+1
View File
@@ -21,6 +21,7 @@ pci_types = "0.10.1"
pico-args = { workspace = true, features = ["combined-flags"] }
plain.workspace = true
redox-scheme.workspace = true
scheme-utils = { path = "../../scheme-utils" }
redox_syscall.workspace = true
serde.workspace = true
+22 -44
View File
@@ -3,6 +3,7 @@ use std::collections::{BTreeMap, VecDeque};
use pci_types::{ConfigRegionAccess, PciAddress};
use redox_scheme::scheme::SchemeSync;
use redox_scheme::{CallerCtx, OpenResult};
use scheme_utils::HandleMap;
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
use syscall::error::{Error, Result, EACCES, EBADF, EINVAL, EIO, EISDIR, ENOENT, ENOTDIR};
use syscall::flag::{MODE_CHR, MODE_DIR, O_DIRECTORY, O_STAT};
@@ -12,8 +13,7 @@ use syscall::ENOLCK;
use crate::cfg_access::Pcie;
pub struct PciScheme {
handles: BTreeMap<usize, HandleWrapper>,
next_id: usize,
handles: HandleMap<HandleWrapper>,
pub pcie: Pcie,
pub tree: BTreeMap<PciAddress, crate::Func>,
}
@@ -53,34 +53,19 @@ const DEVICE_CONTENTS: &[&str] = &["channel"];
impl PciScheme {
pub fn access(&mut self) -> usize {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(
id,
HandleWrapper {
inner: Handle::Access,
stat: false,
},
);
id
self.handles.insert(HandleWrapper {
inner: Handle::Access,
stat: false,
})
}
}
impl SchemeSync for PciScheme {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(
id,
HandleWrapper {
inner: Handle::SchemeRoot,
stat: false,
},
);
Ok(id)
Ok(self.handles.insert(HandleWrapper {
inner: Handle::SchemeRoot,
stat: false,
}))
}
fn openat(
&mut self,
@@ -90,7 +75,7 @@ impl SchemeSync for PciScheme {
_fcntl_flags: u32,
ctx: &CallerCtx,
) -> Result<OpenResult> {
let handle = self.handles.get(&dirfd).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(dirfd)?;
if !handle.inner.is_scheme_root() {
return Err(Error::new(EACCES));
}
@@ -132,23 +117,17 @@ impl SchemeSync for PciScheme {
return Err(Error::new(EACCES));
}
let id = self.next_id;
self.next_id += 1;
self.handles.insert(
id,
HandleWrapper {
inner: handle,
stat,
},
);
let id = self.handles.insert(HandleWrapper {
inner: handle,
stat,
});
Ok(OpenResult::ThisScheme {
number: id,
flags: NewFdFlags::POSITIONED,
})
}
fn fstat(&mut self, id: usize, stat: &mut syscall::Stat, _ctx: &CallerCtx) -> Result<()> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get_mut(id)?;
let (len, mode) = match handle.inner {
Handle::TopLevel { ref entries } => (entries.len(), MODE_DIR | 0o755),
@@ -168,7 +147,7 @@ impl SchemeSync for PciScheme {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get_mut(id)?;
if handle.stat {
return Err(Error::new(EBADF));
@@ -195,7 +174,7 @@ impl SchemeSync for PciScheme {
return Ok(buf);
};
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get_mut(id)?;
if handle.stat {
return Err(Error::new(EBADF));
@@ -237,7 +216,7 @@ impl SchemeSync for PciScheme {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get_mut(id)?;
if handle.stat {
return Err(Error::new(EBADF));
@@ -259,7 +238,7 @@ impl SchemeSync for PciScheme {
metadata: &[u64],
_ctx: &CallerCtx,
) -> Result<usize> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get_mut(id)?;
if handle.stat {
return Err(Error::new(EBADF));
@@ -329,7 +308,7 @@ impl SchemeSync for PciScheme {
impl PciScheme {
pub fn on_close(&mut self, id: usize) {
match self.handles.remove(&id) {
match self.handles.remove(id) {
Some(HandleWrapper {
inner: Handle::Channel { addr, .. },
..
@@ -347,8 +326,7 @@ impl PciScheme {
impl PciScheme {
pub fn new(pcie: Pcie) -> Self {
Self {
handles: BTreeMap::new(),
next_id: 0,
handles: HandleMap::new(),
pcie,
tree: BTreeMap::new(),
}
+1
View File
@@ -17,6 +17,7 @@ futures = { version = "0.3.28", features = ["executor"] }
redox_syscall = { workspace = true, features = ["std"] }
redox-scheme.workspace = true
scheme-utils = { path = "../../../scheme-utils" }
[lints]
workspace = true
+12 -21
View File
@@ -13,6 +13,7 @@ use libredox::Fd;
use partitionlib::{LogicalBlockSize, PartitionTable};
use redox_scheme::scheme::{register_scheme_inner, SchemeAsync, SchemeState};
use redox_scheme::{CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket};
use scheme_utils::HandleMap;
use syscall::dirent::DirentBuf;
use syscall::schemev2::NewFdFlags;
use syscall::{
@@ -276,8 +277,7 @@ impl<T: Disk> DiskScheme<T> {
.into_iter()
.map(|(k, disk)| (k, DiskWrapper::new(disk, executor)))
.collect(),
next_id: 0,
handles: BTreeMap::new(),
handles: HandleMap::new(),
};
let cap_id = inner.scheme_root().expect("failed to get this scheme root");
@@ -361,8 +361,7 @@ struct DiskSchemeInner<T> {
scheme_name: String,
socket: Socket,
disks: BTreeMap<u32, DiskWrapper<T>>,
handles: BTreeMap<usize, Handle>,
next_id: usize,
handles: HandleMap<Handle>,
}
pub trait ExecutorTrait {
@@ -432,10 +431,7 @@ impl<T: Disk> DiskSchemeInner<T> {
impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.insert(Handle::SchemeRoot))
}
async fn openat(
&mut self,
@@ -445,10 +441,7 @@ impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
_fcntl_flags: u32,
ctx: &CallerCtx,
) -> Result<OpenResult> {
if !matches!(
self.handles.get(&dirfd).ok_or(Error::new(EBADF))?,
Handle::SchemeRoot
) {
if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
@@ -515,9 +508,7 @@ impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
return Err(Error::new(ENOENT));
}
};
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, handle);
let id = self.handles.insert(handle);
Ok(OpenResult::ThisScheme {
number: id,
flags: NewFdFlags::POSITIONED,
@@ -534,7 +525,7 @@ impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
}
async fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
match *self.handles.get(&id).ok_or(Error::new(EBADF))? {
match *self.handles.get(id)? {
Handle::List(ref data) => {
stat.st_mode = MODE_DIR;
stat.st_size = data.len() as u64;
@@ -568,7 +559,7 @@ impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
}
async fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(id)?;
let mut i = 0;
@@ -622,7 +613,7 @@ impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
match *self.handles.get_mut(id)? {
Handle::List(ref handle) => {
let src = usize::try_from(offset)
.ok()
@@ -654,7 +645,7 @@ impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
match *self.handles.get_mut(id)? {
Handle::List(_) => Err(Error::new(EBADF)),
Handle::Disk(number) => {
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
@@ -671,7 +662,7 @@ impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
}
async fn fsize(&mut self, id: usize, _ctx: &CallerCtx) -> Result<u64> {
Ok(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
Ok(match *self.handles.get_mut(id)? {
Handle::List(ref handle) => handle.len() as u64,
Handle::Disk(number) => {
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
@@ -696,6 +687,6 @@ impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
impl<D: Disk> DiskSchemeInner<D> {
pub fn on_close(&mut self, id: usize) {
let _ = self.handles.remove(&id);
let _ = self.handles.remove(id);
}
}
+1
View File
@@ -9,6 +9,7 @@ libredox = { workspace = true, features = ["call"]}
daemon = { path = "../daemon" }
redox_syscall.workspace = true
redox-scheme.workspace = true
scheme-utils = { path = "../scheme-utils" }
redox_event.workspace = true
anyhow.workspace = true
libc.workspace = true
+18 -53
View File
@@ -1,4 +1,5 @@
use redox_scheme::{scheme::SchemeSync, CallerCtx, OpenResult};
use scheme_utils::HandleMap;
use std::{
cmp,
collections::{hash_map::Entry, HashMap},
@@ -14,10 +15,10 @@ enum Handle {
SchemeRoot,
}
impl Handle {
fn as_shm(&self) -> Option<&Rc<str>> {
fn as_shm(&self) -> Result<&Rc<str>, Error> {
match self {
Self::Shm(path) => Some(path),
Self::SchemeRoot => None,
Self::Shm(path) => Ok(path),
Self::SchemeRoot => Err(Error::new(EBADF)),
}
}
}
@@ -32,26 +33,20 @@ pub struct ShmHandle {
}
pub struct ShmScheme {
maps: HashMap<Rc<str>, ShmHandle>,
handles: HashMap<usize, Handle>,
next_id: usize,
handles: HandleMap<Handle>,
}
impl ShmScheme {
pub fn new() -> Self {
Self {
maps: HashMap::new(),
handles: HashMap::new(),
next_id: 0,
handles: HandleMap::new(),
}
}
}
impl SchemeSync for ShmScheme {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.insert(Handle::SchemeRoot))
}
//FIXME: Handle O_RDONLY/O_WRONLY/O_RDWR
fn openat(
@@ -62,7 +57,7 @@ impl SchemeSync for ShmScheme {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<OpenResult> {
let handle = self.handles.get(&dirfd).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(dirfd)?;
if !matches!(handle, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
@@ -87,10 +82,8 @@ impl SchemeSync for ShmScheme {
}
};
entry.refs += 1;
self.handles.insert(self.next_id, Handle::Shm(path));
let id = self.handles.insert(Handle::Shm(path));
let id = self.next_id;
self.next_id += 1;
Ok(OpenResult::ThisScheme {
number: id,
flags: NewFdFlags::POSITIONED,
@@ -106,18 +99,14 @@ impl SchemeSync for ShmScheme {
}
// Write path
let path = self
.handles
.get(&id)
.and_then(Handle::as_shm)
.ok_or(Error::new(EBADF))?;
let path = self.handles.get(id).and_then(Handle::as_shm)?;
let len = cmp::min(path.len(), buf.len() - PREFIX.len());
buf[PREFIX.len()..][..len].copy_from_slice(&path.as_bytes()[..len]);
Ok(PREFIX.len() + len)
}
fn on_close(&mut self, id: usize) {
let Handle::Shm(path) = self.handles.remove(&id).unwrap() else {
let Handle::Shm(path) = self.handles.remove(id).unwrap() else {
return;
};
let mut entry = match self.maps.entry(path) {
@@ -131,7 +120,7 @@ impl SchemeSync for ShmScheme {
}
}
fn unlinkat(&mut self, dirfd: usize, path: &str, flags: usize, _ctx: &CallerCtx) -> Result<()> {
let handle = self.handles.get(&dirfd).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(dirfd)?;
if !matches!(handle, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
@@ -152,11 +141,7 @@ impl SchemeSync for ShmScheme {
Ok(())
}
fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
let path = self
.handles
.get(&id)
.and_then(Handle::as_shm)
.ok_or(Error::new(EBADF))?;
let path = self.handles.get(id).and_then(Handle::as_shm)?;
let size = self
.maps
.get(path)
@@ -174,11 +159,7 @@ impl SchemeSync for ShmScheme {
Ok(())
}
fn fsize(&mut self, id: usize, _ctx: &CallerCtx) -> Result<u64> {
let path = self
.handles
.get(&id)
.and_then(Handle::as_shm)
.ok_or(Error::new(EBADF))?;
let path = self.handles.get(id).and_then(Handle::as_shm)?;
let size = self
.maps
.get(path)
@@ -189,11 +170,7 @@ impl SchemeSync for ShmScheme {
Ok(size as u64)
}
fn ftruncate(&mut self, id: usize, len: u64, _ctx: &CallerCtx) -> Result<()> {
let path = self
.handles
.get(&id)
.and_then(Handle::as_shm)
.ok_or(Error::new(EBADF))?;
let path = self.handles.get(id).and_then(Handle::as_shm)?;
self.maps
.get_mut(path)
.expect("handle pointing to nothing")
@@ -208,11 +185,7 @@ impl SchemeSync for ShmScheme {
_flags: MapFlags,
_ctx: &CallerCtx,
) -> Result<usize> {
let path = self
.handles
.get(&id)
.and_then(Handle::as_shm)
.ok_or(Error::new(EBADF))?;
let path = self.handles.get(id).and_then(Handle::as_shm)?;
self.maps
.get_mut(path)
.expect("handle pointing to nothing")
@@ -227,11 +200,7 @@ impl SchemeSync for ShmScheme {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
let path = self
.handles
.get(&id)
.and_then(Handle::as_shm)
.ok_or(Error::new(EBADF))?;
let path = self.handles.get(id).and_then(Handle::as_shm)?;
self.maps
.get_mut(path)
.expect("handle pointing to nothing")
@@ -246,11 +215,7 @@ impl SchemeSync for ShmScheme {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
let path = self
.handles
.get(&id)
.and_then(Handle::as_shm)
.ok_or(Error::new(EBADF))?;
let path = self.handles.get(id).and_then(Handle::as_shm)?;
self.maps
.get_mut(path)
.expect("handle pointing to nothing")
+1
View File
@@ -10,6 +10,7 @@ redox_syscall.workspace = true
daemon = { path = "../daemon" }
libredox.workspace = true
redox-scheme.workspace = true
scheme-utils = { path = "../scheme-utils" }
[lints]
workspace = true
+19 -35
View File
@@ -7,6 +7,7 @@ use std::sync::mpsc::{self, Sender};
use redox_scheme::scheme::SchemeSync;
use redox_scheme::{CallerCtx, OpenResult, SendFdRequest, Socket};
use scheme_utils::HandleMap;
use syscall::error::*;
use syscall::schemev2::NewFdFlags;
@@ -20,11 +21,10 @@ pub enum LogHandle {
}
pub struct LogScheme<'sock> {
next_id: usize,
socket: &'sock Socket,
kernel_debug: File,
output_tx: Sender<OutputCmd>,
handles: BTreeMap<usize, LogHandle>,
handles: HandleMap<LogHandle>,
}
enum OutputCmd {
@@ -88,11 +88,10 @@ impl<'sock> LogScheme<'sock> {
});
LogScheme {
next_id: 0,
socket,
kernel_debug,
output_tx,
handles: BTreeMap::new(),
handles: HandleMap::new(),
}
}
@@ -133,10 +132,7 @@ impl<'sock> LogScheme<'sock> {
impl<'sock> SchemeSync for LogScheme<'sock> {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
self.handles.insert(id, LogHandle::SchemeRoot);
Ok(id)
Ok(self.handles.insert(LogHandle::SchemeRoot))
}
fn openat(
&mut self,
@@ -146,27 +142,18 @@ impl<'sock> SchemeSync for LogScheme<'sock> {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> Result<OpenResult> {
if !matches!(
self.handles.get(&dirfd).ok_or(Error::new(EBADF))?,
LogHandle::SchemeRoot
) {
if !matches!(self.handles.get(dirfd)?, LogHandle::SchemeRoot) {
return Err(Error::new(EACCES));
}
let id = self.next_id;
self.next_id += 1;
if path == "add_sink" {
self.handles.insert(id, LogHandle::AddSink);
let id = if path == "add_sink" {
self.handles.insert(LogHandle::AddSink)
} else {
self.handles.insert(
id,
LogHandle::Log {
context: path.to_string().into_boxed_str(),
bufs: BTreeMap::new(),
},
);
}
self.handles.insert(LogHandle::Log {
context: path.to_string().into_boxed_str(),
bufs: BTreeMap::new(),
})
};
Ok(OpenResult::ThisScheme {
number: id,
@@ -182,7 +169,7 @@ impl<'sock> SchemeSync for LogScheme<'sock> {
_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let _handle = self.handles.get(id)?;
// TODO
@@ -197,7 +184,7 @@ impl<'sock> SchemeSync for LogScheme<'sock> {
_flags: u32,
ctx: &CallerCtx,
) -> Result<usize> {
let (context, bufs) = match self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
let (context, bufs) = match self.handles.get_mut(id)? {
LogHandle::Log { context, bufs } => (context, bufs),
LogHandle::SchemeRoot | LogHandle::AddSink => return Err(Error::new(EBADF)),
};
@@ -218,10 +205,7 @@ impl<'sock> SchemeSync for LogScheme<'sock> {
fn on_sendfd(&mut self, sendfd_request: &SendFdRequest) -> Result<usize> {
let id = sendfd_request.id();
if !matches!(
self.handles.get(&id).ok_or(Error::new(EBADF))?,
LogHandle::AddSink
) {
if !matches!(self.handles.get(id)?, LogHandle::AddSink) {
return Err(Error::new(EBADF));
}
@@ -239,13 +223,13 @@ impl<'sock> SchemeSync for LogScheme<'sock> {
}
fn fcntl(&mut self, id: usize, _cmd: usize, _arg: usize, _ctx: &CallerCtx) -> Result<usize> {
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let _handle = self.handles.get(id)?;
Ok(0)
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(id)?;
let scheme_path = b"/scheme/log/";
@@ -271,7 +255,7 @@ impl<'sock> SchemeSync for LogScheme<'sock> {
}
fn fsync(&mut self, id: usize, _ctx: &CallerCtx) -> Result<()> {
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
let _handle = self.handles.get(id)?;
//TODO: flush remaining data?
@@ -279,6 +263,6 @@ impl<'sock> SchemeSync for LogScheme<'sock> {
}
fn on_close(&mut self, id: usize) {
self.handles.remove(&id);
self.handles.remove(id);
}
}
+1
View File
@@ -16,6 +16,7 @@ redox-log.workspace = true
libredox = { workspace = true, features = ["mkns"] }
anyhow.workspace = true
redox-scheme.workspace = true
scheme-utils = { path = "../scheme-utils" }
[dependencies.log]
workspace = true
+1 -1
View File
@@ -457,7 +457,7 @@ where
let scheme = &mut self.scheme;
let state = &mut self.state;
for (&fd, handle) in &mut scheme.handles {
for (&fd, handle) in scheme.handles.iter_mut() {
let Handle::File(file) = handle else {
continue;
};
+27 -54
View File
@@ -6,6 +6,7 @@ use redox_scheme::{
scheme::{register_scheme_inner, SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket,
};
use scheme_utils::HandleMap;
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
use std::cell::RefCell;
use std::collections::BTreeMap;
@@ -343,8 +344,7 @@ impl NetCfgScheme {
}));
let mut inner = NetCfgSchemeInner {
scheme_file,
next_fd: 1,
handles: BTreeMap::new(),
handles: HandleMap::new(),
root_node: mk_root_node(
iface,
Rc::clone(&notifier),
@@ -426,8 +426,7 @@ enum Handle {
struct NetCfgSchemeInner {
scheme_file: Socket,
next_fd: usize,
handles: BTreeMap<usize, Handle>,
handles: HandleMap<Handle>,
root_node: CfgNodeRef,
notifier: NotifierRef,
}
@@ -443,10 +442,7 @@ impl NetCfgSchemeInner {
impl SchemeSync for NetCfgSchemeInner {
fn scheme_root(&mut self) -> SyscallResult<usize> {
let id = self.next_fd;
self.next_fd += 1;
self.handles.insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.insert(Handle::SchemeRoot))
}
fn openat(
@@ -458,10 +454,7 @@ impl SchemeSync for NetCfgSchemeInner {
ctx: &CallerCtx,
) -> SyscallResult<OpenResult> {
{
let handle = self
.handles
.get(&dirfd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get(dirfd)?;
if !matches!(handle, Handle::SchemeRoot) {
return Err(SyscallError::new(syscall::EACCES));
@@ -481,28 +474,23 @@ impl SchemeSync for NetCfgSchemeInner {
}
let current_node = current_node.borrow();
let read_buf = Vec::from(current_node.read());
let fd = self.next_fd;
let fd = self.handles.insert(Handle::File(NetCfgFile {
path: path.to_owned(),
is_dir: current_node.is_dir(),
is_writable: current_node.is_writable(),
is_readable: current_node.is_readable(),
node_writer: if current_node.is_writable() {
current_node.new_writer()
} else {
None
},
uid: ctx.uid,
pos: 0,
read_buf,
write_buf: vec![],
done: false,
}));
trace!("open {} {}", fd, path);
self.next_fd += 1;
self.handles.insert(
fd,
Handle::File(NetCfgFile {
path: path.to_owned(),
is_dir: current_node.is_dir(),
is_writable: current_node.is_writable(),
is_readable: current_node.is_readable(),
node_writer: if current_node.is_writable() {
current_node.new_writer()
} else {
None
},
uid: ctx.uid,
pos: 0,
read_buf,
write_buf: vec![],
done: false,
}),
);
Ok(OpenResult::ThisScheme {
number: fd,
flags: NewFdFlags::empty(),
@@ -511,7 +499,7 @@ impl SchemeSync for NetCfgSchemeInner {
fn on_close(&mut self, fd: usize) {
trace!("close {}", fd);
if let Some(handle) = self.handles.remove(&fd) {
if let Some(handle) = self.handles.remove(fd) {
match handle {
Handle::SchemeRoot => {
// SchemeRoot closed, nothing specific to clean up
@@ -534,10 +522,7 @@ impl SchemeSync for NetCfgSchemeInner {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> SyscallResult<usize> {
let handle = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get_mut(fd)?;
let file = match handle {
Handle::File(file) => file,
@@ -575,10 +560,7 @@ impl SchemeSync for NetCfgSchemeInner {
_fcntl_flags: u32,
_ctx: &CallerCtx,
) -> SyscallResult<usize> {
let handle = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get_mut(fd)?;
let file = match handle {
Handle::File(file) => file,
@@ -595,10 +577,7 @@ impl SchemeSync for NetCfgSchemeInner {
}
fn fstat(&mut self, fd: usize, stat: &mut Stat, _ctx: &CallerCtx) -> SyscallResult<()> {
let handle = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get_mut(fd)?;
match handle {
Handle::SchemeRoot => return Err(SyscallError::new(syscall::EBADF)),
@@ -625,10 +604,7 @@ impl SchemeSync for NetCfgSchemeInner {
events: SyscallEventFlags,
_ctx: &CallerCtx,
) -> SyscallResult<SyscallEventFlags> {
let handle = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get_mut(fd)?;
match handle {
Handle::SchemeRoot => return Err(SyscallError::new(syscall::EBADF)),
@@ -644,10 +620,7 @@ impl SchemeSync for NetCfgSchemeInner {
}
fn fsync(&mut self, fd: usize, _ctx: &CallerCtx) -> SyscallResult<()> {
let handle = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get_mut(fd)?;
let file = match handle {
Handle::File(file) => file,
+23 -85
View File
@@ -15,6 +15,7 @@ use redox_scheme::{
scheme::{register_scheme_inner, Op, SchemeSync},
CallerCtx, OpenResult, Socket,
};
use scheme_utils::HandleMap;
use syscall::data::TimeSpec;
use syscall::flag::{EVENT_READ, EVENT_WRITE};
use syscall::schemev2::NewFdFlags;
@@ -274,8 +275,7 @@ pub struct SocketScheme<SocketT>
where
SocketT: SchemeSocket + AnySocket<'static>,
{
next_fd: usize,
pub handles: BTreeMap<usize, Handle<SocketT>>,
pub handles: HandleMap<Handle<SocketT>>,
ref_counts: BTreeMap<SocketHandle, usize>,
context: Context,
pub socket_set: Rc<RefCell<SocketSet>>,
@@ -296,8 +296,7 @@ where
scheme_file: Socket,
) -> SyscallResult<SocketScheme<SocketT>> {
let mut scheme = SocketScheme {
next_fd: 1,
handles: BTreeMap::new(),
handles: HandleMap::new(),
ref_counts: BTreeMap::new(),
socket_set,
scheme_data: SocketT::new_scheme_data(),
@@ -313,10 +312,7 @@ where
pub fn handle_block(&mut self, op: &Op) -> SyscallResult<Option<TimeSpec>> {
let fd = op.file_id().expect("op is not fd based request");
let (read_timeout, write_timeout) = {
let handle = self
.handles
.get(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get(fd)?;
if let Handle::File(SchemeFile::Socket(ref scheme_file)) = *handle {
Ok((scheme_file.read_timeout, scheme_file.write_timeout))
@@ -351,10 +347,7 @@ where
setting: Setting<SocketT::SettingT>,
buf: &mut [u8],
) -> SyscallResult<usize> {
let file = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let file = self.handles.get_mut(fd)?;
let file = match *file {
Handle::File(SchemeFile::Socket(ref mut file)) => file,
@@ -400,10 +393,7 @@ where
setting: Setting<SocketT::SettingT>,
buf: &[u8],
) -> SyscallResult<usize> {
let file = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let file = self.handles.get_mut(fd)?;
let file = match *file {
Handle::File(SchemeFile::Socket(ref mut file)) => file,
_ => return Err(SyscallError::new(syscall::EBADF)),
@@ -469,10 +459,7 @@ where
Ok(0)
}
SocketCall::GetSockOpt => {
let handle = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get_mut(fd)?;
match *handle {
Handle::File(ref mut file) => {
@@ -506,10 +493,7 @@ where
// SocketCall::Unbind => self.handle_unbind(id),
// SocketCall::GetToken => self.handle_get_token(id, payload),
SocketCall::GetPeerName => {
let file = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let file = self.handles.get_mut(fd)?;
let file = match *file {
Handle::File(ref mut f) => f,
@@ -522,10 +506,7 @@ where
}
SocketCall::RecvMsg => {
let flags = metadata[1] as usize;
let handle = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get_mut(fd)?;
match *handle {
Handle::File(ref mut file) => {
@@ -542,11 +523,7 @@ where
SocketCall::Shutdown => {
let how = metadata[1] as usize;
match self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?
{
match self.handles.get_mut(fd)? {
Handle::File(file) => {
let mut socket_set = self.socket_set.borrow_mut();
let socket = socket_set.get_mut::<SocketT>(file.socket_handle());
@@ -590,10 +567,7 @@ where
write_enabled,
};
let id = self.next_fd;
self.next_fd += 1;
self.handles.insert(id, Handle::Null(null));
let id = self.handles.insert(Handle::Null(null));
Ok(OpenResult::ThisScheme {
number: id,
@@ -621,11 +595,8 @@ where
data,
});
let id = self.next_fd;
self.next_fd += 1;
self.ref_counts.insert(socket_handle, 1);
self.handles.insert(id, Handle::File(file));
let id = self.handles.insert(Handle::File(file));
Ok(OpenResult::ThisScheme {
number: id,
@@ -640,10 +611,7 @@ where
SocketT: SchemeSocket + AnySocket<'static>,
{
fn scheme_root(&mut self) -> SyscallResult<usize> {
let id = self.next_fd;
self.next_fd += 1;
self.handles.insert(id, Handle::SchemeRoot);
Ok(id)
Ok(self.handles.insert(Handle::SchemeRoot))
}
fn openat(
@@ -654,12 +622,7 @@ where
_fcntl_flags: u32,
ctx: &CallerCtx,
) -> SyscallResult<OpenResult> {
let handle = self
.handles
.get(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
match handle {
match self.handles.get(fd)? {
Handle::SchemeRoot => self.open_inner(path, flags, ctx.uid, ctx.gid, true, true),
_ => Err(SyscallError::new(syscall::EACCES)),
}
@@ -676,9 +639,7 @@ where
}
fn on_close(&mut self, fd: usize) {
let handle = if let Some(handle) = self.handles.remove(&fd) {
handle
} else {
let Some(handle) = self.handles.remove(fd) else {
return;
};
@@ -738,10 +699,7 @@ where
_ctx: &CallerCtx,
) -> SyscallResult<usize> {
let (fd, setting) = {
let file = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let file = self.handles.get_mut(fd)?;
match *file {
Handle::File(SchemeFile::Setting(ref setting_handle)) => {
@@ -773,10 +731,7 @@ where
_ctx: &CallerCtx,
) -> SyscallResult<usize> {
let (fd, setting) = {
let file = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let file = self.handles.get_mut(fd)?;
match *file {
Handle::File(SchemeFile::Setting(ref setting_handle)) => {
(setting_handle.fd, setting_handle.setting)
@@ -804,10 +759,7 @@ where
let path = str::from_utf8(buf).or_else(|_| Err(SyscallError::new(syscall::EINVAL)))?;
let new_file = {
let handle = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get_mut(fd)?;
let file = match *handle {
Handle::SchemeRoot => return Err(SyscallError::new(syscall::EBADF)),
@@ -888,9 +840,7 @@ where
new_handle
};
let id = self.next_fd;
self.handles.insert(id, Handle::File(new_file));
self.next_fd += 1;
let id = self.handles.insert(Handle::File(new_file));
Ok(OpenResult::ThisScheme {
number: id,
@@ -904,10 +854,7 @@ where
events: SyscallEventFlags,
_ctx: &CallerCtx,
) -> SyscallResult<SyscallEventFlags> {
let file = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let file = self.handles.get_mut(fd)?;
let file = match *file {
Handle::File(ref mut f) => f,
@@ -929,10 +876,7 @@ where
fn fsync(&mut self, fd: usize, _ctx: &CallerCtx) -> SyscallResult<()> {
{
let _file = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let _file = self.handles.get_mut(fd)?;
}
Ok(())
// TODO Implement fsyncing
@@ -940,10 +884,7 @@ where
}
fn fpath(&mut self, fd: usize, buf: &mut [u8], _ctx: &CallerCtx) -> SyscallResult<usize> {
let file = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let file = self.handles.get_mut(fd)?;
let file = match *file {
Handle::File(ref mut f) => f,
@@ -963,10 +904,7 @@ where
arg: usize,
_ctx: &CallerCtx,
) -> SyscallResult<usize> {
let handle = self
.handles
.get_mut(&fd)
.ok_or_else(|| SyscallError::new(syscall::EBADF))?;
let handle = self.handles.get_mut(fd)?;
match *handle {
Handle::File(SchemeFile::Socket(ref mut socket_file)) => match cmd {
+1
View File
@@ -12,6 +12,7 @@ description = "RAM filesystem, which is useful for early logging"
daemon = { path = "../daemon" }
redox_syscall.workspace = true
redox-scheme.workspace = true
scheme-utils = { path = "../scheme-utils" }
libredox = { workspace = true, features = ["call"] }
indexmap = "2.5.0"
slab.workspace = true
+16 -29
View File
@@ -1,10 +1,10 @@
use std::collections::HashMap;
use std::convert::{TryFrom, TryInto};
use std::io::{Cursor, Seek};
use std::iter;
use std::os::unix::io::AsRawFd;
use std::{mem, str};
use scheme_utils::HandleMap;
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
use syscall::error::{
EACCES, EBADF, EBADFD, EEXIST, EINVAL, EIO, EISDIR, ENOMEM, ENOSYS, ENOTDIR, ENOTEMPTY,
@@ -33,8 +33,7 @@ enum Handle {
pub struct Scheme {
scheme_name: String,
filesystem: Filesystem,
handles: HashMap<usize, Handle>,
next_id: usize,
handles: HandleMap<Handle>,
proc_creds_capability: libredox::Fd,
}
impl Scheme {
@@ -43,8 +42,7 @@ impl Scheme {
Ok(Self {
scheme_name,
filesystem: Filesystem::new()?,
handles: HashMap::new(),
next_id: 0,
handles: HandleMap::new(),
proc_creds_capability: {
libredox::Fd::open(
"/scheme/proc/proc-creds-capability",
@@ -168,10 +166,7 @@ impl Scheme {
impl SchemeSync for Scheme {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.handles.insert(id, Handle::SchemeRoot);
self.next_id += 1;
Ok(id)
Ok(self.handles.insert(Handle::SchemeRoot))
}
fn openat(
&mut self,
@@ -181,10 +176,7 @@ impl SchemeSync for Scheme {
fcntl_flags: u32,
ctx: &CallerCtx,
) -> Result<OpenResult> {
if !matches!(
self.handles.get(&dirfd).ok_or(Error::new(EBADF))?,
Handle::SchemeRoot
) {
if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
@@ -274,9 +266,7 @@ impl SchemeSync for Scheme {
self.open_existing(path, flags | fcntl_flags as usize, ctx.uid, ctx.gid)?
.0
};
let new_id = self.next_id;
self.handles.insert(new_id, Handle::Inode(inode));
self.next_id += 1;
let new_id = self.handles.insert(Handle::Inode(inode));
Ok(OpenResult::ThisScheme {
number: new_id,
flags: NewFdFlags::POSITIONED,
@@ -284,10 +274,7 @@ impl SchemeSync for Scheme {
}
fn unlinkat(&mut self, dirfd: usize, path: &str, flags: usize, ctx: &CallerCtx) -> Result<()> {
{
if !matches!(
self.handles.get(&dirfd).ok_or(Error::new(EBADF))?,
Handle::SchemeRoot
) {
if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
}
@@ -309,7 +296,7 @@ impl SchemeSync for Scheme {
let Ok(offset) = usize::try_from(offset) else {
return Ok(0);
};
let inode = match self.handles.get(&fd).ok_or(Error::new(EBADFD))? {
let inode = match self.handles.get(fd)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
@@ -345,7 +332,7 @@ impl SchemeSync for Scheme {
let Ok(offset) = usize::try_from(opaque_offset) else {
return Ok(buf);
};
let inode = match self.handles.get(&fd).ok_or(Error::new(EBADFD))? {
let inode = match self.handles.get(fd)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
@@ -380,7 +367,7 @@ impl SchemeSync for Scheme {
let Ok(offset) = usize::try_from(offset) else {
return Ok(0);
};
let inode = match self.handles.get(&fd).ok_or(Error::new(EBADFD))? {
let inode = match self.handles.get(fd)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
@@ -410,7 +397,7 @@ impl SchemeSync for Scheme {
}
}
fn fchmod(&mut self, fd: usize, mode: u16, _ctx: &CallerCtx) -> Result<()> {
let inode = match self.handles.get(&fd).ok_or(Error::new(EBADFD))? {
let inode = match self.handles.get(fd)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
@@ -474,7 +461,7 @@ impl SchemeSync for Scheme {
Err(Error::new(ENOSYS))
}
fn fpath(&mut self, fd: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let mut current_inode = match *self.handles.get(&fd).ok_or(Error::new(EBADFD))? {
let mut current_inode = match *self.handles.get(fd)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
@@ -523,7 +510,7 @@ impl SchemeSync for Scheme {
Err(Error::new(ENOSYS))
}
fn fstat(&mut self, fd: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
let inode = match *self.handles.get(&fd).ok_or(Error::new(EBADFD))? {
let inode = match *self.handles.get(fd)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
@@ -601,7 +588,7 @@ impl SchemeSync for Scheme {
Ok(())
}
fn ftruncate(&mut self, fd: usize, size: u64, _ctx: &CallerCtx) -> Result<()> {
let inode = match self.handles.get(&fd).ok_or(Error::new(EBADFD))? {
let inode = match self.handles.get(fd)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
@@ -630,7 +617,7 @@ impl SchemeSync for Scheme {
Ok(())
}
fn futimens(&mut self, fd: usize, times: &[TimeSpec], _ctx: &CallerCtx) -> Result<()> {
let inode = match self.handles.get(&fd).ok_or(Error::new(EBADFD))? {
let inode = match self.handles.get(fd)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
@@ -693,7 +680,7 @@ impl SchemeSync for Scheme {
}
impl Scheme {
pub fn on_close(&mut self, fd: usize) {
let Some(Handle::Inode(inode)) = self.handles.remove(&fd) else {
let Some(Handle::Inode(inode)) = self.handles.remove(fd) else {
return;
};
let Some(inode_info) = self.filesystem.files.get_mut(&inode) else {
+1
View File
@@ -12,6 +12,7 @@ redox_syscall.workspace = true
libredox.workspace = true
sha2 = "0.8"
redox-scheme.workspace = true
scheme-utils = { path = "../scheme-utils" }
[target.'cfg(target_arch = "x86_64")'.dependencies]
raw-cpuid = "11.0.1"
+9 -42
View File
@@ -17,6 +17,7 @@ use redox_scheme::{
scheme::{SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket,
};
use scheme_utils::HandleMap;
use syscall::data::Stat;
use syscall::flag::{EventFlags, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_WRONLY};
use syscall::schemev2::NewFdFlags;
@@ -25,8 +26,6 @@ use syscall::{Error, Result, EACCES, EBADF, EEXIST, ENOENT, EPERM, MODE_CHR};
// Create an RNG Seed to create initial seed from the rdrand intel instruction
use rand_core::SeedableRng;
use sha2::{Digest, Sha256};
use std::collections::BTreeMap;
use std::num::Wrapping;
// This Daemon implements a Cryptographically Secure Random Number Generator
// that does not block on read - i.e. it is equivalent to linux /dev/urandom
@@ -148,11 +147,7 @@ struct RandScheme {
// https://docs.rs/rand/0.5.0/rand/prng/chacha/struct.ChaChaRng.html
// Allows 2^64 streams of random numbers, which we will equate with file numbers
prng_stat: Stat,
handles: BTreeMap<usize, Handle>,
// calls the system RNG (us) for entropy to protect against HashDOS attacks.
// Trying to create a HashMap causes a system crash.
// <file number, information about the open file>
next_id: Wrapping<usize>,
handles: HandleMap<Handle>,
}
impl RandScheme {
@@ -166,15 +161,14 @@ impl RandScheme {
st_uid: 0,
..Default::default()
},
handles: BTreeMap::new(),
next_id: Wrapping(0),
handles: HandleMap::new(),
}
}
/// Gets the open file info for a file descriptor if it is open - error otherwise.
fn get_fd(&self, fd: usize) -> Result<&OpenFileInfo> {
// Check we've got a valid file descriptor
let handle = self.handles.get(&fd).ok_or(Error::new(EBADF))?;
let handle = self.handles.get(fd)?;
handle.as_file().ok_or(Error::new(EBADF))
}
/// Checks to see if the op (MODE_READ, MODE_WRITE) can be performed on the open file
@@ -212,7 +206,6 @@ impl RandScheme {
return Err(Error::new(EEXIST));
}
let id = self.next_id;
let open_file_info = OpenFileInfo {
o_flags: flags,
file_stat: self.prng_stat,
@@ -231,20 +224,10 @@ impl RandScheme {
return Err(Error::new(EPERM));
}
self.handles.insert(id.0, Handle::File(open_file_info));
// If we've looped round there's a small chance that the file descriptor still exists, so loop till we get one that doesn't
self.next_id += Wrapping(1);
loop {
if !self.handles.contains_key(&self.next_id.0) {
break;
} else {
self.next_id += Wrapping(1);
}
}
let id = self.handles.insert(Handle::File(open_file_info));
Ok(OpenResult::ThisScheme {
number: id.0,
number: id,
flags: NewFdFlags::empty(),
})
}
@@ -354,20 +337,7 @@ fn test_scheme_perms() {
impl SchemeSync for RandScheme {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.handles.insert(id.0, Handle::SchemeRoot);
// Get the next file descriptor
self.next_id += Wrapping(1);
// If we've looped round there's a small chance that the file descriptor still exists, so loop till we get one that doesn't
loop {
if !self.handles.contains_key(&self.next_id.0) {
break;
} else {
self.next_id += Wrapping(1);
}
}
Ok(id.0)
Ok(self.handles.insert(Handle::SchemeRoot))
}
fn openat(
@@ -378,10 +348,7 @@ impl SchemeSync for RandScheme {
_fcntl_flags: u32,
ctx: &CallerCtx,
) -> Result<OpenResult> {
if !matches!(
self.handles.get(&dirfd).ok_or(Error::new(EBADF))?,
Handle::SchemeRoot
) {
if !matches!(self.handles.get(dirfd)?, Handle::SchemeRoot) {
return Err(Error::new(EACCES));
}
@@ -489,7 +456,7 @@ impl SchemeSync for RandScheme {
fn on_close(&mut self, file: usize) {
// just remove the file descriptor from the open descriptors
let _ = self.handles.remove(&file);
self.handles.remove(file);
}
}
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "scheme-utils"
version = "0.0.0"
edition = "2024"
[dependencies]
libredox.workspace = true
redox_syscall.workspace = true
[lints]
workspace = true
+67
View File
@@ -0,0 +1,67 @@
use std::collections::{BTreeMap, btree_map};
use std::num::Wrapping;
use syscall::{EBADF, Error, Result};
pub struct HandleMap<T> {
handles: BTreeMap<usize, T>,
next_id: Wrapping<usize>,
}
impl<T> HandleMap<T> {
pub const fn new() -> Self {
HandleMap {
handles: BTreeMap::new(),
next_id: Wrapping(1),
}
}
pub fn insert(&mut self, handle: T) -> usize {
let id = self.next_id;
// If we've looped round there's a small chance that the file descriptor still exists, so loop till we get one that doesn't
self.next_id += Wrapping(1);
loop {
if !self.handles.contains_key(&self.next_id.0) {
break;
} else {
self.next_id += Wrapping(1);
}
}
self.handles.insert(id.0, handle);
id.0
}
pub fn remove(&mut self, id: usize) -> Option<T> {
self.handles.remove(&id)
}
pub fn get(&self, id: usize) -> Result<&T> {
self.handles.get(&id).ok_or(Error::new(EBADF))
}
pub fn get_mut(&mut self, id: usize) -> Result<&mut T> {
self.handles.get_mut(&id).ok_or(Error::new(EBADF))
}
pub fn iter(&self) -> btree_map::Iter<'_, usize, T> {
self.handles.iter()
}
pub fn iter_mut(&mut self) -> btree_map::IterMut<'_, usize, T> {
self.handles.iter_mut()
}
pub fn keys(&self) -> btree_map::Keys<'_, usize, T> {
self.handles.keys()
}
pub fn values(&self) -> btree_map::Values<'_, usize, T> {
self.handles.values()
}
pub fn values_mut(&mut self) -> btree_map::ValuesMut<'_, usize, T> {
self.handles.values_mut()
}
}