1 use core::fmt::Debug; 2 3 use alloc::sync::Arc; 4 use system_error::SystemError; 5 6 use crate::filesystem::vfs::file::FileMode; 7 8 use super::{ 9 termios::Termios, 10 tty_core::{TtyCore, TtyCoreData, TtyFlag}, 11 }; 12 13 pub mod ntty; 14 15 pub trait TtyLineDiscipline: Sync + Send + Debug { 16 fn open(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>; 17 fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>; 18 fn flush_buffer(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>; 19 20 /// ## tty行规程循环读取函数 21 /// 22 /// ### 参数 23 /// - tty: 操作的tty 24 /// - buf: 数据将被读取到buf 25 /// - len: 读取的字节长度 26 /// - cookie: 表示是否是继续上次的读,第一次读取应该传入false 27 /// - offset: 读取的偏移量 28 fn read( 29 &self, 30 tty: Arc<TtyCore>, 31 buf: &mut [u8], 32 len: usize, 33 cookie: &mut bool, 34 offset: usize, 35 mode: FileMode, 36 ) -> Result<usize, SystemError>; 37 fn write( 38 &self, 39 tty: Arc<TtyCore>, 40 buf: &[u8], 41 len: usize, 42 mode: FileMode, 43 ) -> Result<usize, SystemError>; 44 fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError>; 45 46 /// ### 设置termios后更新行规程状态 47 /// 48 /// - old: 之前的termios,如果为None则表示第一次设置 49 fn set_termios(&self, tty: Arc<TtyCore>, old: Option<Termios>) -> Result<(), SystemError>; 50 51 fn poll(&self, tty: Arc<TtyCore>) -> Result<usize, SystemError>; 52 fn hangup(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>; 53 54 /// ## 接收数据 55 fn receive_buf( 56 &self, 57 tty: Arc<TtyCore>, 58 buf: &[u8], 59 flags: Option<&[u8]>, 60 count: usize, 61 ) -> Result<usize, SystemError>; 62 63 /// ## 接收数据 64 fn receive_buf2( 65 &self, 66 tty: Arc<TtyCore>, 67 buf: &[u8], 68 flags: Option<&[u8]>, 69 count: usize, 70 ) -> Result<usize, SystemError>; 71 72 /// ## 唤醒线路写者 73 fn write_wakeup(&self, _tty: &TtyCoreData) -> Result<(), SystemError> { 74 Err(SystemError::ENOSYS) 75 } 76 } 77 78 #[derive(Debug, Clone, Copy)] 79 pub enum LineDisciplineType { 80 NTty = 0, 81 } 82 83 impl LineDisciplineType { 84 pub fn from_line(line: u8) -> Self { 85 match line { 86 0 => Self::NTty, 87 _ => { 88 todo!() 89 } 90 } 91 } 92 } 93 94 pub struct TtyLdiscManager; 95 96 impl TtyLdiscManager { 97 /// ## 为tty初始化ldisc 98 /// 99 /// ### 参数 100 /// - tty:需要设置的tty 101 /// - o_tty: other tty 用于pty pair 102 pub fn ldisc_setup(tty: Arc<TtyCore>, o_tty: Option<Arc<TtyCore>>) -> Result<(), SystemError> { 103 let ld = tty.ldisc(); 104 105 let ret = ld.open(tty); 106 if let Err(err) = ret { 107 if err == SystemError::ENOSYS { 108 return Err(err); 109 } 110 } 111 112 // 处理PTY 113 if let Some(o_tty) = o_tty { 114 let ld = o_tty.ldisc(); 115 116 let ret: Result<(), SystemError> = ld.open(o_tty.clone()); 117 if ret.is_err() { 118 o_tty.core().flags_write().remove(TtyFlag::LDISC_OPEN); 119 let _ = ld.close(o_tty.clone()); 120 } 121 } 122 123 Ok(()) 124 } 125 } 126