termios.rs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. use super::tty_ldisc::LineDisciplineType;
  2. /// ## 窗口大小
  3. #[repr(C)]
  4. #[derive(Debug, Default, Clone, Copy)]
  5. pub struct WindowSize {
  6. /// 行
  7. pub row: u16,
  8. /// 列
  9. pub col: u16,
  10. /// x方向像素数
  11. pub xpixel: u16,
  12. /// y方向像素数
  13. pub ypixel: u16,
  14. }
  15. #[derive(Debug, Clone, Copy)]
  16. pub struct Termios {
  17. pub input_mode: InputMode,
  18. pub output_mode: OutputMode,
  19. pub control_mode: ControlMode,
  20. pub local_mode: LocalMode,
  21. pub control_characters: [u8; CONTORL_CHARACTER_NUM],
  22. pub line: LineDisciplineType,
  23. pub input_speed: u32,
  24. pub output_speed: u32,
  25. }
  26. #[derive(Clone, Copy)]
  27. pub struct PosixTermios {
  28. pub c_iflag: u32,
  29. pub c_oflag: u32,
  30. pub c_cflag: u32,
  31. pub c_lflag: u32,
  32. pub c_cc: [u8; CONTORL_CHARACTER_NUM],
  33. pub c_line: u8,
  34. pub c_ispeed: u32,
  35. pub c_ospeed: u32,
  36. }
  37. impl PosixTermios {
  38. pub fn from_kernel_termios(termios: Termios) -> Self {
  39. Self {
  40. c_iflag: termios.input_mode.bits,
  41. c_oflag: termios.output_mode.bits,
  42. c_cflag: termios.control_mode.bits,
  43. c_lflag: termios.local_mode.bits,
  44. c_cc: termios.control_characters.clone(),
  45. c_line: termios.line as u8,
  46. c_ispeed: termios.input_speed,
  47. c_ospeed: termios.output_speed,
  48. }
  49. }
  50. #[allow(dead_code)]
  51. pub fn to_kernel_termios(&self) -> Termios {
  52. Termios {
  53. input_mode: InputMode::from_bits_truncate(self.c_iflag),
  54. output_mode: OutputMode::from_bits_truncate(self.c_oflag),
  55. control_mode: ControlMode::from_bits_truncate(self.c_cflag),
  56. local_mode: LocalMode::from_bits_truncate(self.c_lflag),
  57. control_characters: self.c_cc.clone(),
  58. line: LineDisciplineType::from_line(self.c_line),
  59. input_speed: self.c_ispeed,
  60. output_speed: self.c_ospeed,
  61. }
  62. }
  63. }
  64. pub const INIT_CONTORL_CHARACTERS: [u8; CONTORL_CHARACTER_NUM] = [
  65. b'C' - 0x40, // VINTR
  66. b'\\' - 0x40, // VQUIT
  67. 0o177, // VERASE
  68. b'U' - 0x40, // VKILL
  69. b'D' - 0x40, // VEOF
  70. 1, // VMIN
  71. 0, // VEOL
  72. 0, // VTIME
  73. 0, // VEOL2
  74. 0, // VSWTC
  75. b'W' - 0x40, // VWERASE
  76. b'R' - 0x40, // VREPRINT
  77. b'Z' - 0x40, // VSUSP
  78. b'Q' - 0x40, // VSTART
  79. b'S' - 0x40, // VSTOP
  80. b'V' - 0x40, // VLNEXT
  81. b'O' - 0x40, // VDISCARD
  82. 0,
  83. 0,
  84. ];
  85. // pub const INIT_CONTORL_CHARACTERS: [u8; CONTORL_CHARACTER_NUM] = {
  86. // let mut chs: [u8; CONTORL_CHARACTER_NUM] = Default::default();
  87. // chs[ControlCharIndex::VINTR] = b'C' - 0x40;
  88. // chs[ControlCharIndex::VQUIT] = b'\\' - 0x40;
  89. // chs[ControlCharIndex::VERASE] = 0o177;
  90. // chs[ControlCharIndex::VKILL] = b'U' - 0x40;
  91. // chs[ControlCharIndex::VEOF] = b'D' - 0x40;
  92. // chs[ControlCharIndex::VSTART] = b'Q' - 0x40;
  93. // chs[ControlCharIndex::VSTOP] = b'S' - 0x40;
  94. // chs[ControlCharIndex::VSUSP] = b'Z' - 0x40;
  95. // chs[ControlCharIndex::VREPRINT] = b'R' - 0x40;
  96. // chs[ControlCharIndex::VDISCARD] = b'O' - 0x40;
  97. // chs[ControlCharIndex::VWERASE] = b'W' - 0x40;
  98. // chs[ControlCharIndex::VLNEXT] = b'V' - 0x40;
  99. // // chs[ContorlCharIndex::VDSUSP] = b'Y' - 0x40;
  100. // chs[ControlCharIndex::VMIN] = 1;
  101. // return chs;
  102. // };
  103. lazy_static! {
  104. pub static ref TTY_STD_TERMIOS: Termios = {
  105. Termios {
  106. input_mode: InputMode::ICRNL | InputMode::IXON,
  107. output_mode: OutputMode::OPOST | OutputMode::ONLCR,
  108. control_mode: ControlMode::B38400
  109. | ControlMode::CREAD
  110. | ControlMode::HUPCL
  111. | ControlMode::CS8,
  112. local_mode: LocalMode::ISIG
  113. | LocalMode::ICANON
  114. | LocalMode::ECHO
  115. | LocalMode::ECHOE
  116. | LocalMode::ECHOK
  117. | LocalMode::ECHOCTL
  118. | LocalMode::ECHOKE
  119. | LocalMode::IEXTEN,
  120. control_characters: INIT_CONTORL_CHARACTERS.clone(),
  121. line: LineDisciplineType::NTty,
  122. input_speed: 38400,
  123. output_speed: 38400,
  124. }
  125. };
  126. }
  127. pub const CONTORL_CHARACTER_NUM: usize = 19;
  128. bitflags! {
  129. /// termios输入特性
  130. pub struct InputMode: u32 {
  131. /// 如果设置了该标志,表示启用软件流控制。
  132. const IXON = 0x0200;
  133. /// 如果设置了该标志,表示启用输入流控制。
  134. const IXOFF = 0x0400;
  135. /// Map Uppercase to Lowercase on Input 将大写转换为小写
  136. /// 表示不区分大小写
  137. const IUCLC = 0x1000;
  138. /// 如果设置了该标志,表示当输入队列满时,产生一个响铃信号。
  139. const IMAXBEL = 0x2000;
  140. /// 如果设置了该标志,表示输入数据被视为 UTF-8 编码。
  141. const IUTF8 = 0x4000;
  142. /// 忽略中断信号
  143. const IGNBRK = 0x001;
  144. /// 检测到中断信号时生成中断(产生中断信号)
  145. const BRKINT = 0x002;
  146. /// 忽略具有奇偶校验错误的字符
  147. const IGNPAR = 0x004;
  148. /// 在检测到奇偶校验错误或帧错误时,将字符以 \377 标记
  149. const PARMRK = 0x008;
  150. /// 启用输入奇偶校验检查
  151. const INPCK = 0x010;
  152. /// 从输入字符中剥离第 8 位,即只保留低 7 位
  153. const ISTRIP = 0x020;
  154. /// 表示将输入的换行符 (\n) 映射为回车符 (\r)
  155. const INLCR = 0x040;
  156. /// 表示忽略回车符 (\r)
  157. const IGNCR = 0x080;
  158. /// 表示将输入的回车符 (\r) 映射为换行符 (\n)
  159. const ICRNL = 0x100;
  160. /// 表示在输入被停止(Ctrl-S)后,任何字符的输入都将重新启动输入
  161. const IXANY = 0x800;
  162. }
  163. /// termios输出特性
  164. pub struct OutputMode: u32 {
  165. /// 在输出时将换行符替换\r\n
  166. const ONLCR = 0x00002;
  167. /// Map Lowercase to Uppercase on Output 输出字符时将小写字母映射为大写字母
  168. const OLCUC = 0x00004;
  169. /// 与NL协同 配置换行符的处理方式
  170. const NLDLY = 0x00300;
  171. const NL0 = 0x00000; // 不延迟换行
  172. const NL1 = 0x00100; // 延迟换行(输出回车后等待一段时间再输出换行)
  173. const NL2 = 0x00200; // NL2 和 NL3保留,暂未使用
  174. const NL3 = 0x00300;
  175. /// 配置水平制表符的处理方式
  176. const TABDLY = 0x00c00;
  177. const TAB0 = 0x00000; // 不延迟水平制表符
  178. const TAB1 = 0x00400; // 在输出水平制表符时,延迟到下一个设置的水平制表符位置
  179. const TAB2 = 0x00800; // 在输出水平制表符时,延迟到下一个设置的 8 的倍数的位置
  180. const TAB3 = 0x00c00; // TAB3 和 XTABS(与 TAB3 等效)保留,暂未使用
  181. const XTABS = 0x00c00;
  182. /// 配置回车符的处理方式
  183. const CRDLY = 0x03000;
  184. const CR0 = 0x00000; // 不延迟回车
  185. const CR1 = 0x01000; // 延迟回车(输出回车后等待一段时间再输出换行)
  186. const CR2 = 0x02000; // CR2 和 CR3保留,暂未使用
  187. const CR3 = 0x03000;
  188. /// 配置换页符(form feed)的处理方式
  189. const FFDLY = 0x04000;
  190. const FF0 = 0x00000; // 不延迟换页
  191. const FF1 = 0x04000; // 延迟换页
  192. /// 配置退格符(backspace)的处理方式
  193. const BSDLY = 0x08000;
  194. const BS0 = 0x00000; // 不延迟退格
  195. const BS1 = 0x08000; // 延迟退格
  196. /// 配置垂直制表符(vertical tab)的处理方式
  197. const VTDLY = 0x10000;
  198. const VT0 = 0x00000; // 不延迟垂直制表符
  199. const VT1 = 0x10000; // 延迟垂直制表符
  200. /// 表示执行输出处理,即启用输出处理函数
  201. const OPOST = 0x01;
  202. /// 表示将输出的回车符 (\r) 映射为换行符 (\n)
  203. const OCRNL = 0x08;
  204. /// 表示在输出时,如果光标在第 0 列,则不输出回车符 (\r)
  205. const ONOCR = 0x10;
  206. /// 表示将回车符 (\r) 映射为换行符 (\n)
  207. const ONLRET = 0x20;
  208. /// 表示使用填充字符进行延迟。这个填充字符的默认值是空格。
  209. const OFILL = 0x40;
  210. /// 表示使用删除字符 (DEL, \177) 作为填充字符
  211. const OFDEL = 0x80;
  212. }
  213. /// 配置终端设备的基本特性和控制参数
  214. pub struct ControlMode: u32 {
  215. /// Baud Rate Mask 指定波特率的掩码
  216. const CBAUD = 0x000000ff;
  217. /// Extra Baud Bits 指定更高的波特率位
  218. const CBAUDEX = 0x00000000;
  219. /// Custom Baud Rate 指定自定义波特率 如果设置了 BOTHER,则通过以下位来设置自定义的波特率值
  220. const BOTHER = 0x0000001f;
  221. const B0 = 0x00000000;
  222. const B50 = 0x00000001;
  223. const B75 = 0x00000002;
  224. const B110 = 0x00000003;
  225. const B134 = 0x00000004;
  226. const B150 = 0x00000005;
  227. const B200 = 0x00000006;
  228. const B300 = 0x00000007;
  229. const B600 = 0x00000008;
  230. const B1200 = 0x00000009;
  231. const B1800 = 0x0000000a;
  232. const B2400 = 0x0000000b;
  233. const B4800 = 0x0000000c;
  234. const B9600 = 0x0000000d;
  235. const B19200 = 0x0000000e;
  236. const B38400 = 0x0000000f;
  237. const B57600 = 0x00000010;
  238. const B115200 = 0x00000011;
  239. const B230400 = 0x00000012;
  240. const B460800 = 0x00000013;
  241. const B500000 = 0x00000014;
  242. const B576000 = 0x00000015;
  243. const B921600 = 0x00000016;
  244. const B1000000 = 0x00000017;
  245. const B1152000 = 0x00000018;
  246. const B1500000 = 0x00000019;
  247. const B2000000 = 0x0000001a;
  248. const B2500000 = 0x0000001b;
  249. const B3000000 = 0x0000001c;
  250. const B3500000 = 0x0000001d;
  251. const B4000000 = 0x0000001e;
  252. /// 指定字符大小的掩码 以下位为特定字符大小
  253. const CSIZE = 0x00000300;
  254. const CS5 = 0x00000000;
  255. const CS6 = 0x00000100;
  256. const CS7 = 0x00000200;
  257. const CS8 = 0x00000300;
  258. /// Stop Bit Select 表示使用两个停止位;否则,表示使用一个停止位
  259. const CSTOPB = 0x00000400;
  260. /// 表示启用接收器。如果未设置,则禁用接收器。
  261. const CREAD = 0x00000800;
  262. /// 表示启用奇偶校验。如果未设置,则禁用奇偶校验。
  263. const PARENB = 0x00001000;
  264. /// 表示启用奇校验。如果未设置,则表示启用偶校验。
  265. const PARODD = 0x00002000;
  266. /// 表示在终端设备被关闭时挂断线路(执行挂断操作)
  267. const HUPCL = 0x00004000;
  268. /// 表示忽略调制解调器的状态(DCD、DSR、CTS 等)
  269. const CLOCAL = 0x00008000;
  270. /// 指定输入波特率的掩码
  271. const CIBAUD = 0x00ff0000;
  272. const ADDRB = 0x20000000;
  273. }
  274. /// 配置终端设备的本地模式(local mode)或控制输入处理的行为
  275. pub struct LocalMode: u32 {
  276. /// 启用中断字符(Ctrl-C、Ctrl-Z)
  277. const ISIG = 0x00000080;
  278. /// 表示启用规范模式,即启用行缓冲和回显。在规范模式下,输入被缓冲,并且只有在输入回车符时才会传递给应用程序。
  279. const ICANON = 0x00000100;
  280. /// 表示启用大写模式,即输入输出都将被转换为大写。
  281. const XCASE = 0x00004000;
  282. /// 表示启用回显(显示用户输入的字符)
  283. const ECHO = 0x00000008;
  284. /// 表示在回显时将擦除的字符用 backspace 和空格字符显示。
  285. const ECHOE = 0x00000002;
  286. /// 表示在回显时将换行符后的字符用空格字符显示。
  287. const ECHOK = 0x00000004;
  288. /// 表示在回显时将换行符显示为换行和回车符。
  289. const ECHONL = 0x00000010;
  290. /// 表示在收到中断(Ctrl-C)和退出(Ctrl-\)字符后,不清空输入和输出缓冲区。
  291. const NOFLSH = 0x80000000;
  292. /// 表示在后台进程尝试写入终端时,发送停止信号(Ctrl-S)
  293. const TOSTOP = 0x00400000;
  294. /// 表示在回显时,显示控制字符为 ^ 加字符。
  295. const ECHOCTL= 0x00000040;
  296. /// 表示在回显时显示带有 # 的换行符(为了与 echo -n 命令兼容)。
  297. const ECHOPRT= 0x00000020;
  298. /// 表示在回显时将 KILL 字符(Ctrl-U)用空格字符显示。
  299. const ECHOKE = 0x00000001;
  300. /// 表示输出正在被冲刷(flush),通常是由于输入/输出流的状态变化。
  301. const FLUSHO = 0x00800000;
  302. /// 表示在规范模式下,存在需要重新打印的字符。
  303. const PENDIN = 0x20000000;
  304. /// 表示启用实现定义的输入处理。
  305. const IEXTEN = 0x00000400;
  306. /// 表示启用扩展的处理函数
  307. const EXTPROC= 0x10000000;
  308. }
  309. pub struct TtySetTermiosOpt: u8 {
  310. const TERMIOS_FLUSH =1;
  311. const TERMIOS_WAIT =2;
  312. const TERMIOS_TERMIO =4;
  313. const TERMIOS_OLD =8;
  314. }
  315. }
  316. /// 对应termios中控制字符的索引
  317. pub struct ControlCharIndex;
  318. #[allow(dead_code)]
  319. impl ControlCharIndex {
  320. pub const DISABLE_CHAR: u8 = b'\0';
  321. /// 中断信号
  322. pub const VINTR: usize = 0;
  323. /// 退出信号
  324. pub const VQUIT: usize = 1;
  325. /// 退格
  326. pub const VERASE: usize = 2;
  327. /// 终止输入信号
  328. pub const VKILL: usize = 3;
  329. /// 文件结束信号 \0?
  330. pub const VEOF: usize = 4;
  331. /// 指定非规范模式下的最小字符数
  332. pub const VMIN: usize = 5;
  333. /// 换行符
  334. pub const VEOL: usize = 6;
  335. /// 指定非规范模式下的超时时间
  336. pub const VTIME: usize = 7;
  337. /// 换行符
  338. pub const VEOL2: usize = 8;
  339. /// 未使用,保留
  340. pub const VSWTC: usize = 9;
  341. /// 擦除前一个单词
  342. pub const VWERASE: usize = 10;
  343. /// 重新打印整行
  344. pub const VREPRINT: usize = 11;
  345. /// 挂起信号
  346. pub const VSUSP: usize = 12;
  347. /// 启动输出信号
  348. pub const VSTART: usize = 13;
  349. /// 停止输出信号
  350. pub const VSTOP: usize = 14;
  351. /// 将下一个字符视为字面值,而不是特殊字符
  352. pub const VLNEXT: usize = 15;
  353. /// 对应于字符丢弃信号,用于丢弃当前输入的行
  354. pub const VDISCARD: usize = 16;
  355. }