Merge branch 'scheme_cleanups3' into 'main'

scheme-utils: Introduce FpathWriter helper

See merge request redox-os/base!233
This commit is contained in:
Jeremy Soller
2026-04-19 11:52:40 -06:00
24 changed files with 258 additions and 413 deletions
+3 -17
View File
@@ -2,7 +2,7 @@ use common::io::Pio;
use redox_scheme::scheme::SchemeSync;
use redox_scheme::CallerCtx;
use redox_scheme::OpenResult;
use scheme_utils::HandleMap;
use scheme_utils::{FpathWriter, HandleMap};
use syscall::error::{Error, Result, EACCES, EBADF, EINVAL, ENOENT};
use syscall::schemev2::NewFdFlags;
use syscall::EWOULDBLOCK;
@@ -323,22 +323,8 @@ 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)?;
if !matches!(handle, Handle::Todo) {
return Err(Error::new(EBADF));
}
}
let mut i = 0;
let scheme_path = b"/scheme/audiohw";
while i < buf.len() && i < scheme_path.len() {
buf[i] = scheme_path[i];
i += 1;
}
Ok(i)
fn fpath(&mut self, _id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
FpathWriter::with(buf, "audiohw", |_| Ok(()))
}
fn on_close(&mut self, id: usize) {
+3 -12
View File
@@ -13,7 +13,7 @@ use common::timeout::Timeout;
use redox_scheme::scheme::SchemeSync;
use redox_scheme::CallerCtx;
use redox_scheme::OpenResult;
use scheme_utils::HandleMap;
use scheme_utils::{FpathWriter, HandleMap};
use syscall::error::{Error, Result, EACCES, EBADF, EIO, ENODEV, EWOULDBLOCK};
use spin::Mutex;
@@ -1076,17 +1076,8 @@ 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)?;
let mut i = 0;
let scheme_path = b"/scheme/audiohw";
while i < buf.len() && i < scheme_path.len() {
buf[i] = scheme_path[i];
i += 1;
}
Ok(i)
fn fpath(&mut self, _id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
FpathWriter::with(buf, "audiohw", |_| Ok(()))
}
fn on_close(&mut self, id: usize) {
+3 -12
View File
@@ -5,7 +5,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 scheme_utils::{FpathWriter, HandleMap};
use syscall::error::{Error, Result, EACCES, EBADF, ENODEV};
use syscall::schemev2::NewFdFlags;
@@ -222,17 +222,8 @@ impl SchemeSync for Sb16 {
Err(Error::new(EBADF))
}
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)?;
let mut i = 0;
let scheme_path = b"/scheme/audiohw";
while i < buf.len() && i < scheme_path.len() {
buf[i] = scheme_path[i];
i += 1;
}
Ok(i)
fn fpath(&mut self, _id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
FpathWriter::with(buf, "audiohw", |_| Ok(()))
}
fn on_close(&mut self, id: usize) {
+12 -11
View File
@@ -18,7 +18,7 @@ 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 scheme_utils::{FpathWriter, HandleMap};
use syscall::schemev2::NewFdFlags;
use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EINVAL, ENOENT, EOPNOTSUPP};
@@ -424,16 +424,17 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> syscall::Result<usize> {
let path = match self.handles.get(id)? {
Handle::V2 {
vt,
next_id: _,
buffers: _,
} => format!("/scheme/{}/v2/{vt}", self.scheme_name),
Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)),
};
buf[..path.len()].copy_from_slice(path.as_bytes());
Ok(path.len())
FpathWriter::with(buf, &self.scheme_name, |w| {
match self.handles.get(id)? {
Handle::V2 {
vt,
next_id: _,
buffers: _,
} => write!(w, "v2/{vt}").unwrap(),
Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)),
};
Ok(())
})
}
fn call(
+2 -9
View File
@@ -9,6 +9,7 @@ use inputd::ConsumerHandle;
use orbclient::{Event, EventOption};
use redox_scheme::scheme::SchemeSync;
use redox_scheme::{CallerCtx, OpenResult};
use scheme_utils::FpathWriter;
use syscall::schemev2::NewFdFlags;
use syscall::{Error, Result, EACCES, EBADF, EINVAL, ENOENT};
@@ -196,15 +197,7 @@ impl SchemeSync for FbbootlogScheme {
}
fn fpath(&mut self, _id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let path = b"fbbootlog:";
let mut i = 0;
while i < buf.len() && i < path.len() {
buf[i] = path[i];
i += 1;
}
Ok(i)
FpathWriter::with_legacy(buf, "fbbootlog", |_| Ok(()))
}
fn fsync(&mut self, _id: usize, _ctx: &CallerCtx) -> Result<()> {
+6 -13
View File
@@ -4,7 +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 scheme_utils::{FpathWriter, HandleMap};
use syscall::schemev2::NewFdFlags;
use syscall::{Error, EventFlags, Result, EACCES, EAGAIN, EBADF, ENOENT, O_NONBLOCK};
@@ -125,18 +125,11 @@ impl SchemeSync for FbconScheme {
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let handle = self.get_vt_handle_mut(id)?;
let path_str = format!("fbcon:{}", handle.vt_i.0);
let path = path_str.as_bytes();
let mut i = 0;
while i < buf.len() && i < path.len() {
buf[i] = path[i];
i += 1;
}
Ok(i)
FpathWriter::with_legacy(buf, "fbcon", |w| {
let handle = self.get_vt_handle_mut(id)?;
write!(w, "{}", handle.vt_i.0).unwrap();
Ok(())
})
}
fn fsync(&mut self, id: usize, _ctx: &CallerCtx) -> Result<()> {
+11 -13
View File
@@ -25,7 +25,7 @@ use redox_scheme::scheme::SchemeSync;
use redox_scheme::{CallerCtx, OpenResult, Response, SignalBehavior, Socket};
use orbclient::{Event, EventOption};
use scheme_utils::{Blocking, HandleMap};
use scheme_utils::{Blocking, FpathWriter, HandleMap};
use syscall::schemev2::NewFdFlags;
use syscall::{Error as SysError, EventFlags, EACCES, EBADF, EEXIST, EINVAL};
@@ -269,19 +269,17 @@ impl SchemeSync for InputScheme {
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> syscall::Result<usize> {
let handle = self.handles.get(id)?;
let display = self.display.as_ref().ok_or(SysError::new(EINVAL))?;
FpathWriter::with(buf, display, |w| {
let handle = self.handles.get(id)?;
if let Handle::Consumer { vt, .. } = handle {
let display = self.display.as_ref().ok_or(SysError::new(EINVAL))?;
let vt = format!("/scheme/{}/{vt}", display);
let size = core::cmp::min(vt.len(), buf.len());
buf[..size].copy_from_slice(&vt.as_bytes()[..size]);
Ok(size)
} else {
Err(SysError::new(EINVAL))
}
if let Handle::Consumer { vt, .. } = handle {
write!(w, "{vt}").unwrap();
Ok(())
} else {
Err(SysError::new(EINVAL))
}
})
}
fn read(
+10 -33
View File
@@ -6,7 +6,7 @@ use redox_scheme::{
scheme::{IntoTag, Op, SchemeResponse, SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket,
};
use scheme_utils::HandleMap;
use scheme_utils::{FpathWriter, HandleMap};
use syscall::schemev2::NewFdFlags;
use syscall::{
Error, EventFlags, Result, Stat, EACCES, EAGAIN, EBADF, EINTR, EINVAL, EWOULDBLOCK, MODE_FILE,
@@ -315,38 +315,15 @@ impl<T: NetworkAdapter> SchemeSync for NetworkSchemeInner<T> {
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let handle = self.handles.get(id)?;
const PREFIX: &[u8] = b"/scheme/";
let len = cmp::min(PREFIX.len(), buf.len());
buf[..len].copy_from_slice(&PREFIX[..len]);
if len < PREFIX.len() {
return Ok(len);
}
let mut i = len;
let scheme_name = self.scheme_name.as_bytes();
let mut j = 0;
while i < buf.len() && j < scheme_name.len() {
buf[i] = scheme_name[j];
i += 1;
j += 1;
}
let path = match handle {
Handle::Data { .. } => &b""[..],
Handle::Mac { .. } => &b"mac"[..],
_ => &b""[..],
};
j = 0;
while i < buf.len() && j < path.len() {
buf[i] = path[j];
i += 1;
j += 1;
}
Ok(i)
FpathWriter::with(buf, &self.scheme_name, |w| {
let path = match self.handles.get(id)? {
Handle::Data { .. } => "",
Handle::Mac { .. } => "mac",
_ => "",
};
write!(w, "{path}").unwrap();
Ok(())
})
}
fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
+11 -42
View File
@@ -13,7 +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 scheme_utils::{FpathWriter, HandleMap};
use syscall::dirent::DirentBuf;
use syscall::schemev2::NewFdFlags;
use syscall::{
@@ -559,50 +559,19 @@ 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)?;
let mut i = 0;
let scheme_name = self.scheme_name.as_bytes();
let mut j = 0;
// TODO: copy_from_slice
while i < buf.len() && j < scheme_name.len() {
buf[i] = scheme_name[j];
i += 1;
j += 1;
}
if i < buf.len() {
buf[i] = b':';
i += 1;
}
match *handle {
Handle::List(_) => (),
Handle::Disk(number) => {
let number_str = format!("{}", number);
let number_bytes = number_str.as_bytes();
j = 0;
while i < buf.len() && j < number_bytes.len() {
buf[i] = number_bytes[j];
i += 1;
j += 1;
FpathWriter::with_legacy(buf, &self.scheme_name, |w| {
match *self.handles.get(id)? {
Handle::List(_) => (),
Handle::Disk(number) => {
write!(w, "{number}").unwrap();
}
}
Handle::Partition(disk_num, part_num) => {
let number_str = format!("{}p{}", disk_num, part_num);
let number_bytes = number_str.as_bytes();
j = 0;
while i < buf.len() && j < number_bytes.len() {
buf[i] = number_bytes[j];
i += 1;
j += 1;
Handle::Partition(disk_num, part_num) => {
write!(w, "{disk_num}p{part_num}").unwrap();
}
Handle::SchemeRoot => return Err(Error::new(EBADF)),
}
Handle::SchemeRoot => return Err(Error::new(EBADF)),
}
Ok(i)
Ok(())
})
}
async fn read(
+8 -17
View File
@@ -26,6 +26,7 @@ use common::dma::Dma;
use futures::executor::block_on;
use log::{debug, error, info, trace, warn};
use redox_scheme::scheme::SchemeSync;
use scheme_utils::FpathWriter;
use smallvec::SmallVec;
use common::io::Io;
@@ -197,7 +198,7 @@ impl Handle {
///
/// # Returns
/// - A [String] containing the scheme path that the handle is associated with.
pub(crate) fn to_scheme(&self) -> String {
pub(crate) fn to_path(&self) -> String {
match self {
Handle::TopLevel(_) => String::from(""),
Handle::Port(port_num, _) => {
@@ -2212,22 +2213,12 @@ impl<const N: usize> SchemeSync for &Xhci<N> {
Ok(())
}
fn fpath(&mut self, fd: usize, buffer: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let mut cursor = io::Cursor::new(buffer);
let guard = self.handles.get(&fd).ok_or(Error::new(EBADF))?;
let scheme = (&*guard).to_scheme();
write!(cursor, "{}", scheme.as_str()).expect(
format!(
"Failed to convert the file descriptor with value {} to the associated file path",
fd
)
.as_str(),
);
let src_len = usize::try_from(cursor.seek(io::SeekFrom::End(0)).unwrap()).unwrap();
Ok(src_len)
fn fpath(&mut self, fd: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
FpathWriter::with(buf, "xhci", |w| {
let handle = self.handles.get(&fd).ok_or(Error::new(EBADF))?;
write!(w, "{}", handle.to_path()).unwrap();
Ok(())
})
}
fn read(
+9 -17
View File
@@ -1,4 +1,5 @@
use redox_scheme::{scheme::SchemeSync, CallerCtx, OpenResult, Response, SignalBehavior, Socket};
use scheme_utils::FpathWriter;
use std::{
cmp,
collections::{HashMap, VecDeque},
@@ -330,24 +331,15 @@ impl<'sock> SchemeSync for ChanScheme<'sock> {
}
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
// Write scheme name
const PREFIX: &[u8] = b"chan:";
let len = cmp::min(PREFIX.len(), buf.len());
buf[..len].copy_from_slice(&PREFIX[..len]);
if len < PREFIX.len() {
return Ok(len);
}
FpathWriter::with_legacy(buf, "chan", |w| {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
if let Extra::SchemeRoot = handle.extra {
return Ok(());
}
w.push_str(handle.path.as_ref().ok_or(Error::new(EBADF))?);
// Write path
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
if let Extra::SchemeRoot = handle.extra {
return Ok(len);
}
let path = handle.path.as_ref().ok_or(Error::new(EBADF))?;
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)
Ok(())
})
}
fn fsync(&mut self, id: usize, _ctx: &CallerCtx) -> Result<()> {
self.handles.get(&id).ok_or(Error::new(EBADF)).and(Ok(()))
+5 -15
View File
@@ -1,5 +1,5 @@
use redox_scheme::{scheme::SchemeSync, CallerCtx, OpenResult};
use scheme_utils::HandleMap;
use scheme_utils::{FpathWriter, HandleMap};
use std::{
cmp,
collections::{hash_map::Entry, HashMap},
@@ -90,20 +90,10 @@ impl SchemeSync for ShmScheme {
})
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
// Write scheme name
const PREFIX: &[u8] = b"/scheme/shm/";
let len = cmp::min(PREFIX.len(), buf.len());
buf[..len].copy_from_slice(&PREFIX[..len]);
if len < PREFIX.len() {
return Ok(len);
}
// Write path
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)
FpathWriter::with(buf, "shm", |w| {
w.push_str(self.handles.get(id).and_then(Handle::as_shm)?);
Ok(())
})
}
fn on_close(&mut self, id: usize) {
let Handle::Shm(path) = self.handles.remove(id).unwrap() else {
+5 -13
View File
@@ -13,6 +13,7 @@ use redox_scheme::{
scheme::SchemeSync, CallerCtx, OpenResult, RecvFdRequest, Response, SendFdRequest,
SignalBehavior, Socket as SchemeSocket,
};
use scheme_utils::FpathWriter;
use std::{
cell::RefCell,
cmp,
@@ -566,19 +567,10 @@ impl<'sock> UdsDgramScheme<'sock> {
}
fn fpath_inner(path: &String, buf: &mut [u8]) -> Result<usize> {
// Write scheme name
const PREFIX: &[u8] = b"/scheme/uds_dgram/";
let len = cmp::min(PREFIX.len(), buf.len());
buf[..len].copy_from_slice(&PREFIX[..len]);
if len < PREFIX.len() {
return Ok(len);
}
// Write path
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)
FpathWriter::with(buf, "uds_dgram", |w| {
w.push_str(path);
Ok(())
})
}
fn read_inner(&mut self, id: usize, buf: &mut [u8], flags: u32) -> Result<usize> {
+5 -13
View File
@@ -12,6 +12,7 @@ use redox_scheme::{
scheme::SchemeSync, CallerCtx, OpenResult, RecvFdRequest, Response, SendFdRequest,
SignalBehavior, Socket as SchemeSocket,
};
use scheme_utils::FpathWriter;
use std::{
cell::RefCell,
cmp,
@@ -1228,19 +1229,10 @@ impl<'sock> UdsStreamScheme<'sock> {
}
fn fpath_inner(path: &String, buf: &mut [u8]) -> Result<usize> {
// Write scheme name
const PREFIX: &[u8] = b"/scheme/uds_stream/";
let len = cmp::min(PREFIX.len(), buf.len());
buf[..len].copy_from_slice(&PREFIX[..len]);
if len < PREFIX.len() {
return Ok(len);
}
// Write path
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)
FpathWriter::with(buf, "uds_stream", |w| {
w.push_str(path);
Ok(())
})
}
}
+9 -24
View File
@@ -7,7 +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 scheme_utils::{FpathWriter, HandleMap};
use syscall::error::*;
use syscall::schemev2::NewFdFlags;
@@ -229,29 +229,14 @@ impl<'sock> SchemeSync for LogScheme<'sock> {
}
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let handle = self.handles.get(id)?;
let scheme_path = b"/scheme/log/";
let mut i = 0;
while i < buf.len() && i < scheme_path.len() {
buf[i] = scheme_path[i];
i += 1;
}
let path_bytes = match handle {
LogHandle::Log { context, .. } => context.as_bytes(),
LogHandle::AddSink => b"add_sink",
LogHandle::SchemeRoot => return Err(Error::new(EBADF)),
};
let mut j = 0;
while i < buf.len() && j < path_bytes.len() {
buf[i] = path_bytes[j];
i += 1;
j += 1;
}
Ok(i)
FpathWriter::with(buf, "log", |w| {
w.push_str(match self.handles.get(id)? {
LogHandle::Log { context, .. } => context,
LogHandle::AddSink => "add_sink",
LogHandle::SchemeRoot => return Err(Error::new(EBADF)),
});
Ok(())
})
}
fn fsync(&mut self, id: usize, _ctx: &CallerCtx) -> Result<()> {
+12 -26
View File
@@ -1,3 +1,4 @@
use scheme_utils::FpathWriter;
use smoltcp::iface::SocketHandle;
use smoltcp::socket::icmp::{
Endpoint as IcmpEndpoint, PacketBuffer as IcmpSocketBuffer,
@@ -249,36 +250,21 @@ impl<'a> SchemeSocket for IcmpSocket<'a> {
}
fn fpath(&self, file: &SchemeFile<Self>, buf: &mut [u8]) -> SyscallResult<usize> {
if let SchemeFile::Socket(ref socket_file) = *file {
match socket_file.data.socket_type {
IcmpSocketType::Echo => {
let path = format!("/scheme/icmp/echo/{}", socket_file.data.ip);
let path = path.as_bytes();
let mut i = 0;
while i < buf.len() && i < path.len() {
buf[i] = path[i];
i += 1;
FpathWriter::with(buf, "icmp", |w| {
if let SchemeFile::Socket(ref socket_file) = *file {
match socket_file.data.socket_type {
IcmpSocketType::Echo => {
write!(w, "echo/{}", socket_file.data.ip).unwrap();
}
Ok(i)
}
IcmpSocketType::Udp => {
let path = format!("/scheme/icmp/udp/{}", socket_file.data.ip);
let path = path.as_bytes();
let mut i = 0;
while i < buf.len() && i < path.len() {
buf[i] = path[i];
i += 1;
IcmpSocketType::Udp => {
write!(w, "udp/{}", socket_file.data.ip).unwrap();
}
Ok(i)
}
Ok(())
} else {
Err(SyscallError::new(syscall::EBADF))
}
} else {
Err(SyscallError::new(syscall::EBADF))
}
})
}
fn handle_recvmsg(
+5 -10
View File
@@ -1,3 +1,4 @@
use scheme_utils::FpathWriter;
use smoltcp::iface::SocketHandle;
use smoltcp::socket::raw::{
PacketBuffer as RawSocketBuffer, PacketMetadata as RawPacketMetadata, Socket as RawSocket,
@@ -137,16 +138,10 @@ impl<'a> SchemeSocket for RawSocket<'a> {
}
fn fpath(&self, _file: &SchemeFile<Self>, buf: &mut [u8]) -> SyscallResult<usize> {
let path = format!("/scheme/ip/{}", self.ip_protocol());
let path = path.as_bytes();
let mut i = 0;
while i < buf.len() && i < path.len() {
buf[i] = path[i];
i += 1;
}
Ok(i)
FpathWriter::with(buf, "ip", |w| {
write!(w, "{}", self.ip_protocol()).unwrap();
Ok(())
})
}
fn handle_recvmsg(
+26 -33
View File
@@ -1,7 +1,7 @@
use scheme_utils::FpathWriter;
use smoltcp::iface::SocketHandle;
use smoltcp::socket::tcp::{Socket as TcpSocket, SocketBuffer as TcpSocketBuffer};
use smoltcp::wire::{IpEndpoint, IpListenEndpoint};
use std::fmt::Write;
use std::str;
use syscall;
use syscall::{Error as SyscallError, Result as SyscallResult};
@@ -273,40 +273,33 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
}
fn fpath(&self, file: &SchemeFile<Self>, buf: &mut [u8]) -> SyscallResult<usize> {
let unspecified = "0.0.0.0:0";
let mut path = String::from("/scheme/tcp/");
match self.remote_endpoint() {
Some(endpoint) => write!(&mut path, "{}", endpoint).unwrap(),
None => path.push_str(unspecified),
}
path.push('/');
match (self.local_endpoint(), file) {
(Some(endpoint), _) => write!(&mut path, "{}", endpoint).unwrap(),
(
None,
SchemeFile::Socket(SocketFile {
data: Some(endpoint),
..
}),
) => {
if endpoint.is_specified() {
write!(&mut path, "{}", endpoint).unwrap()
} else {
write!(&mut path, "0.0.0.0:{}", endpoint.port).unwrap()
}
FpathWriter::with(buf, "tcp", |w| {
let unspecified = "0.0.0.0:0";
match self.remote_endpoint() {
Some(endpoint) => write!(w, "{}", endpoint).unwrap(),
None => w.push_str(unspecified),
}
w.push_str("/");
match (self.local_endpoint(), file) {
(Some(endpoint), _) => write!(w, "{}", endpoint).unwrap(),
(
None,
SchemeFile::Socket(SocketFile {
data: Some(endpoint),
..
}),
) => {
if endpoint.is_specified() {
write!(w, "{}", endpoint).unwrap()
} else {
write!(w, "0.0.0.0:{}", endpoint.port).unwrap()
}
}
_ => w.push_str(unspecified),
}
_ => path.push_str(unspecified),
}
trace!("fpath: {}", path);
let path = path.as_bytes();
let mut i = 0;
while i < buf.len() && i < path.len() {
buf[i] = path[i];
i += 1;
}
Ok(i)
Ok(())
})
}
fn handle_recvmsg(
+22 -28
View File
@@ -1,3 +1,4 @@
use scheme_utils::FpathWriter;
use smoltcp::iface::SocketHandle;
use smoltcp::socket::udp::{
PacketBuffer as UdpSocketBuffer, PacketMetadata as UdpPacketMetadata, Socket as UdpSocket,
@@ -12,7 +13,6 @@ use super::{parse_endpoint, SchemeWrapper, Smolnetd, SocketSet};
use crate::port_set::PortSet;
use crate::router::Router;
use libredox::flag;
use std::fmt::Write;
const SO_SNDBUF: usize = 7;
const SO_RCVBUF: usize = 8;
@@ -269,37 +269,31 @@ impl<'a> SchemeSocket for UdpSocket<'a> {
}
fn fpath(&self, file: &SchemeFile<Self>, buf: &mut [u8]) -> SyscallResult<usize> {
let unspecified = "0.0.0.0:0";
let mut path = String::from("/scheme/udp/");
FpathWriter::with(buf, "udp", |w| {
let unspecified = "0.0.0.0:0";
// remote
match file {
SchemeFile::Socket(SocketFile { data: endpoint, .. }) => {
if endpoint.is_specified() {
write!(&mut path, "{}", endpoint).unwrap()
} else {
write!(&mut path, "0.0.0.0:{}", endpoint.port).unwrap()
// remote
match file {
SchemeFile::Socket(SocketFile { data: endpoint, .. }) => {
if endpoint.is_specified() {
write!(w, "{}", endpoint).unwrap()
} else {
write!(w, "0.0.0.0:{}", endpoint.port).unwrap()
}
}
_ => w.push_str(unspecified),
}
w.push_str("/");
// local
let endpoint = self.endpoint();
if endpoint.is_specified() {
write!(w, "{}", endpoint).unwrap()
} else {
write!(w, "0.0.0.0:{}", endpoint.port).unwrap()
}
_ => path.push_str(unspecified),
}
path.push('/');
// local
let endpoint = self.endpoint();
if endpoint.is_specified() {
write!(&mut path, "{}", endpoint).unwrap()
} else {
write!(&mut path, "0.0.0.0:{}", endpoint.port).unwrap()
}
let path = path.as_bytes();
let mut i = 0;
while i < buf.len() && i < path.len() {
buf[i] = path[i];
i += 1;
}
Ok(i)
Ok(())
})
}
fn handle_recvmsg(
+5 -4
View File
@@ -1,7 +1,7 @@
use std::collections::VecDeque;
use std::io::{Cursor, Write};
use redox_termios::*;
use scheme_utils::FpathWriter;
use syscall::error::Result;
pub struct Pty {
@@ -32,9 +32,10 @@ impl Pty {
}
pub fn path(&self, buf: &mut [u8]) -> Result<usize> {
let mut buf = Cursor::new(buf);
let _ = write!(buf, "/scheme/pty/{}", self.id);
Ok(buf.position().try_into().unwrap_or(usize::MAX))
FpathWriter::with(buf, "pty", |w| {
write!(w, "{}", self.id).unwrap();
Ok(())
})
}
pub fn input(&mut self, buf: &[u8]) {
+35 -37
View File
@@ -1,10 +1,8 @@
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 scheme_utils::{FpathWriter, HandleMap};
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
use syscall::error::{
EACCES, EBADF, EBADFD, EEXIST, EINVAL, EIO, EISDIR, ENOMEM, ENOSYS, ENOTDIR, ENOTEMPTY,
@@ -461,49 +459,49 @@ 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)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
FpathWriter::with(buf, &self.scheme_name, |w| {
let mut current_inode = match *self.handles.get(fd)? {
Handle::Inode(inode) => inode,
Handle::SchemeRoot => return Err(Error::new(EISDIR)),
};
let mut chain = Vec::new();
let mut chain = Vec::new();
let mut current_info = self
.filesystem
.files
.get(&current_inode)
.ok_or(Error::new(EBADFD))?;
while current_inode != Filesystem::ROOT_INODE {
let parent_info = self
let mut current_info = self
.filesystem
.files
.get(&current_info.parent.0)
.get(&current_inode)
.ok_or(Error::new(EBADFD))?;
let FileData::Directory(ref dir) = parent_info.data else {
return Err(Error::new(EBADFD));
};
// TODO: error handling?
let (name, _) = dir
.iter()
.find(|(_name, inode)| inode.0 == current_inode)
.ok_or(Error::new(ENOENT))?;
chain.push(&**name);
while current_inode != Filesystem::ROOT_INODE {
let parent_info = self
.filesystem
.files
.get(&current_info.parent.0)
.ok_or(Error::new(EBADFD))?;
current_inode = current_info.parent.0;
current_info = parent_info;
}
let FileData::Directory(ref dir) = parent_info.data else {
return Err(Error::new(EBADFD));
};
// TODO: error handling?
let (name, _) = dir
.iter()
.find(|(_name, inode)| inode.0 == current_inode)
.ok_or(Error::new(ENOENT))?;
chain.push(&**name);
let mut cursor = Cursor::new(buf);
for component in
iter::once(self.scheme_name.trim_start_matches('/')).chain(chain.iter().copied().rev())
{
use std::io::Write;
current_inode = current_info.parent.0;
current_info = parent_info;
}
write!(cursor, "/{component}").unwrap();
}
Ok(cursor.stream_position().unwrap() as usize)
for (i, component) in chain.iter().copied().rev().enumerate() {
if i != 0 {
w.push_str("/");
}
w.push_str(component);
}
Ok(())
})
}
fn frename(&mut self, _inode: usize, _path: &str, _ctx: &CallerCtx) -> Result<usize> {
// TODO
+2 -8
View File
@@ -12,7 +12,7 @@ pub const MODE_READ: u16 = 0o4;
use raw_cpuid::CpuId;
use redox_scheme::{scheme::SchemeSync, CallerCtx, OpenResult, Socket};
use scheme_utils::{Blocking, HandleMap};
use scheme_utils::{Blocking, FpathWriter, HandleMap};
use syscall::data::Stat;
use syscall::flag::{EventFlags, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_WRONLY};
use syscall::schemev2::NewFdFlags;
@@ -431,13 +431,7 @@ impl SchemeSync for RandScheme {
Ok(EventFlags::EVENT_READ)
}
fn fpath(&mut self, _file: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let mut i = 0;
let scheme_path = b"rand";
while i < buf.len() && i < scheme_path.len() {
buf[i] = scheme_path[i];
i += 1;
}
Ok(i)
FpathWriter::with(buf, "rand", |_| Ok(()))
}
fn fstat(&mut self, file: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
+47
View File
@@ -1,6 +1,7 @@
#![feature(never_type)]
use std::collections::{BTreeMap, btree_map};
use std::fmt;
use std::num::Wrapping;
use syscall::{EBADF, Error, Result};
@@ -73,3 +74,49 @@ impl<T> HandleMap<T> {
self.handles.values_mut()
}
}
pub struct FpathWriter<'a> {
buf: &'a mut [u8],
written: usize,
}
impl<'a> FpathWriter<'a> {
pub fn with(
buf: &'a mut [u8],
scheme_name: &str,
f: impl FnOnce(&mut Self) -> Result<()>,
) -> Result<usize> {
let mut w = FpathWriter { buf, written: 0 };
write!(w, "/scheme/{scheme_name}/").unwrap();
f(&mut w)?;
Ok(w.written)
}
pub fn with_legacy(
buf: &'a mut [u8],
scheme_name: &str,
f: impl FnOnce(&mut Self) -> Result<()>,
) -> Result<usize> {
let mut w = FpathWriter { buf, written: 0 };
write!(w, "{scheme_name}:").unwrap();
f(&mut w)?;
Ok(w.written)
}
pub fn push_str(&mut self, s: &str) {
let count = core::cmp::min(s.len(), self.buf.len() - self.written);
self.buf[self.written..self.written + count].copy_from_slice(&s.as_bytes()[..count]);
self.written += count;
}
pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
std::fmt::write(self, args)
}
}
impl fmt::Write for FpathWriter<'_> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.push_str(s);
Ok(())
}
}
+2 -6
View File
@@ -1,5 +1,6 @@
use redox_scheme::scheme::SchemeSync;
use redox_scheme::{CallerCtx, OpenResult};
use scheme_utils::FpathWriter;
use syscall::{error::*, schemev2::NewFdFlags, MODE_CHR};
use crate::Ty;
@@ -67,12 +68,7 @@ impl SchemeSync for ZeroScheme {
}
fn fpath(&mut self, _id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
let scheme_path = b"zero:";
let size = std::cmp::min(buf.len(), scheme_path.len());
buf[..size].copy_from_slice(&scheme_path[..size]);
Ok(size)
FpathWriter::with(buf, "zero", |_| Ok(()))
}
fn fsync(&mut self, _id: usize, _ctx: &CallerCtx) -> Result<()> {