1 use alloc::{string::ToString, sync::Arc}; 2 use system_error::SystemError; 3 4 use crate::{ 5 driver::tty::{ 6 termios::Termios, 7 tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus}, 8 tty_device::TtyFilePrivateData, 9 tty_driver::{TtyDriver, TtyDriverPrivateData, TtyDriverSubType, TtyOperation}, 10 }, 11 filesystem::{ 12 devpts::DevPtsFs, 13 vfs::{ 14 file::FileMode, syscall::ModeType, FilePrivateData, FileType, MountFS, ROOT_INODE, 15 VFS_MAX_FOLLOW_SYMLINK_TIMES, 16 }, 17 }, 18 libs::spinlock::SpinLockGuard, 19 mm::VirtAddr, 20 net::event_poll::EPollEventType, 21 syscall::user_access::UserBufferWriter, 22 }; 23 24 use super::{ptm_driver, pts_driver, PtyCommon}; 25 26 pub const NR_UNIX98_PTY_MAX: u32 = 128; 27 28 #[derive(Debug)] 29 pub struct Unix98PtyDriverInner; 30 31 impl Unix98PtyDriverInner { 32 pub fn new() -> Self { 33 Self 34 } 35 } 36 37 impl TtyOperation for Unix98PtyDriverInner { 38 fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> { 39 PtyCommon::pty_common_install(driver, tty, false) 40 } 41 42 fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> { 43 PtyCommon::pty_common_open(tty) 44 } 45 46 fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> { 47 let to = tty.checked_link()?; 48 49 if nr == 0 || tty.flow_irqsave().stopped { 50 return Ok(0); 51 } 52 53 to.core().port().unwrap().receive_buf(buf, &[], nr) 54 } 55 56 fn write_room(&self, tty: &TtyCoreData) -> usize { 57 // TODO 暂时 58 if tty.flow_irqsave().stopped { 59 return 0; 60 } 61 62 8192 63 } 64 65 fn flush_buffer(&self, tty: &TtyCoreData) -> Result<(), SystemError> { 66 let to = tty.checked_link()?; 67 68 let mut ctrl = to.core().contorl_info_irqsave(); 69 ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_FLUSHWRITE); 70 71 to.core().read_wq().wakeup_all(); 72 73 Ok(()) 74 } 75 76 fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> { 77 let core = tty.core(); 78 if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtyMaster { 79 return Err(SystemError::ENOSYS); 80 } 81 82 match cmd { 83 TtyIoctlCmd::TIOCSPTLCK => { 84 return PtyCommon::pty_set_lock(core, VirtAddr::new(arg)); 85 } 86 TtyIoctlCmd::TIOCGPTLCK => { 87 return PtyCommon::pty_get_lock(core, VirtAddr::new(arg)); 88 } 89 TtyIoctlCmd::TIOCPKT => { 90 return PtyCommon::pty_set_packet_mode(core, VirtAddr::new(arg)); 91 } 92 TtyIoctlCmd::TIOCGPKT => { 93 return PtyCommon::pty_get_packet_mode(core, VirtAddr::new(arg)); 94 } 95 TtyIoctlCmd::TIOCGPTN => { 96 let mut user_writer = 97 UserBufferWriter::new(arg as *mut u32, core::mem::size_of::<u32>(), true)?; 98 99 return user_writer.copy_one_to_user(&(core.index() as u32), 0); 100 } 101 _ => { 102 return Err(SystemError::ENOIOCTLCMD); 103 } 104 } 105 } 106 107 fn set_termios(&self, tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> { 108 let core = tty.core(); 109 if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave { 110 return Err(SystemError::ENOSYS); 111 } 112 todo!() 113 } 114 115 fn start(&self, core: &TtyCoreData) -> Result<(), SystemError> { 116 if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave { 117 return Err(SystemError::ENOSYS); 118 } 119 120 let link = core.checked_link()?; 121 122 let mut ctrl = core.contorl_info_irqsave(); 123 ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_STOP); 124 ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_START); 125 126 link.core() 127 .read_wq() 128 .wakeup_any(EPollEventType::EPOLLIN.bits() as u64); 129 130 Ok(()) 131 } 132 133 fn stop(&self, core: &TtyCoreData) -> Result<(), SystemError> { 134 if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave { 135 return Err(SystemError::ENOSYS); 136 } 137 138 let link = core.checked_link()?; 139 140 let mut ctrl = core.contorl_info_irqsave(); 141 ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_START); 142 ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_STOP); 143 144 link.core() 145 .read_wq() 146 .wakeup_any(EPollEventType::EPOLLIN.bits() as u64); 147 148 Ok(()) 149 } 150 151 fn flush_chars(&self, _tty: &TtyCoreData) { 152 // 不做处理 153 } 154 155 fn lookup( 156 &self, 157 index: usize, 158 priv_data: TtyDriverPrivateData, 159 ) -> Result<Arc<TtyCore>, SystemError> { 160 if let TtyDriverPrivateData::Pty(false) = priv_data { 161 return pts_driver() 162 .ttys() 163 .get(&index) 164 .cloned() 165 .ok_or(SystemError::ENODEV); 166 } 167 168 return Err(SystemError::ENOSYS); 169 } 170 171 fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> { 172 let driver = tty.core().driver(); 173 174 driver.ttys().remove(&tty.core().index()); 175 if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave { 176 let pts_root_inode = 177 ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 178 let _ = pts_root_inode.unlink(&tty.core().index().to_string()); 179 } 180 181 Ok(()) 182 } 183 } 184 185 pub fn ptmx_open( 186 mut data: SpinLockGuard<FilePrivateData>, 187 mode: &FileMode, 188 ) -> Result<(), SystemError> { 189 let pts_root_inode = 190 ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 191 192 let fs = pts_root_inode 193 .fs() 194 .as_any_ref() 195 .downcast_ref::<MountFS>() 196 .unwrap() 197 .inner_filesystem(); 198 let fsinfo = fs.as_any_ref().downcast_ref::<DevPtsFs>().unwrap(); 199 200 let index = fsinfo.alloc_index()?; 201 202 let tty = TtyDriver::init_tty_device(ptm_driver(), index)?; 203 204 // 设置privdata 205 *data = FilePrivateData::Tty(TtyFilePrivateData { 206 tty: tty.clone(), 207 mode: *mode, 208 }); 209 210 let core = tty.core(); 211 core.flags_write().insert(TtyFlag::PTY_LOCK); 212 213 let _ = pts_root_inode.create( 214 &index.to_string(), 215 FileType::CharDevice, 216 ModeType::from_bits_truncate(0x666), 217 )?; 218 219 ptm_driver().driver_funcs().open(core)?; 220 221 Ok(()) 222 } 223