From 91f12cabd97f16dca3917626f8aa8c83f84873a6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 13 Dec 2025 14:15:43 +0100 Subject: [PATCH] ptyd: Update to redox-scheme 0.8 --- Cargo.lock | 12 +--- ptyd/Cargo.toml | 2 +- ptyd/src/controlterm.rs | 17 +++--- ptyd/src/main.rs | 120 ++++++++++++++++------------------------ ptyd/src/pgrp.rs | 14 ++--- ptyd/src/resource.rs | 6 +- ptyd/src/scheme.rs | 57 +++++++++++-------- ptyd/src/subterm.rs | 19 ++++--- ptyd/src/termios.rs | 14 ++--- ptyd/src/winsize.rs | 14 ++--- 10 files changed, 126 insertions(+), 149 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5a1f8d24c..c850e02047 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1417,7 +1417,7 @@ version = "0.1.0" dependencies = [ "daemon", "libredox", - "redox-scheme 0.3.0", + "redox-scheme 0.8.2", "redox_event", "redox_syscall", "redox_termios", @@ -1621,16 +1621,6 @@ dependencies = [ "redox_syscall", ] -[[package]] -name = "redox-scheme" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e7f06e1b19d8143043e959fbd7b76a37e759e3e9c6bbfc9c91c496b0b44d20" -dependencies = [ - "libredox", - "redox_syscall", -] - [[package]] name = "redox-scheme" version = "0.4.0" diff --git a/ptyd/Cargo.toml b/ptyd/Cargo.toml index 5c817ec36b..91348d0793 100644 --- a/ptyd/Cargo.toml +++ b/ptyd/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] libredox = "0.1.3" daemon = { path = "../daemon" } -redox-scheme = "0.3.0" +redox-scheme = "0.8.2" redox_event = "0.4.0" redox_syscall = "0.5.0" redox_termios = "0.1.3" diff --git a/ptyd/src/controlterm.rs b/ptyd/src/controlterm.rs index 6dbe3f9ac0..727c63ded8 100644 --- a/ptyd/src/controlterm.rs +++ b/ptyd/src/controlterm.rs @@ -3,6 +3,7 @@ use std::rc::{Rc, Weak}; use syscall::error::{Error, Result, EAGAIN, EINVAL}; use syscall::flag::{EventFlags, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK}; +use syscall::EWOULDBLOCK; use crate::pty::Pty; use crate::resource::Resource; @@ -39,7 +40,7 @@ impl Resource for PtyControlTerm { self.pty.borrow_mut().path(buf) } - fn read(&mut self, buf: &mut [u8]) -> Result> { + fn read(&mut self, buf: &mut [u8]) -> Result { self.notified_read = false; let mut pty = self.pty.borrow_mut(); @@ -60,28 +61,28 @@ impl Resource for PtyControlTerm { pty.miso.push_front(new_packet); } - Ok(Some(i)) + Ok(i) } else if self.flags & O_NONBLOCK == O_NONBLOCK || Rc::weak_count(&self.pty) == 0 { Err(Error::new(EAGAIN)) } else { - Ok(None) + Err(Error::new(EWOULDBLOCK)) } } - fn write(&mut self, buf: &[u8]) -> Result> { + fn write(&mut self, buf: &[u8]) -> Result { let mut pty = self.pty.borrow_mut(); if pty.mosi.len() >= 64 { - return Ok(None); + return Err(Error::new(EWOULDBLOCK)); } pty.input(buf); - Ok(Some(buf.len())) + Ok(buf.len()) } - fn sync(&mut self) -> Result { - Ok(0) + fn sync(&mut self) -> Result<()> { + Ok(()) } fn fcntl(&mut self, cmd: usize, arg: usize) -> Result { diff --git a/ptyd/src/main.rs b/ptyd/src/main.rs index 335f2ff856..46bdfff79e 100644 --- a/ptyd/src/main.rs +++ b/ptyd/src/main.rs @@ -1,11 +1,11 @@ +use std::cell::RefCell; + use event::{user_data, EventFlags, EventQueue}; -use libredox::errno::{EAGAIN, EBADF, EWOULDBLOCK}; -use libredox::error::Error; use libredox::{flag, Fd}; -use redox_scheme::{CallRequest, RequestKind, Response, SignalBehavior, Socket}; +use redox_scheme::wrappers::ReadinessBased; +use redox_scheme::{Response, SignalBehavior, Socket}; use syscall::data::TimeSpec; -use syscall::EINTR; mod controlterm; mod pgrp; @@ -37,6 +37,7 @@ fn daemon(daemon: daemon::Daemon) -> ! { Fd::open(&time_path, flag::O_NONBLOCK, 0).expect("pty: failed to open time:"); let socket = redox_scheme::Socket::nonblock("pty").expect("pty: failed to create pty scheme"); + let mut handler = ReadinessBased::new(&socket, 16); libredox::call::setrens(0, 0).expect("ptyd: failed to enter null namespace"); @@ -52,20 +53,18 @@ fn daemon(daemon: daemon::Daemon) -> ! { //TODO: do not set timeout if not necessary timeout(&mut time_file).expect("pty: failed to set timeout"); - let mut scheme = PtyScheme::new(); - let mut todo = Vec::new(); + let scheme = RefCell::new(PtyScheme::new()); let mut timeout_count = 0u64; - scan_requests(&socket, &mut scheme, &mut todo).expect("pty: could not scan requests"); - do_todos(&socket, &mut scheme, &mut todo); - issue_events(&socket, &mut scheme); + scan_requests(&mut handler, &scheme).expect("pty: could not scan requests"); + issue_events(&socket, &mut *scheme.borrow_mut()); for event_res in event_queue { let event = event_res.expect("pty: failed to read from event queue"); match event.user_data { EventSource::Socket => { - if scan_requests(&socket, &mut scheme, &mut todo).is_err() { + if scan_requests(&mut handler, &scheme).is_err() { break; } } @@ -74,92 +73,67 @@ fn daemon(daemon: daemon::Daemon) -> ! { timeout_count = timeout_count.wrapping_add(1); - for (_id, handle) in scheme.handles.iter_mut() { + for (_id, handle) in scheme.borrow_mut().handles.iter_mut() { handle.timeout(timeout_count); } + + handler + .poll_all_requests(|| scheme.borrow_mut()) + .expect("ihdad: failed to poll requests"); } } - do_todos(&socket, &mut scheme, &mut todo); - issue_events(&socket, &mut scheme); + issue_events(&socket, &mut *scheme.borrow_mut()); } std::process::exit(0); } -struct Todo { - request: CallRequest, - cancelling: bool, -} - fn scan_requests( - socket: &Socket, - scheme: &mut PtyScheme, - todo: &mut Vec, + handler: &mut ReadinessBased<'_>, + scheme: &RefCell, ) -> libredox::error::Result<()> { - loop { - let request = match socket.next_request(SignalBehavior::Restart) { - Ok(Some(req)) => req, - Ok(None) => return Err(Error::new(EBADF)), - Err(error) if error.errno == EWOULDBLOCK || error.errno == EAGAIN => break, - Err(other) => panic!("pty: failed to read from socket: {other}"), - }; + // 1. Read requests + match handler + .read_requests() + .expect("pty: failed to read from socket") + { + true => {} // Read requests success + false => { + panic!("pty: channel EOF") + } + } - match request.kind() { - RequestKind::Cancellation(req) => { - if let Some(idx) = todo - .iter() - .position(|t| t.request.request().request_id() == req.id) - { - todo[idx].cancelling = true; - } - } - RequestKind::Call(request) => { - if let Some(response) = request.handle_scheme_block(scheme) { - let _ = socket - .write_response(response, SignalBehavior::Restart) - .expect("pty: failed to write responses to pty scheme"); - } else { - todo.push(Todo { - request, - cancelling: false, - }); - } - } - _ => (), + // 2. Process requests + handler.process_requests(|| scheme.borrow_mut()); + + // 3. Poll all blocking requests + handler + .poll_all_requests(|| scheme.borrow_mut()) + .expect("pty: error occured in poll_all_requests"); + + // 4. Write responses + match handler + .write_responses() + .expect("pty: failed to write to socket") + { + true => {} // Write requests success + false => { + panic!("pty: channel EOF") } } Ok(()) } -fn do_todos(socket: &Socket, scheme: &mut PtyScheme, todo: &mut Vec) { - let mut i = 0; - while i < todo.len() { - if let Some(response) = todo[i].request.handle_scheme_block(scheme) { - todo.remove(i); - socket - .write_response(response, SignalBehavior::Restart) - .expect("pty: failed to write responses to pty scheme"); - } else if todo[i].cancelling { - socket - .write_response( - Response::new(&todo[i].request, Err(Error::new(EINTR).into())), - SignalBehavior::Restart, - ) - .expect("pty: failed to write responses to pty scheme"); - todo.remove(i); - } else { - i += 1; - } - } -} - fn issue_events(socket: &Socket, scheme: &mut PtyScheme) { for (id, handle) in scheme.handles.iter_mut() { let events = handle.events(); if events != syscall::EventFlags::empty() { socket - .post_fevent(*id, events.bits()) + .write_response( + Response::post_fevent(*id, events.bits()), + SignalBehavior::Restart, + ) .expect("pty: failed to send scheme event"); } } diff --git a/ptyd/src/pgrp.rs b/ptyd/src/pgrp.rs index 2cd785124d..5137bf2b14 100644 --- a/ptyd/src/pgrp.rs +++ b/ptyd/src/pgrp.rs @@ -39,7 +39,7 @@ impl Resource for PtyPgrp { } } - fn read(&mut self, buf: &mut [u8]) -> Result> { + fn read(&mut self, buf: &mut [u8]) -> Result { if let Some(pty_lock) = self.pty.upgrade() { let pty = pty_lock.borrow(); @@ -50,13 +50,13 @@ impl Resource for PtyPgrp { .ok_or(Error::new(EBADF))?; *dst_buf = (pty.pgrp as u32).to_ne_bytes(); - Ok(Some(4)) + Ok(4) } else { - Ok(Some(0)) + Ok(0) } } - fn write(&mut self, buf: &[u8]) -> Result> { + fn write(&mut self, buf: &[u8]) -> Result { if let Some(pty_lock) = self.pty.upgrade() { let mut pty = pty_lock.borrow_mut(); @@ -68,14 +68,14 @@ impl Resource for PtyPgrp { pty.pgrp = new_pgrp as usize; //println!("WRITE PGRP {}: {} => {}", pty.id, pty.pgrp, new_pgrp); - Ok(Some(4)) + Ok(4) } else { Err(Error::new(EPIPE)) } } - fn sync(&mut self) -> Result { - Ok(0) + fn sync(&mut self) -> Result<()> { + Ok(()) } fn fcntl(&mut self, cmd: usize, arg: usize) -> Result { diff --git a/ptyd/src/resource.rs b/ptyd/src/resource.rs index ed0c499c03..ac300b54ef 100644 --- a/ptyd/src/resource.rs +++ b/ptyd/src/resource.rs @@ -11,9 +11,9 @@ pub trait Resource { fn flags(&self) -> usize; fn path(&mut self, buf: &mut [u8]) -> Result; - fn read(&mut self, buf: &mut [u8]) -> Result>; - fn write(&mut self, buf: &[u8]) -> Result>; - fn sync(&mut self) -> Result; + fn read(&mut self, buf: &mut [u8]) -> Result; + fn write(&mut self, buf: &[u8]) -> Result; + fn sync(&mut self) -> Result<()>; fn fcntl(&mut self, cmd: usize, arg: usize) -> Result; fn fevent(&mut self) -> Result; fn events(&mut self) -> EventFlags; diff --git a/ptyd/src/scheme.rs b/ptyd/src/scheme.rs index 8a304d5b3c..f0402ca654 100644 --- a/ptyd/src/scheme.rs +++ b/ptyd/src/scheme.rs @@ -3,10 +3,12 @@ use std::collections::BTreeMap; use std::rc::Rc; use std::str; -use redox_scheme::SchemeBlock; +use redox_scheme::scheme::SchemeSync; +use redox_scheme::{CallerCtx, OpenResult}; use syscall::data::Stat; use syscall::error::{Error, Result, EBADF, EINVAL, ENOENT}; use syscall::flag::{EventFlags, MODE_CHR}; +use syscall::schemev2::NewFdFlags; use crate::controlterm::PtyControlTerm; use crate::pgrp::PtyPgrp; @@ -30,8 +32,8 @@ impl PtyScheme { } } -impl SchemeBlock for PtyScheme { - fn open(&mut self, path: &str, flags: usize, _uid: u32, _gid: u32) -> Result> { +impl SchemeSync for PtyScheme { + fn open(&mut self, path: &str, flags: usize, _ctx: &CallerCtx) -> Result { let path = path.trim_matches('/'); if path.is_empty() { @@ -42,7 +44,10 @@ impl SchemeBlock for PtyScheme { self.handles .insert(id, Box::new(PtyControlTerm::new(pty, flags))); - Ok(Some(id)) + Ok(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::empty(), + }) } else { let control_term_id = path.parse::().or(Err(Error::new(EINVAL)))?; let pty = { @@ -59,11 +64,14 @@ impl SchemeBlock for PtyScheme { self.handles .insert(id, Box::new(PtySubTerm::new(pty, flags))); - Ok(Some(id)) + Ok(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::empty(), + }) } } - fn dup(&mut self, old_id: usize, buf: &[u8]) -> Result> { + fn dup(&mut self, old_id: usize, buf: &[u8], _ctx: &CallerCtx) -> Result { let handle: Box = { let old_handle = self.handles.get(&old_id).ok_or(Error::new(EBADF))?; @@ -82,7 +90,10 @@ impl SchemeBlock for PtyScheme { self.next_id += 1; self.handles.insert(id, handle); - Ok(Some(id)) + Ok(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::empty(), + }) } fn read( @@ -91,7 +102,8 @@ impl SchemeBlock for PtyScheme { buf: &mut [u8], _offset: u64, _fcntl_flags: u32, - ) -> Result> { + _ctx: &CallerCtx, + ) -> Result { let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; handle.read(buf) } @@ -102,27 +114,28 @@ impl SchemeBlock for PtyScheme { buf: &[u8], _offset: u64, _fcntl_flags: u32, - ) -> Result> { + _ctx: &CallerCtx, + ) -> Result { let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; handle.write(buf) } - fn fcntl(&mut self, id: usize, cmd: usize, arg: usize) -> Result> { + fn fcntl(&mut self, id: usize, cmd: usize, arg: usize, _ctx: &CallerCtx) -> Result { let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; - handle.fcntl(cmd, arg).map(Some) + handle.fcntl(cmd, arg) } - fn fevent(&mut self, id: usize, _flags: EventFlags) -> Result> { + fn fevent(&mut self, id: usize, _flags: EventFlags, _ctx: &CallerCtx) -> Result { let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; - handle.fevent().map(Some) + handle.fevent() } - fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { + fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result { let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; - handle.path(buf).map(Some) + handle.path(buf) } - fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result> { + fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> { let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; *stat = Stat { @@ -130,17 +143,15 @@ impl SchemeBlock for PtyScheme { ..Default::default() }; - Ok(Some(0)) + Ok(()) } - fn fsync(&mut self, id: usize) -> Result> { + fn fsync(&mut self, id: usize, _ctx: &CallerCtx) -> Result<()> { let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; - handle.sync().map(Some) + handle.sync() } - fn close(&mut self, id: usize) -> Result> { - drop(self.handles.remove(&id)); - - Ok(Some(0)) + fn on_close(&mut self, id: usize) { + self.handles.remove(&id); } } diff --git a/ptyd/src/subterm.rs b/ptyd/src/subterm.rs index 96a7357765..098182da32 100644 --- a/ptyd/src/subterm.rs +++ b/ptyd/src/subterm.rs @@ -3,6 +3,7 @@ use std::rc::Weak; use syscall::error::{Error, Result, EAGAIN, EINVAL, EPIPE}; use syscall::flag::{EventFlags, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK}; +use syscall::EWOULDBLOCK; use crate::pty::Pty; use crate::resource::Resource; @@ -43,7 +44,7 @@ impl Resource for PtySubTerm { } } - fn read(&mut self, buf: &mut [u8]) -> Result> { + fn read(&mut self, buf: &mut [u8]) -> Result { self.notified_read = false; if let Some(pty_lock) = self.pty.upgrade() { @@ -63,40 +64,40 @@ impl Resource for PtySubTerm { pty.mosi.push_front(packet[i..].to_vec()); } - Ok(Some(i)) + Ok(i) } else if self.flags & O_NONBLOCK == O_NONBLOCK { Err(Error::new(EAGAIN)) } else { - Ok(None) + Err(Error::new(EWOULDBLOCK)) } } else { - Ok(Some(0)) + Ok(0) } } - fn write(&mut self, buf: &[u8]) -> Result> { + fn write(&mut self, buf: &[u8]) -> Result { if let Some(pty_lock) = self.pty.upgrade() { let mut pty = pty_lock.borrow_mut(); if pty.miso.len() >= 64 { - return Ok(None); + return Err(Error::new(EWOULDBLOCK)); } pty.output(buf); - Ok(Some(buf.len())) + Ok(buf.len()) } else { Err(Error::new(EPIPE)) } } - fn sync(&mut self) -> Result { + fn sync(&mut self) -> Result<()> { if let Some(pty_lock) = self.pty.upgrade() { let mut pty = pty_lock.borrow_mut(); pty.miso.push_back(vec![1]); - Ok(0) + Ok(()) } else { Err(Error::new(EPIPE)) } diff --git a/ptyd/src/termios.rs b/ptyd/src/termios.rs index 4918612350..5f28f38b8b 100644 --- a/ptyd/src/termios.rs +++ b/ptyd/src/termios.rs @@ -40,7 +40,7 @@ impl Resource for PtyTermios { } } - fn read(&mut self, buf: &mut [u8]) -> Result> { + fn read(&mut self, buf: &mut [u8]) -> Result { if let Some(pty_lock) = self.pty.upgrade() { let pty = pty_lock.borrow(); let termios: &[u8] = pty.termios.deref(); @@ -50,13 +50,13 @@ impl Resource for PtyTermios { buf[i] = termios[i]; i += 1; } - Ok(Some(i)) + Ok(i) } else { - Ok(Some(0)) + Ok(0) } } - fn write(&mut self, buf: &[u8]) -> Result> { + fn write(&mut self, buf: &[u8]) -> Result { if let Some(pty_lock) = self.pty.upgrade() { let mut pty = pty_lock.borrow_mut(); let termios: &mut [u8] = pty.termios.deref_mut(); @@ -66,14 +66,14 @@ impl Resource for PtyTermios { termios[i] = buf[i]; i += 1; } - Ok(Some(i)) + Ok(i) } else { Err(Error::new(EPIPE)) } } - fn sync(&mut self) -> Result { - Ok(0) + fn sync(&mut self) -> Result<()> { + Ok(()) } fn fcntl(&mut self, cmd: usize, arg: usize) -> Result { diff --git a/ptyd/src/winsize.rs b/ptyd/src/winsize.rs index a03edc48aa..a4b807eb79 100644 --- a/ptyd/src/winsize.rs +++ b/ptyd/src/winsize.rs @@ -40,7 +40,7 @@ impl Resource for PtyWinsize { } } - fn read(&mut self, buf: &mut [u8]) -> Result> { + fn read(&mut self, buf: &mut [u8]) -> Result { if let Some(pty_lock) = self.pty.upgrade() { let pty = pty_lock.borrow(); let winsize: &[u8] = pty.winsize.deref(); @@ -50,13 +50,13 @@ impl Resource for PtyWinsize { buf[i] = winsize[i]; i += 1; } - Ok(Some(i)) + Ok(i) } else { - Ok(Some(0)) + Ok(0) } } - fn write(&mut self, buf: &[u8]) -> Result> { + fn write(&mut self, buf: &[u8]) -> Result { if let Some(pty_lock) = self.pty.upgrade() { let mut pty = pty_lock.borrow_mut(); let winsize: &mut [u8] = pty.winsize.deref_mut(); @@ -66,14 +66,14 @@ impl Resource for PtyWinsize { winsize[i] = buf[i]; i += 1; } - Ok(Some(i)) + Ok(i) } else { Err(Error::new(EPIPE)) } } - fn sync(&mut self) -> Result { - Ok(0) + fn sync(&mut self) -> Result<()> { + Ok(()) } fn fcntl(&mut self, cmd: usize, arg: usize) -> Result {