ptyd: Update to redox-scheme 0.8

This commit is contained in:
bjorn3
2025-12-13 14:15:43 +01:00
parent feee6fe4de
commit 91f12cabd9
10 changed files with 126 additions and 149 deletions
Generated
+1 -11
View File
@@ -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"
+1 -1
View File
@@ -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"
+9 -8
View File
@@ -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<Option<usize>> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
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<Option<usize>> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
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<usize> {
Ok(0)
fn sync(&mut self) -> Result<()> {
Ok(())
}
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize> {
+47 -73
View File
@@ -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<Todo>,
handler: &mut ReadinessBased<'_>,
scheme: &RefCell<PtyScheme>,
) -> 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<Todo>) {
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");
}
}
+7 -7
View File
@@ -39,7 +39,7 @@ impl Resource for PtyPgrp {
}
}
fn read(&mut self, buf: &mut [u8]) -> Result<Option<usize>> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
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<Option<usize>> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
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<usize> {
Ok(0)
fn sync(&mut self) -> Result<()> {
Ok(())
}
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize> {
+3 -3
View File
@@ -11,9 +11,9 @@ pub trait Resource {
fn flags(&self) -> usize;
fn path(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read(&mut self, buf: &mut [u8]) -> Result<Option<usize>>;
fn write(&mut self, buf: &[u8]) -> Result<Option<usize>>;
fn sync(&mut self) -> Result<usize>;
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn sync(&mut self) -> Result<()>;
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize>;
fn fevent(&mut self) -> Result<EventFlags>;
fn events(&mut self) -> EventFlags;
+34 -23
View File
@@ -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<Option<usize>> {
impl SchemeSync for PtyScheme {
fn open(&mut self, path: &str, flags: usize, _ctx: &CallerCtx) -> Result<OpenResult> {
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::<usize>().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<Option<usize>> {
fn dup(&mut self, old_id: usize, buf: &[u8], _ctx: &CallerCtx) -> Result<OpenResult> {
let handle: Box<dyn Resource> = {
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<Option<usize>> {
_ctx: &CallerCtx,
) -> Result<usize> {
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<Option<usize>> {
_ctx: &CallerCtx,
) -> Result<usize> {
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<Option<usize>> {
fn fcntl(&mut self, id: usize, cmd: usize, arg: usize, _ctx: &CallerCtx) -> Result<usize> {
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<Option<EventFlags>> {
fn fevent(&mut self, id: usize, _flags: EventFlags, _ctx: &CallerCtx) -> Result<EventFlags> {
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<Option<usize>> {
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
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<Option<usize>> {
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<Option<usize>> {
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<Option<usize>> {
drop(self.handles.remove(&id));
Ok(Some(0))
fn on_close(&mut self, id: usize) {
self.handles.remove(&id);
}
}
+10 -9
View File
@@ -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<Option<usize>> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
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<Option<usize>> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
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<usize> {
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))
}
+7 -7
View File
@@ -40,7 +40,7 @@ impl Resource for PtyTermios {
}
}
fn read(&mut self, buf: &mut [u8]) -> Result<Option<usize>> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
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<Option<usize>> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
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<usize> {
Ok(0)
fn sync(&mut self) -> Result<()> {
Ok(())
}
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize> {
+7 -7
View File
@@ -40,7 +40,7 @@ impl Resource for PtyWinsize {
}
}
fn read(&mut self, buf: &mut [u8]) -> Result<Option<usize>> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
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<Option<usize>> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
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<usize> {
Ok(0)
fn sync(&mut self) -> Result<()> {
Ok(())
}
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize> {