scheme-utils: Introduce FpathWriter helper

This commit is contained in:
bjorn3
2026-04-19 14:35:33 +02:00
parent 648939b5b8
commit 64d23e9e05
24 changed files with 267 additions and 407 deletions
+6 -16
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;
@@ -324,21 +324,11 @@ 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)
FpathWriter::with(buf, |w| {
let _handle = self.handles.lock().get_mut(id)?;
w.push_str("/scheme/audiohw");
Ok(())
})
}
fn on_close(&mut self, id: usize) {
+6 -11
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;
@@ -1077,16 +1077,11 @@ 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)
FpathWriter::with(buf, |w| {
let _handle = self.handles.lock().get_mut(id)?;
w.push_str("/scheme/audiohw");
Ok(())
})
}
fn on_close(&mut self, id: usize) {
+6 -11
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;
@@ -223,16 +223,11 @@ 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)?;
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)
FpathWriter::with(buf, |w| {
let _handle = self.handles.lock().get_mut(id)?;
w.push_str("/scheme/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, |w| {
match self.handles.get(id)? {
Handle::V2 {
vt,
next_id: _,
buffers: _,
} => write!(w, "/scheme/{}/v2/{vt}", self.scheme_name).unwrap(),
Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)),
};
Ok(())
})
}
fn call(
+5 -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,10 @@ 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(buf, |w| {
w.push_str("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(buf, |w| {
let handle = self.get_vt_handle_mut(id)?;
write!(w, "fbcon:{}", 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)?;
FpathWriter::with(buf, |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 {
let display = self.display.as_ref().ok_or(SysError::new(EINVAL))?;
write!(w, "/scheme/{}/{vt}", display).unwrap();
Ok(())
} else {
Err(SysError::new(EINVAL))
}
})
}
fn read(
+11 -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,16 @@ 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, |w| {
write!(w, "/scheme/{}/", self.scheme_name).unwrap();
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<()> {
+12 -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,20 @@ 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(buf, |w| {
write!(w, "{}:", self.scheme_name).unwrap();
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(
+7 -16
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;
@@ -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, |w| {
let handle = self.handles.get(&fd).ok_or(Error::new(EBADF))?;
write!(w, "{}", handle.to_scheme()).unwrap();
Ok(())
})
}
fn read(
+10 -16
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,17 @@ 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(buf, |w| {
w.push_str("chan:");
// 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]);
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))?);
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(()))
+6 -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,11 @@ 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, |w| {
w.push_str("/scheme/shm/");
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 {
+6 -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,11 @@ 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, |w| {
w.push_str("/scheme/uds_dgram/");
w.push_str(path);
Ok(())
})
}
fn read_inner(&mut self, id: usize, buf: &mut [u8], flags: u32) -> Result<usize> {
+6 -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,11 @@ 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, |w| {
w.push_str("/scheme/uds_stream/");
w.push_str(path);
Ok(())
})
}
}
+10 -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,15 @@ 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, |w| {
w.push_str("/scheme/log/");
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, |w| {
if let SchemeFile::Socket(ref socket_file) = *file {
match socket_file.data.socket_type {
IcmpSocketType::Echo => {
write!(w, "/scheme/icmp/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, "/scheme/icmp/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, |w| {
write!(w, "/scheme/ip/{}", self.ip_protocol()).unwrap();
Ok(())
})
}
fn handle_recvmsg(
+27 -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,34 @@ 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, |w| {
let unspecified = "0.0.0.0:0";
write!(w, "/scheme/tcp/").unwrap();
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(
+23 -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,32 @@ 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, |w| {
let unspecified = "0.0.0.0:0";
w.push_str("/scheme/udp/");
// 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, |w| {
write!(w, "/scheme/pty/{}", self.id).unwrap();
Ok(())
})
}
pub fn input(&mut self, buf: &[u8]) {
+34 -36
View File
@@ -1,10 +1,9 @@
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 +460,48 @@ 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, |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 component in iter::once(self.scheme_name.trim_start_matches('/'))
.chain(chain.iter().copied().rev())
{
write!(w, "/{component}").unwrap();
}
Ok(())
})
}
fn frename(&mut self, _inode: usize, _path: &str, _ctx: &CallerCtx) -> Result<usize> {
// TODO
+5 -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,10 @@ 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, |w| {
w.push_str("/scheme/rand");
Ok(())
})
}
fn fstat(&mut self, file: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
+31
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,33 @@ 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], f: impl FnOnce(&mut Self) -> Result<()>) -> Result<usize> {
let mut w = FpathWriter { buf, written: 0 };
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(())
}
}
+5 -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,10 @@ 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, |w| {
w.push_str("zero:");
Ok(())
})
}
fn fsync(&mut self, _id: usize, _ctx: &CallerCtx) -> Result<()> {