use core::fmt::Debug; use alloc::sync::Arc; use system_error::SystemError; use crate::filesystem::vfs::file::FileMode; use super::{ termios::Termios, tty_core::{TtyCore, TtyCoreData, TtyFlag}, }; pub mod ntty; pub trait TtyLineDiscipline: Sync + Send + Debug { fn open(&self, tty: Arc) -> Result<(), SystemError>; fn close(&self, tty: Arc) -> Result<(), SystemError>; fn flush_buffer(&self, tty: Arc) -> Result<(), SystemError>; /// ## tty行规程循环读取函数 /// /// ### 参数 /// - tty: 操作的tty /// - buf: 数据将被读取到buf /// - len: 读取的字节长度 /// - cookie: 表示是否是继续上次的读,第一次读取应该传入false /// - offset: 读取的偏移量 fn read( &self, tty: Arc, buf: &mut [u8], len: usize, cookie: &mut bool, offset: usize, mode: FileMode, ) -> Result; fn write( &self, tty: Arc, buf: &[u8], len: usize, mode: FileMode, ) -> Result; fn ioctl(&self, tty: Arc, cmd: u32, arg: usize) -> Result; /// ### 设置termios后更新行规程状态 /// /// - old: 之前的termios,如果为None则表示第一次设置 fn set_termios(&self, tty: Arc, old: Option) -> Result<(), SystemError>; fn poll(&self, tty: Arc) -> Result; fn hangup(&self, tty: Arc) -> Result<(), SystemError>; /// ## 接收数据 fn receive_buf( &self, tty: Arc, buf: &[u8], flags: Option<&[u8]>, count: usize, ) -> Result; /// ## 接收数据 fn receive_buf2( &self, tty: Arc, buf: &[u8], flags: Option<&[u8]>, count: usize, ) -> Result; /// ## 唤醒线路写者 fn write_wakeup(&self, _tty: &TtyCoreData) -> Result<(), SystemError> { Err(SystemError::ENOSYS) } } #[derive(Debug, Clone, Copy)] pub enum LineDisciplineType { NTty = 0, } impl LineDisciplineType { pub fn from_line(line: u8) -> Self { match line { 0 => Self::NTty, _ => { todo!() } } } } pub struct TtyLdiscManager; impl TtyLdiscManager { /// ## 为tty初始化ldisc /// /// ### 参数 /// - tty:需要设置的tty /// - o_tty: other tty 用于pty pair pub fn ldisc_setup(tty: Arc, o_tty: Option>) -> Result<(), SystemError> { let ld = tty.ldisc(); let ret = ld.open(tty); if let Err(err) = ret { if err == SystemError::ENOSYS { return Err(err); } } // 处理PTY if let Some(o_tty) = o_tty { let ld = o_tty.ldisc(); let ret: Result<(), SystemError> = ld.open(o_tty.clone()); if ret.is_err() { o_tty.core().flags_write().remove(TtyFlag::LDISC_OPEN); let _ = ld.close(o_tty.clone()); } } Ok(()) } }