Files
RedBear-OS/recipes/core/base/ptyd/src/controlterm.rs
T
vasilito 8acc73d774 milestone: desktop path Phases 1-5
Phase 1 (Runtime Substrate): 4 check binaries, --probe, POSIX tests
Phase 2 (Wayland Compositor): bounded scaffold, zero warnings
Phase 3 (KWin Session): preflight checker (KWin stub, gated on Qt6Quick)
Phase 4 (KDE Plasma): 18 KF6 enabled, preflight checker
Phase 5 (Hardware GPU): DRM/firmware/Mesa preflight checker

Build: zero warnings, all scripts syntax-clean. Oracle-verified.
2026-04-29 09:54:06 +01:00

130 lines
3.2 KiB
Rust

use std::cell::RefCell;
use std::rc::{Rc, Weak};
use syscall::error::{Error, Result, EAGAIN, EINVAL, EWOULDBLOCK};
use syscall::flag::{EventFlags, F_GETFL, F_SETFL, O_ACCMODE, O_NONBLOCK};
use crate::pty::Pty;
use crate::resource::Resource;
/// Read side of a pipe
pub struct PtyControlTerm {
pty: Rc<RefCell<Pty>>,
flags: usize,
notified_read: bool,
notified_write: bool,
}
impl PtyControlTerm {
pub fn new(pty: Rc<RefCell<Pty>>, flags: usize) -> Self {
PtyControlTerm {
pty,
flags,
notified_read: false,
notified_write: false,
}
}
}
impl Resource for PtyControlTerm {
fn pty(&self) -> Weak<RefCell<Pty>> {
Rc::downgrade(&self.pty)
}
fn flags(&self) -> usize {
self.flags
}
fn path(&mut self, buf: &mut [u8]) -> Result<usize> {
self.pty.borrow_mut().path(buf)
}
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
self.notified_read = false;
let mut pty = self.pty.borrow_mut();
if let Some(packet) = pty.miso.pop_front() {
let mut i = 0;
while i < buf.len() && i < packet.len() {
buf[i] = packet[i];
i += 1;
}
if i < packet.len() {
let packet_remaining = &packet[i..];
let mut new_packet = Vec::with_capacity(packet_remaining.len() + 1);
new_packet.push(packet[0]);
new_packet.extend(packet_remaining);
pty.miso.push_front(new_packet);
}
Ok(i)
} else if self.flags & O_NONBLOCK == O_NONBLOCK || Rc::weak_count(&self.pty) == 0 {
Err(Error::new(EAGAIN))
} else {
Err(Error::new(EWOULDBLOCK))
}
}
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let mut pty = self.pty.borrow_mut();
if pty.mosi.len() >= 64 {
return Err(Error::new(EWOULDBLOCK));
}
pty.input(buf);
Ok(buf.len())
}
fn sync(&mut self) -> Result<()> {
Ok(())
}
fn fcntl(&mut self, cmd: usize, arg: usize) -> Result<usize> {
match cmd {
F_GETFL => Ok(self.flags),
F_SETFL => {
self.flags = (self.flags & O_ACCMODE) | (arg & !O_ACCMODE);
Ok(0)
}
_ => Err(Error::new(EINVAL)),
}
}
fn fevent(&mut self) -> Result<EventFlags> {
self.notified_read = false; // resend
self.notified_write = false;
Ok(self.events())
}
fn events(&mut self) -> EventFlags {
let mut events = EventFlags::empty();
let pty = self.pty.borrow();
if pty.miso.front().is_some() {
if !self.notified_read {
self.notified_read = true;
events |= syscall::EVENT_READ;
}
} else {
self.notified_read = false;
}
if !self.notified_write {
self.notified_write = true;
events |= syscall::EVENT_WRITE;
}
events
}
fn timeout(&self, count: u64) {
let mut pty = self.pty.borrow_mut();
pty.timeout(count);
}
}