unix98pty.rs 8.9 KB

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