tty_device.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. use core::fmt::Debug;
  2. use alloc::{
  3. string::{String, ToString},
  4. sync::{Arc, Weak},
  5. };
  6. use system_error::SystemError;
  7. use unified_init::macros::unified_init;
  8. use crate::{
  9. arch::ipc::signal::Signal,
  10. driver::{
  11. base::{
  12. char::CharDevice,
  13. class::Class,
  14. device::{
  15. bus::Bus,
  16. device_number::{DeviceNumber, Major},
  17. device_register,
  18. driver::Driver,
  19. Device, DeviceKObjType, DeviceType, IdTable,
  20. },
  21. kobject::{KObject, LockedKObjectState},
  22. kset::KSet,
  23. },
  24. serial::serial_init,
  25. },
  26. filesystem::{
  27. devfs::{devfs_register, DevFS, DeviceINode},
  28. epoll::EPollItem,
  29. kernfs::KernFSInode,
  30. vfs::{
  31. file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata,
  32. PollableInode,
  33. },
  34. },
  35. init::initcall::INITCALL_DEVICE,
  36. libs::{
  37. rwlock::{RwLock, RwLockWriteGuard},
  38. spinlock::SpinLockGuard,
  39. },
  40. mm::VirtAddr,
  41. process::ProcessManager,
  42. syscall::user_access::{UserBufferReader, UserBufferWriter},
  43. };
  44. use super::{
  45. kthread::tty_flush_thread_init,
  46. pty::unix98pty::ptmx_open,
  47. sysfs::sys_class_tty_instance,
  48. termios::WindowSize,
  49. tty_core::{TtyCore, TtyFlag, TtyIoctlCmd},
  50. tty_driver::{TtyDriverManager, TtyDriverSubType, TtyDriverType, TtyOperation},
  51. tty_job_control::TtyJobCtrlManager,
  52. virtual_terminal::vty_init,
  53. };
  54. #[derive(Debug)]
  55. pub struct InnerTtyDevice {
  56. /// 当前设备所述的kset
  57. kset: Option<Arc<KSet>>,
  58. parent_kobj: Option<Weak<dyn KObject>>,
  59. /// 当前设备所述的总线
  60. bus: Option<Weak<dyn Bus>>,
  61. inode: Option<Arc<KernFSInode>>,
  62. driver: Option<Weak<dyn Driver>>,
  63. can_match: bool,
  64. metadata: Metadata,
  65. }
  66. impl InnerTtyDevice {
  67. pub fn new() -> Self {
  68. Self {
  69. kset: None,
  70. parent_kobj: None,
  71. bus: None,
  72. inode: None,
  73. driver: None,
  74. can_match: false,
  75. metadata: Metadata::new(FileType::CharDevice, ModeType::from_bits_truncate(0o755)),
  76. }
  77. }
  78. pub fn metadata_mut(&mut self) -> &mut Metadata {
  79. &mut self.metadata
  80. }
  81. }
  82. #[derive(Debug, PartialEq)]
  83. pub enum TtyType {
  84. Tty,
  85. Pty(PtyType),
  86. }
  87. #[derive(Debug, PartialEq)]
  88. pub enum PtyType {
  89. Ptm,
  90. Pts,
  91. }
  92. #[cast_to([sync] Device)]
  93. pub struct TtyDevice {
  94. name: String,
  95. id_table: IdTable,
  96. tty_type: TtyType,
  97. inner: RwLock<InnerTtyDevice>,
  98. kobj_state: LockedKObjectState,
  99. /// TTY所属的文件系统
  100. fs: RwLock<Weak<DevFS>>,
  101. }
  102. impl TtyDevice {
  103. pub fn new(name: String, id_table: IdTable, tty_type: TtyType) -> Arc<TtyDevice> {
  104. let dev_num = id_table.device_number();
  105. let dev = TtyDevice {
  106. name,
  107. id_table,
  108. inner: RwLock::new(InnerTtyDevice::new()),
  109. kobj_state: LockedKObjectState::new(None),
  110. fs: RwLock::new(Weak::default()),
  111. tty_type,
  112. };
  113. dev.inner.write().metadata.raw_dev = dev_num;
  114. Arc::new(dev)
  115. }
  116. pub fn inner_write(&self) -> RwLockWriteGuard<InnerTtyDevice> {
  117. self.inner.write()
  118. }
  119. pub fn name_ref(&self) -> &str {
  120. &self.name
  121. }
  122. fn tty_core(private_data: &FilePrivateData) -> Result<Arc<TtyCore>, SystemError> {
  123. let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data {
  124. (tty_priv.tty.clone(), tty_priv.mode)
  125. } else {
  126. return Err(SystemError::EIO);
  127. };
  128. Ok(tty)
  129. }
  130. }
  131. impl Debug for TtyDevice {
  132. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  133. f.debug_struct("TtyDevice")
  134. .field("name", &self.name)
  135. .finish()
  136. }
  137. }
  138. impl PollableInode for TtyDevice {
  139. fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
  140. let tty = TtyDevice::tty_core(private_data)?;
  141. tty.ldisc().poll(tty)
  142. }
  143. fn add_epitem(
  144. &self,
  145. epitem: Arc<EPollItem>,
  146. private_data: &FilePrivateData,
  147. ) -> Result<(), SystemError> {
  148. let tty = TtyDevice::tty_core(private_data)?;
  149. let core = tty.core();
  150. core.add_epitem(epitem);
  151. Ok(())
  152. }
  153. fn remove_epitem(
  154. &self,
  155. epitem: &Arc<EPollItem>,
  156. private_data: &FilePrivateData,
  157. ) -> Result<(), SystemError> {
  158. let tty = TtyDevice::tty_core(private_data)?;
  159. let core = tty.core();
  160. core.remove_epitem(epitem)
  161. }
  162. }
  163. impl IndexNode for TtyDevice {
  164. fn open(
  165. &self,
  166. mut data: SpinLockGuard<FilePrivateData>,
  167. mode: &crate::filesystem::vfs::file::FileMode,
  168. ) -> Result<(), SystemError> {
  169. if let FilePrivateData::Tty(_) = &*data {
  170. return Ok(());
  171. }
  172. if self.tty_type == TtyType::Pty(PtyType::Ptm) {
  173. return ptmx_open(data, mode);
  174. }
  175. let dev_num = self.metadata()?.raw_dev;
  176. let (index, driver) =
  177. TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
  178. let tty = driver.open_tty(Some(index))?;
  179. // 设置privdata
  180. *data = FilePrivateData::Tty(TtyFilePrivateData {
  181. tty: tty.clone(),
  182. mode: *mode,
  183. });
  184. let ret = tty.open(tty.core());
  185. if let Err(err) = ret {
  186. if err == SystemError::ENOSYS {
  187. return Err(SystemError::ENODEV);
  188. }
  189. return Err(err);
  190. }
  191. let driver = tty.core().driver();
  192. // 考虑noctty(当前tty)
  193. if !(mode.contains(FileMode::O_NOCTTY) && dev_num == DeviceNumber::new(Major::TTY_MAJOR, 0)
  194. || dev_num == DeviceNumber::new(Major::TTYAUX_MAJOR, 1)
  195. || (driver.tty_driver_type() == TtyDriverType::Pty
  196. && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster))
  197. {
  198. let pcb = ProcessManager::current_pcb();
  199. let pcb_tty = pcb.sig_info_irqsave().tty();
  200. if pcb_tty.is_none() && tty.core().contorl_info_irqsave().session.is_none() {
  201. TtyJobCtrlManager::proc_set_tty(tty);
  202. }
  203. }
  204. Ok(())
  205. }
  206. fn read_at(
  207. &self,
  208. _offset: usize,
  209. len: usize,
  210. buf: &mut [u8],
  211. data: SpinLockGuard<FilePrivateData>,
  212. ) -> Result<usize, system_error::SystemError> {
  213. let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
  214. (tty_priv.tty(), tty_priv.mode)
  215. } else {
  216. return Err(SystemError::EIO);
  217. };
  218. drop(data);
  219. let ld = tty.ldisc();
  220. let mut offset = 0;
  221. let mut cookie = false;
  222. loop {
  223. let mut size = if len > buf.len() { buf.len() } else { len };
  224. size = ld.read(tty.clone(), buf, size, &mut cookie, offset, mode)?;
  225. // 没有更多数据
  226. if size == 0 {
  227. break;
  228. }
  229. offset += size;
  230. // 缓冲区写满
  231. if offset >= len {
  232. break;
  233. }
  234. // 没有更多数据
  235. if !cookie {
  236. break;
  237. }
  238. }
  239. return Ok(offset);
  240. }
  241. fn write_at(
  242. &self,
  243. _offset: usize,
  244. len: usize,
  245. buf: &[u8],
  246. data: SpinLockGuard<FilePrivateData>,
  247. ) -> Result<usize, system_error::SystemError> {
  248. let mut count = len;
  249. let (tty, mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
  250. (tty_priv.tty(), tty_priv.mode)
  251. } else {
  252. return Err(SystemError::EIO);
  253. };
  254. drop(data);
  255. let ld = tty.ldisc();
  256. let core = tty.core();
  257. let mut chunk = 2048;
  258. if core.flags().contains(TtyFlag::NO_WRITE_SPLIT) {
  259. chunk = 65536;
  260. }
  261. chunk = chunk.min(count);
  262. let pcb = ProcessManager::current_pcb();
  263. let mut written = 0;
  264. loop {
  265. // 至少需要写多少
  266. let size = chunk.min(count);
  267. // 将数据从buf拷贝到writebuf
  268. let ret = ld.write(tty.clone(), &buf[written..], size, mode)?;
  269. written += ret;
  270. count -= ret;
  271. if count == 0 {
  272. break;
  273. }
  274. if pcb.has_pending_signal_fast() {
  275. return Err(SystemError::ERESTARTSYS);
  276. }
  277. }
  278. if written > 0 {
  279. // todo: 更新时间
  280. }
  281. Ok(written)
  282. }
  283. fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> {
  284. todo!()
  285. }
  286. fn as_any_ref(&self) -> &dyn core::any::Any {
  287. self
  288. }
  289. fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
  290. todo!()
  291. }
  292. fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
  293. Ok(self.inner.read().metadata.clone())
  294. }
  295. fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
  296. let mut guard = self.inner_write();
  297. guard.metadata = metadata.clone();
  298. Ok(())
  299. }
  300. fn close(&self, data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
  301. let (tty, _mode) = if let FilePrivateData::Tty(tty_priv) = &*data {
  302. (tty_priv.tty(), tty_priv.mode)
  303. } else {
  304. return Err(SystemError::EIO);
  305. };
  306. drop(data);
  307. tty.close(tty.clone())
  308. }
  309. fn resize(&self, _len: usize) -> Result<(), SystemError> {
  310. Ok(())
  311. }
  312. fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
  313. let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
  314. (tty_priv.tty(), tty_priv.mode)
  315. } else {
  316. return Err(SystemError::EIO);
  317. };
  318. match cmd {
  319. TtyIoctlCmd::TIOCSETD
  320. | TtyIoctlCmd::TIOCSBRK
  321. | TtyIoctlCmd::TIOCCBRK
  322. | TtyIoctlCmd::TCSBRK
  323. | TtyIoctlCmd::TCSBRKP => {
  324. TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?;
  325. if cmd != TtyIoctlCmd::TIOCCBRK {
  326. todo!()
  327. }
  328. }
  329. _ => {}
  330. }
  331. match cmd {
  332. TtyIoctlCmd::TIOCGWINSZ => {
  333. let core = tty.core();
  334. let winsize = *core.window_size();
  335. let mut user_writer = UserBufferWriter::new(
  336. VirtAddr::new(arg).as_ptr::<WindowSize>(),
  337. core::mem::size_of::<WindowSize>(),
  338. true,
  339. )?;
  340. let err = user_writer.copy_one_to_user(&winsize, 0);
  341. if err.is_err() {
  342. return Err(SystemError::EFAULT);
  343. }
  344. return Ok(0);
  345. }
  346. TtyIoctlCmd::TIOCSWINSZ => {
  347. let reader = UserBufferReader::new(
  348. arg as *const (),
  349. core::mem::size_of::<WindowSize>(),
  350. true,
  351. )?;
  352. let user_winsize = reader.read_one_from_user::<WindowSize>(0)?;
  353. let ret = tty.resize(tty.clone(), *user_winsize);
  354. if ret != Err(SystemError::ENOSYS) {
  355. return ret.map(|_| 0);
  356. } else {
  357. return tty.tty_do_resize(*user_winsize).map(|_| 0);
  358. }
  359. }
  360. _ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) {
  361. Ok(_) => {
  362. return Ok(0);
  363. }
  364. Err(e) => {
  365. if e != SystemError::ENOIOCTLCMD {
  366. return Err(e);
  367. }
  368. }
  369. },
  370. }
  371. match tty.ioctl(tty.clone(), cmd, arg) {
  372. Ok(_) => {
  373. return Ok(0);
  374. }
  375. Err(e) => {
  376. if e != SystemError::ENOIOCTLCMD {
  377. return Err(e);
  378. }
  379. }
  380. }
  381. tty.ldisc().ioctl(tty, cmd, arg)?;
  382. Ok(0)
  383. }
  384. fn as_pollable_inode(&self) -> Result<&dyn PollableInode, SystemError> {
  385. Ok(self)
  386. }
  387. }
  388. impl DeviceINode for TtyDevice {
  389. fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) {
  390. *self.fs.write() = fs;
  391. }
  392. }
  393. impl KObject for TtyDevice {
  394. fn as_any_ref(&self) -> &dyn core::any::Any {
  395. self
  396. }
  397. fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
  398. self.inner.write().inode = inode;
  399. }
  400. fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
  401. self.inner.read().inode.clone()
  402. }
  403. fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
  404. self.inner.read().parent_kobj.clone()
  405. }
  406. fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
  407. self.inner.write().parent_kobj = parent
  408. }
  409. fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
  410. self.inner.read().kset.clone()
  411. }
  412. fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) {
  413. self.inner.write().kset = kset
  414. }
  415. fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
  416. Some(&DeviceKObjType)
  417. }
  418. fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {}
  419. fn name(&self) -> alloc::string::String {
  420. self.name.to_string()
  421. }
  422. fn set_name(&self, _name: alloc::string::String) {
  423. // self.name = name
  424. }
  425. fn kobj_state(
  426. &self,
  427. ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
  428. self.kobj_state.read()
  429. }
  430. fn kobj_state_mut(
  431. &self,
  432. ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
  433. self.kobj_state.write()
  434. }
  435. fn set_kobj_state(&self, state: crate::driver::base::kobject::KObjectState) {
  436. *self.kobj_state.write() = state
  437. }
  438. }
  439. impl Device for TtyDevice {
  440. fn dev_type(&self) -> crate::driver::base::device::DeviceType {
  441. DeviceType::Char
  442. }
  443. fn id_table(&self) -> crate::driver::base::device::IdTable {
  444. self.id_table.clone()
  445. }
  446. fn bus(&self) -> Option<Weak<dyn Bus>> {
  447. self.inner.read().bus.clone()
  448. }
  449. fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>) {
  450. self.inner.write().bus = bus
  451. }
  452. fn set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>) {
  453. // do nothing
  454. }
  455. fn class(&self) -> Option<Arc<dyn Class>> {
  456. sys_class_tty_instance()
  457. .cloned()
  458. .map(|x| x as Arc<dyn Class>)
  459. }
  460. fn driver(&self) -> Option<Arc<dyn crate::driver::base::device::driver::Driver>> {
  461. self.inner.read().driver.clone()?.upgrade()
  462. }
  463. fn set_driver(
  464. &self,
  465. driver: Option<alloc::sync::Weak<dyn crate::driver::base::device::driver::Driver>>,
  466. ) {
  467. self.inner.write().driver = driver
  468. }
  469. fn is_dead(&self) -> bool {
  470. false
  471. }
  472. fn can_match(&self) -> bool {
  473. self.inner.read().can_match
  474. }
  475. fn set_can_match(&self, can_match: bool) {
  476. self.inner.write().can_match = can_match
  477. }
  478. fn state_synced(&self) -> bool {
  479. true
  480. }
  481. fn dev_parent(&self) -> Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>> {
  482. None
  483. }
  484. fn set_dev_parent(
  485. &self,
  486. _dev_parent: Option<alloc::sync::Weak<dyn crate::driver::base::device::Device>>,
  487. ) {
  488. todo!()
  489. }
  490. }
  491. impl CharDevice for TtyDevice {
  492. fn read(&self, _len: usize, _buf: &mut [u8]) -> Result<usize, SystemError> {
  493. todo!()
  494. }
  495. fn write(&self, _len: usize, _buf: &[u8]) -> Result<usize, SystemError> {
  496. todo!()
  497. }
  498. fn sync(&self) -> Result<(), SystemError> {
  499. todo!()
  500. }
  501. }
  502. #[derive(Debug, Clone)]
  503. pub struct TtyFilePrivateData {
  504. pub tty: Arc<TtyCore>,
  505. pub mode: FileMode,
  506. }
  507. impl TtyFilePrivateData {
  508. pub fn tty(&self) -> Arc<TtyCore> {
  509. self.tty.clone()
  510. }
  511. }
  512. /// 初始化tty设备和console子设备
  513. #[unified_init(INITCALL_DEVICE)]
  514. #[inline(never)]
  515. pub fn tty_init() -> Result<(), SystemError> {
  516. let console = TtyDevice::new(
  517. "console".to_string(),
  518. IdTable::new(
  519. String::from("console"),
  520. Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 1)),
  521. ),
  522. TtyType::Tty,
  523. );
  524. // 将设备注册到devfs,TODO:这里console设备应该与tty在一个设备group里面
  525. device_register(console.clone())?;
  526. devfs_register(&console.name.clone(), console)?;
  527. serial_init()?;
  528. tty_flush_thread_init();
  529. return vty_init();
  530. }