tty_core.rs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. use core::{
  2. fmt::Debug,
  3. sync::atomic::{AtomicBool, AtomicUsize, Ordering},
  4. };
  5. use alloc::{
  6. collections::LinkedList,
  7. string::String,
  8. sync::{Arc, Weak},
  9. };
  10. use system_error::SystemError;
  11. use crate::{
  12. driver::{base::device::device_number::DeviceNumber, tty::pty::ptm_driver},
  13. libs::{
  14. rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
  15. spinlock::{SpinLock, SpinLockGuard},
  16. wait_queue::EventWaitQueue,
  17. },
  18. mm::VirtAddr,
  19. net::event_poll::{EPollEventType, EPollItem},
  20. process::{process_group::Pgid, session::Sid, ProcessControlBlock},
  21. syscall::user_access::{UserBufferReader, UserBufferWriter},
  22. };
  23. use super::{
  24. termios::{ControlMode, PosixTermios, Termios, TtySetTermiosOpt, WindowSize},
  25. tty_driver::{TtyCorePrivateField, TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation},
  26. tty_ldisc::{
  27. ntty::{NTtyData, NTtyLinediscipline},
  28. TtyLineDiscipline,
  29. },
  30. tty_port::TtyPort,
  31. virtual_terminal::{vc_manager, virtual_console::VirtualConsoleData, DrawRegion},
  32. };
  33. #[derive(Debug)]
  34. pub struct TtyCore {
  35. core: TtyCoreData,
  36. /// 线路规程函数集
  37. line_discipline: Arc<dyn TtyLineDiscipline>,
  38. }
  39. impl Drop for TtyCore {
  40. fn drop(&mut self) {
  41. if self.core.driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave {
  42. ptm_driver().ttys().remove(&self.core().index);
  43. }
  44. }
  45. }
  46. impl TtyCore {
  47. #[inline(never)]
  48. pub fn new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self> {
  49. let name = driver.tty_line_name(index);
  50. let device_number = driver
  51. .device_number(index)
  52. .expect("Get tty device number failed.");
  53. let termios = driver.init_termios();
  54. let core = TtyCoreData {
  55. tty_driver: driver,
  56. termios: RwLock::new(termios),
  57. name,
  58. flags: RwLock::new(TtyFlag::empty()),
  59. count: AtomicUsize::new(0),
  60. window_size: RwLock::new(WindowSize::default()),
  61. read_wq: EventWaitQueue::new(),
  62. write_wq: EventWaitQueue::new(),
  63. port: RwLock::new(None),
  64. index,
  65. vc_index: AtomicUsize::new(usize::MAX),
  66. ctrl: SpinLock::new(TtyContorlInfo::default()),
  67. closing: AtomicBool::new(false),
  68. flow: SpinLock::new(TtyFlowState::default()),
  69. link: RwLock::default(),
  70. epitems: SpinLock::new(LinkedList::new()),
  71. device_number,
  72. privete_fields: SpinLock::new(None),
  73. };
  74. return Arc::new(Self {
  75. core,
  76. line_discipline: Arc::new(NTtyLinediscipline {
  77. data: SpinLock::new(NTtyData::new()),
  78. }),
  79. });
  80. }
  81. #[inline]
  82. pub fn core(&self) -> &TtyCoreData {
  83. return &self.core;
  84. }
  85. pub fn private_fields(&self) -> Option<Arc<dyn TtyCorePrivateField>> {
  86. self.core.privete_fields.lock().clone()
  87. }
  88. pub fn set_private_fields(&self, fields: Arc<dyn TtyCorePrivateField>) {
  89. *self.core.privete_fields.lock() = Some(fields);
  90. }
  91. #[inline]
  92. pub fn ldisc(&self) -> Arc<dyn TtyLineDiscipline> {
  93. self.line_discipline.clone()
  94. }
  95. pub fn write_to_core(&self, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
  96. self.core
  97. .driver()
  98. .driver_funcs()
  99. .write(self.core(), buf, nr)
  100. }
  101. pub fn reopen(&self) -> Result<(), SystemError> {
  102. let tty_core = self.core();
  103. let driver = tty_core.driver();
  104. if driver.tty_driver_type() == TtyDriverType::Pty
  105. && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster
  106. {
  107. return Err(SystemError::EIO);
  108. }
  109. // if *tty_core.count.read() == 0 {
  110. // return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
  111. // }
  112. // TODO 判断flags
  113. tty_core.add_count();
  114. Ok(())
  115. }
  116. #[inline]
  117. pub fn set_port(&self, port: Arc<dyn TtyPort>) {
  118. *self.core.port.write() = Some(port);
  119. }
  120. pub fn tty_start(&self) {
  121. let mut flow = self.core.flow.lock_irqsave();
  122. if !flow.stopped || flow.tco_stopped {
  123. return;
  124. }
  125. flow.stopped = false;
  126. let _ = self.start(self.core());
  127. self.tty_wakeup();
  128. }
  129. pub fn tty_stop(&self) {
  130. let mut flow = self.core.flow.lock_irqsave();
  131. if flow.stopped {
  132. return;
  133. }
  134. flow.stopped = true;
  135. let _ = self.stop(self.core());
  136. }
  137. pub fn tty_wakeup(&self) {
  138. if self.core.flags().contains(TtyFlag::DO_WRITE_WAKEUP) {
  139. let _ = self.ldisc().write_wakeup(self.core());
  140. }
  141. self.core()
  142. .write_wq
  143. .wakeup_any(EPollEventType::EPOLLOUT.bits() as u64);
  144. }
  145. pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
  146. let core = tty.core();
  147. let real_tty = if core.driver().tty_driver_type() == TtyDriverType::Pty
  148. && core.driver().tty_driver_sub_type() == TtyDriverSubType::PtyMaster
  149. {
  150. core.link().unwrap()
  151. } else {
  152. tty
  153. };
  154. match cmd {
  155. TtyIoctlCmd::TCGETS => {
  156. let termios = PosixTermios::from_kernel_termios(*real_tty.core.termios());
  157. let mut user_writer = UserBufferWriter::new(
  158. VirtAddr::new(arg).as_ptr::<PosixTermios>(),
  159. core::mem::size_of::<PosixTermios>(),
  160. true,
  161. )?;
  162. user_writer.copy_one_to_user(&termios, 0)?;
  163. return Ok(0);
  164. }
  165. TtyIoctlCmd::TCSETS => {
  166. return TtyCore::core_set_termios(
  167. real_tty,
  168. VirtAddr::new(arg),
  169. TtySetTermiosOpt::TERMIOS_OLD,
  170. );
  171. }
  172. TtyIoctlCmd::TCSETSW => {
  173. return TtyCore::core_set_termios(
  174. real_tty,
  175. VirtAddr::new(arg),
  176. TtySetTermiosOpt::TERMIOS_WAIT | TtySetTermiosOpt::TERMIOS_OLD,
  177. );
  178. }
  179. _ => {
  180. return Err(SystemError::ENOIOCTLCMD);
  181. }
  182. }
  183. }
  184. pub fn core_set_termios(
  185. tty: Arc<TtyCore>,
  186. arg: VirtAddr,
  187. opt: TtySetTermiosOpt,
  188. ) -> Result<usize, SystemError> {
  189. #[allow(unused_assignments)]
  190. // TERMIOS_TERMIO下会用到
  191. let mut tmp_termios = *tty.core().termios();
  192. if opt.contains(TtySetTermiosOpt::TERMIOS_TERMIO) {
  193. todo!()
  194. } else {
  195. let user_reader = UserBufferReader::new(
  196. arg.as_ptr::<PosixTermios>(),
  197. core::mem::size_of::<PosixTermios>(),
  198. true,
  199. )?;
  200. let mut term = PosixTermios::default();
  201. user_reader.copy_one_from_user(&mut term, 0)?;
  202. tmp_termios = term.to_kernel_termios();
  203. }
  204. if opt.contains(TtySetTermiosOpt::TERMIOS_FLUSH) {
  205. let ld = tty.ldisc();
  206. let _ = ld.flush_buffer(tty.clone());
  207. }
  208. if opt.contains(TtySetTermiosOpt::TERMIOS_WAIT) {
  209. // TODO
  210. }
  211. TtyCore::set_termios_next(tty, tmp_termios)?;
  212. Ok(0)
  213. }
  214. fn set_termios_next(tty: Arc<TtyCore>, new_termios: Termios) -> Result<(), SystemError> {
  215. let mut termios = tty.core().termios_write();
  216. let old_termios = *termios;
  217. *termios = new_termios;
  218. let tmp = termios.control_mode;
  219. termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
  220. drop(termios);
  221. let ret = tty.set_termios(tty.clone(), old_termios);
  222. let mut termios = tty.core().termios_write();
  223. if ret.is_err() {
  224. termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL;
  225. termios.control_mode |= old_termios.control_mode
  226. & !(ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL);
  227. termios.input_speed = old_termios.input_speed;
  228. termios.output_speed = old_termios.output_speed;
  229. }
  230. drop(termios);
  231. let ld = tty.ldisc();
  232. ld.set_termios(tty, Some(old_termios)).ok();
  233. Ok(())
  234. }
  235. pub fn tty_do_resize(&self, windowsize: WindowSize) -> Result<(), SystemError> {
  236. // TODO: 向前台进程发送信号
  237. *self.core.window_size_write() = windowsize;
  238. Ok(())
  239. }
  240. }
  241. #[derive(Debug, Default)]
  242. pub struct TtyContorlInfo {
  243. /// 当前会话的SId
  244. pub session: Option<Sid>,
  245. /// 前台进程组id
  246. pub pgid: Option<Pgid>,
  247. /// packet模式下使用,目前未用到
  248. pub pktstatus: TtyPacketStatus,
  249. pub packet: bool,
  250. }
  251. impl TtyContorlInfo {
  252. pub fn set_info_by_pcb(&mut self, pcb: Arc<ProcessControlBlock>) {
  253. self.session = Some(pcb.sid());
  254. self.pgid = Some(pcb.pgid());
  255. }
  256. }
  257. #[derive(Debug, Default)]
  258. pub struct TtyFlowState {
  259. /// 表示流控是否被停止
  260. pub stopped: bool,
  261. /// 表示 TCO(Transmit Continuous Operation)流控是否被停止
  262. pub tco_stopped: bool,
  263. }
  264. #[derive(Debug)]
  265. pub struct TtyCoreData {
  266. tty_driver: Arc<TtyDriver>,
  267. termios: RwLock<Termios>,
  268. name: String,
  269. flags: RwLock<TtyFlag>,
  270. /// 在初始化时即确定不会更改,所以这里不用加锁
  271. index: usize,
  272. vc_index: AtomicUsize,
  273. count: AtomicUsize,
  274. /// 窗口大小
  275. window_size: RwLock<WindowSize>,
  276. /// 读等待队列
  277. read_wq: EventWaitQueue,
  278. /// 写等待队列
  279. write_wq: EventWaitQueue,
  280. /// 端口
  281. port: RwLock<Option<Arc<dyn TtyPort>>>,
  282. /// 前台进程
  283. ctrl: SpinLock<TtyContorlInfo>,
  284. /// 是否正在关闭
  285. closing: AtomicBool,
  286. /// 流控状态
  287. flow: SpinLock<TtyFlowState>,
  288. /// 链接tty
  289. link: RwLock<Weak<TtyCore>>,
  290. /// epitems
  291. epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
  292. /// 设备号
  293. device_number: DeviceNumber,
  294. privete_fields: SpinLock<Option<Arc<dyn TtyCorePrivateField>>>,
  295. }
  296. impl TtyCoreData {
  297. #[inline]
  298. pub fn driver(&self) -> &Arc<TtyDriver> {
  299. &self.tty_driver
  300. }
  301. #[inline]
  302. pub fn flow_irqsave(&self) -> SpinLockGuard<TtyFlowState> {
  303. self.flow.lock_irqsave()
  304. }
  305. #[inline]
  306. pub fn port(&self) -> Option<Arc<dyn TtyPort>> {
  307. self.port.read().clone()
  308. }
  309. #[inline]
  310. pub fn index(&self) -> usize {
  311. self.index
  312. }
  313. #[inline]
  314. pub fn name(&self) -> &String {
  315. &self.name
  316. }
  317. pub fn device_number(&self) -> &DeviceNumber {
  318. &self.device_number
  319. }
  320. #[inline]
  321. pub fn flags(&self) -> TtyFlag {
  322. *self.flags.read_irqsave()
  323. }
  324. #[inline]
  325. pub fn flags_write(&self) -> RwLockWriteGuard<'_, TtyFlag> {
  326. self.flags.write_irqsave()
  327. }
  328. #[inline]
  329. pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
  330. self.termios.read_irqsave()
  331. }
  332. #[inline]
  333. pub fn termios_write(&self) -> RwLockWriteGuard<Termios> {
  334. self.termios.write_irqsave()
  335. }
  336. #[inline]
  337. pub fn set_termios(&self, termios: Termios) {
  338. let mut termios_guard = self.termios_write();
  339. *termios_guard = termios;
  340. }
  341. #[inline]
  342. pub fn count(&self) -> usize {
  343. self.count.load(Ordering::SeqCst)
  344. }
  345. #[inline]
  346. pub fn add_count(&self) {
  347. self.count
  348. .fetch_add(1, core::sync::atomic::Ordering::SeqCst);
  349. }
  350. #[inline]
  351. pub fn read_wq(&self) -> &EventWaitQueue {
  352. &self.read_wq
  353. }
  354. #[inline]
  355. pub fn write_wq(&self) -> &EventWaitQueue {
  356. &self.write_wq
  357. }
  358. #[inline]
  359. pub fn contorl_info_irqsave(&self) -> SpinLockGuard<TtyContorlInfo> {
  360. self.ctrl.lock_irqsave()
  361. }
  362. #[inline]
  363. pub fn window_size_upgradeable(&self) -> RwLockUpgradableGuard<WindowSize> {
  364. self.window_size.upgradeable_read()
  365. }
  366. #[inline]
  367. pub fn window_size(&self) -> RwLockReadGuard<WindowSize> {
  368. self.window_size.read()
  369. }
  370. #[inline]
  371. pub fn window_size_write(&self) -> RwLockWriteGuard<WindowSize> {
  372. self.window_size.write()
  373. }
  374. #[inline]
  375. pub fn is_closing(&self) -> bool {
  376. self.closing.load(core::sync::atomic::Ordering::SeqCst)
  377. }
  378. #[inline]
  379. pub fn vc_data(&self) -> Option<Arc<SpinLock<VirtualConsoleData>>> {
  380. vc_manager().get(self.vc_index()?).unwrap().vc_data()
  381. }
  382. pub fn set_vc_index(&self, index: usize) {
  383. self.vc_index.store(index, Ordering::SeqCst);
  384. }
  385. pub fn vc_index(&self) -> Option<usize> {
  386. let x = self.vc_index.load(Ordering::SeqCst);
  387. if x == usize::MAX {
  388. return None;
  389. }
  390. return Some(x);
  391. }
  392. #[inline]
  393. pub fn link(&self) -> Option<Arc<TtyCore>> {
  394. self.link.read().upgrade()
  395. }
  396. pub fn checked_link(&self) -> Result<Arc<TtyCore>, SystemError> {
  397. if let Some(link) = self.link() {
  398. return Ok(link);
  399. }
  400. return Err(SystemError::ENODEV);
  401. }
  402. pub fn set_link(&self, link: Weak<TtyCore>) {
  403. *self.link.write() = link;
  404. }
  405. pub fn init_termios(&self) {
  406. let tty_index = self.index();
  407. let driver = self.driver();
  408. // 初始化termios
  409. if !driver
  410. .flags()
  411. .contains(super::tty_driver::TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS)
  412. {
  413. // 先查看是否有已经保存的termios
  414. if let Some(t) = driver.saved_termios().get(tty_index) {
  415. let mut termios = *t;
  416. termios.line = driver.init_termios().line;
  417. self.set_termios(termios);
  418. }
  419. }
  420. // TODO:设置termios波特率?
  421. }
  422. #[inline]
  423. pub fn add_epitem(&self, epitem: Arc<EPollItem>) {
  424. self.epitems.lock().push_back(epitem)
  425. }
  426. pub fn remove_epitem(&self, epitem: &Arc<EPollItem>) -> Result<(), SystemError> {
  427. let mut guard = self.epitems.lock();
  428. let len = guard.len();
  429. guard.retain(|x| !Arc::ptr_eq(x, epitem));
  430. if len != guard.len() {
  431. return Ok(());
  432. }
  433. Err(SystemError::ENOENT)
  434. }
  435. pub fn eptiems(&self) -> &SpinLock<LinkedList<Arc<EPollItem>>> {
  436. &self.epitems
  437. }
  438. pub fn do_write(&self, buf: &[u8], mut nr: usize) -> Result<usize, SystemError> {
  439. // 关闭中断
  440. if let Some(vc_data) = self.vc_data() {
  441. let mut vc_data_guard = vc_data.lock_irqsave();
  442. let mut offset = 0;
  443. // 这个参数是用来扫描unicode字符的,但是这部分目前未完成,先写着
  444. let mut rescan = false;
  445. let mut ch: u32 = 0;
  446. let mut draw = DrawRegion::default();
  447. // 首先隐藏光标再写
  448. vc_data_guard.hide_cursor();
  449. while nr != 0 {
  450. if !rescan {
  451. ch = buf[offset] as u32;
  452. offset += 1;
  453. nr -= 1;
  454. }
  455. let (tc, rescan_last) = vc_data_guard.translate(&mut ch);
  456. if tc.is_none() {
  457. // 表示未转换完成
  458. continue;
  459. }
  460. let tc = tc.unwrap();
  461. rescan = rescan_last;
  462. if vc_data_guard.is_control(tc, ch) {
  463. vc_data_guard.flush(&mut draw);
  464. vc_data_guard.do_control(ch);
  465. continue;
  466. }
  467. if !vc_data_guard.console_write_normal(tc, ch, &mut draw) {
  468. continue;
  469. }
  470. }
  471. vc_data_guard.flush(&mut draw);
  472. // TODO: notify update
  473. return Ok(offset);
  474. } else {
  475. return Ok(0);
  476. }
  477. }
  478. }
  479. impl TtyOperation for TtyCore {
  480. #[inline]
  481. fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
  482. return self.core().tty_driver.driver_funcs().open(tty);
  483. }
  484. #[inline]
  485. fn write_room(&self, tty: &TtyCoreData) -> usize {
  486. return self.core().tty_driver.driver_funcs().write_room(tty);
  487. }
  488. #[inline]
  489. fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
  490. return self.core().tty_driver.driver_funcs().write(tty, buf, nr);
  491. }
  492. #[inline]
  493. fn flush_chars(&self, tty: &TtyCoreData) {
  494. self.core().tty_driver.driver_funcs().flush_chars(tty);
  495. }
  496. #[inline]
  497. fn put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError> {
  498. return self.core().tty_driver.driver_funcs().put_char(tty, ch);
  499. }
  500. #[inline]
  501. fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
  502. return self.core().tty_driver.driver_funcs().install(driver, tty);
  503. }
  504. #[inline]
  505. fn start(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
  506. return self.core().tty_driver.driver_funcs().start(tty);
  507. }
  508. #[inline]
  509. fn stop(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
  510. return self.core().tty_driver.driver_funcs().stop(tty);
  511. }
  512. #[inline]
  513. fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
  514. return self.core().tty_driver.driver_funcs().ioctl(tty, cmd, arg);
  515. }
  516. #[inline]
  517. fn chars_in_buffer(&self) -> usize {
  518. return self.core().tty_driver.driver_funcs().chars_in_buffer();
  519. }
  520. #[inline]
  521. fn set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError> {
  522. return self
  523. .core()
  524. .tty_driver
  525. .driver_funcs()
  526. .set_termios(tty, old_termios);
  527. }
  528. fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
  529. self.core().tty_driver.driver_funcs().close(tty)
  530. }
  531. fn resize(&self, tty: Arc<TtyCore>, winsize: WindowSize) -> Result<(), SystemError> {
  532. self.core.tty_driver.driver_funcs().resize(tty, winsize)
  533. }
  534. }
  535. bitflags! {
  536. pub struct TtyFlag: u32 {
  537. /// 终端被节流
  538. const THROTTLED = 1 << 0;
  539. /// 终端输入输出错误状态
  540. const IO_ERROR = 1 << 1;
  541. /// 终端的其他一方已关闭
  542. const OTHER_CLOSED = 1 << 2;
  543. /// 终端处于独占状态
  544. const EXCLUSIVE = 1 << 3;
  545. /// 终端执行写唤醒操作
  546. const DO_WRITE_WAKEUP = 1 << 5;
  547. /// 终端线路驱动程序已打开
  548. const LDISC_OPEN = 1 << 11;
  549. /// 终端伪终端设备已锁定
  550. const PTY_LOCK = 1 << 16;
  551. /// 终端禁用写分裂操作
  552. const NO_WRITE_SPLIT = 1 << 17;
  553. /// 终端挂断(挂起)状态
  554. const HUPPED = 1 << 18;
  555. /// 终端正在挂断(挂起)
  556. const HUPPING = 1 << 19;
  557. /// 终端线路驱动程序正在更改
  558. const LDISC_CHANGING = 1 << 20;
  559. /// 终端线路驱动程序已停止
  560. const LDISC_HALTED = 1 << 22;
  561. }
  562. #[derive(Default)]
  563. pub struct TtyPacketStatus: u8 {
  564. /* Used for packet mode */
  565. const TIOCPKT_DATA = 0;
  566. const TIOCPKT_FLUSHREAD = 1;
  567. const TIOCPKT_FLUSHWRITE = 2;
  568. const TIOCPKT_STOP = 4;
  569. const TIOCPKT_START = 8;
  570. const TIOCPKT_NOSTOP = 16;
  571. const TIOCPKT_DOSTOP = 32;
  572. const TIOCPKT_IOCTL = 64;
  573. }
  574. }
  575. #[derive(Debug, PartialEq)]
  576. pub enum EchoOperation {
  577. /// 开始特殊操作。
  578. Start,
  579. /// 向后移动光标列。
  580. MoveBackCol,
  581. /// 设置规范模式下的列位置。
  582. SetCanonCol,
  583. /// 擦除制表符。
  584. EraseTab,
  585. Undefined(u8),
  586. }
  587. impl EchoOperation {
  588. pub fn from_u8(num: u8) -> EchoOperation {
  589. match num {
  590. 0xff => Self::Start,
  591. 0x80 => Self::MoveBackCol,
  592. 0x81 => Self::SetCanonCol,
  593. 0x82 => Self::EraseTab,
  594. _ => Self::Undefined(num),
  595. }
  596. }
  597. pub fn to_u8(&self) -> u8 {
  598. match *self {
  599. EchoOperation::Start => 0xff,
  600. EchoOperation::MoveBackCol => 0x80,
  601. EchoOperation::SetCanonCol => 0x81,
  602. EchoOperation::EraseTab => 0x82,
  603. EchoOperation::Undefined(num) => num,
  604. }
  605. }
  606. }
  607. pub struct TtyIoctlCmd;
  608. #[allow(dead_code)]
  609. impl TtyIoctlCmd {
  610. /// 获取终端参数
  611. pub const TCGETS: u32 = 0x5401;
  612. /// 设置终端参数
  613. pub const TCSETS: u32 = 0x5402;
  614. /// 设置终端参数并等待所有输出完成
  615. pub const TCSETSW: u32 = 0x5403;
  616. /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空
  617. pub const TCSETSF: u32 = 0x5404;
  618. /// 获取终端参数
  619. pub const TCGETA: u32 = 0x5405;
  620. /// 设置终端参数
  621. pub const TCSETA: u32 = 0x5406;
  622. /// 设置终端参数并等待所有输出完成
  623. pub const TCSETAW: u32 = 0x5407;
  624. /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空
  625. pub const TCSETAF: u32 = 0x5408;
  626. /// 发送零字节,等待所有输出完成
  627. pub const TCSBRK: u32 = 0x5409;
  628. /// 控制终端的流控
  629. pub const TCXONC: u32 = 0x540A;
  630. /// 刷新输入/输出缓冲区或者丢弃输入缓冲区
  631. pub const TCFLSH: u32 = 0x540B;
  632. /// 设置设备为独占模式
  633. pub const TIOCEXCL: u32 = 0x540C;
  634. /// 设置设备为非独占模式
  635. pub const TIOCNXCL: u32 = 0x540D;
  636. /// 设置当前进程的控制终端
  637. pub const TIOCSCTTY: u32 = 0x540E;
  638. /// 获取前台进程组
  639. pub const TIOCGPGRP: u32 = 0x540F;
  640. ///设置前台进程组
  641. pub const TIOCSPGRP: u32 = 0x5410;
  642. /// 获取输出队列的字节数
  643. pub const TIOCOUTQ: u32 = 0x5411;
  644. /// 模拟从终端输入字符
  645. pub const TIOCSTI: u32 = 0x5412;
  646. /// 获取窗口大小
  647. pub const TIOCGWINSZ: u32 = 0x5413;
  648. /// 设置窗口大小
  649. pub const TIOCSWINSZ: u32 = 0x5414;
  650. /// 获取终端控制信号的状态
  651. pub const TIOCMGET: u32 = 0x5415;
  652. /// 设置终端控制信号的位
  653. pub const TIOCMBIS: u32 = 0x5416;
  654. /// 清除终端控制信号的位
  655. pub const TIOCMBIC: u32 = 0x5417;
  656. /// 设置终端控制信号的状态
  657. pub const TIOCMSET: u32 = 0x5418;
  658. /// 获取软件载波状态
  659. pub const TIOCGSOFTCAR: u32 = 0x5419;
  660. /// 设置软件载波状态
  661. pub const TIOCSSOFTCAR: u32 = 0x541A;
  662. /// 获取输入队列的字节数
  663. pub const FIONREAD: u32 = 0x541B;
  664. /// Linux 特有命令
  665. pub const TIOCLINUX: u32 = 0x541C;
  666. /// 获取控制台设备
  667. pub const TIOCCONS: u32 = 0x541D;
  668. /// 获取串行设备参数
  669. pub const TIOCGSERIAL: u32 = 0x541E;
  670. /// 设置串行设备参数
  671. pub const TIOCSSERIAL: u32 = 0x541F;
  672. /// 设置套接字的报文模式
  673. pub const TIOCPKT: u32 = 0x5420;
  674. /// 设置非阻塞 I/O
  675. pub const FIONBIO: u32 = 0x5421;
  676. /// 清除控制终端
  677. pub const TIOCNOTTY: u32 = 0x5422;
  678. /// 设置终端线路驱动器
  679. pub const TIOCSETD: u32 = 0x5423;
  680. /// 获取终端线路驱动器
  681. pub const TIOCGETD: u32 = 0x5424;
  682. /// 发送终止条件
  683. pub const TCSBRKP: u32 = 0x5425;
  684. /// 开始发送零比特
  685. pub const TIOCSBRK: u32 = 0x5427;
  686. /// 停止发送零比特
  687. pub const TIOCCBRK: u32 = 0x5428;
  688. /// Return the session ID of FD
  689. pub const TIOCGSID: u32 = 0x5429;
  690. /// 设置ptl锁标记
  691. pub const TIOCSPTLCK: u32 = 0x40045431;
  692. /// 获取ptl锁标记
  693. pub const TIOCGPTLCK: u32 = 0x80045439;
  694. /// 获取packet标记
  695. pub const TIOCGPKT: u32 = 0x80045438;
  696. /// 获取pts index
  697. pub const TIOCGPTN: u32 = 0x80045430;
  698. }