1 use core::intrinsics::unlikely; 2 3 use alloc::string::String; 4 5 use kdepends::thingbuf::mpsc::{ 6 self, 7 errors::{TryRecvError, TrySendError}, 8 }; 9 10 use crate::libs::rwlock::RwLock; 11 12 pub mod init; 13 pub mod serial; 14 pub mod tty_device; 15 pub mod tty_driver; 16 pub mod vt; 17 18 bitflags! { 19 pub struct TtyCoreState: u32{ 20 /// 在读取stdin缓冲区时,由于队列为空,有读者被阻塞 21 const BLOCK_AT_STDIN_READ = (1 << 0); 22 /// 开启输入回显。 23 const ECHO_ON = (1 << 1); 24 } 25 26 #[derive(Default)] 27 pub struct TtyFileFlag:u32{ 28 /// 当前文件是stdin文件 29 const STDIN = (1 << 0); 30 /// 当前文件是stdout文件 31 const STDOUT = (1 << 1); 32 /// 当前文件是stderr文件 33 const STDERR = (1 << 2); 34 } 35 } 36 37 /// @brief tty文件的私有信息 38 #[derive(Debug, Default, Clone)] 39 pub struct TtyFilePrivateData { 40 flags: TtyFileFlag, 41 } 42 43 /// @brief tty设备的核心功能结构体。在此结构体的基础上,衍生出TTY/PTY/PTS等 44 /// 45 /// 每个TTY Core有5个端口: 46 /// - stdin:连接到一个活动进程的stdin文件描述符 47 /// - stdout:连接到多个进程的stdout文件描述符 48 /// - stderr:连接到多个进程的stdout文件描述符 49 /// - 输入端口:向tty设备输入数据的接口。输入到该接口的数据,将被导向stdin接口。 50 /// 如果开启了回显,那么,数据也将同时被导向输出端 51 /// - 输出端口:tty设备对外输出数据的端口。从stdout、stderr输入的数据,将会被导向此端口。 52 /// 此端口可以连接到屏幕、文件、或者是另一个tty core的输入端口。如果开启了 53 /// 输入数据回显,那么,输入端口的数据,将会被同时导向此端口,以及stdin端口 54 #[derive(Debug)] 55 struct TtyCore { 56 /// stdin的mpsc队列输入输出端 57 stdin_rx: mpsc::Receiver<u8>, 58 stdin_tx: mpsc::Sender<u8>, 59 /// 输出的mpsc队列输入输出端 60 output_rx: mpsc::Receiver<u8>, 61 output_tx: mpsc::Sender<u8>, 62 // 前台进程,以后改成前台进程组 63 // front_job: Option<Pid>, 64 /// tty核心的状态 65 state: RwLock<TtyCoreState>, 66 } 67 68 #[derive(Debug)] 69 #[allow(dead_code)] 70 pub enum TtyError { 71 /// 缓冲区满,返回成功传送的字节数 72 BufferFull(usize), 73 /// 缓冲区空,返回成功传送的字节数 74 BufferEmpty(usize), 75 /// 设备已经被关闭 76 Closed, 77 /// End of file(已经读取的字符数,包含eof) 78 EOF(usize), 79 /// 接收到信号终止 80 Stopped(usize), 81 Unknown(String), 82 } 83 84 impl TtyCore { 85 // 各个缓冲区的大小 86 pub const STDIN_BUF_SIZE: usize = 4096; 87 pub const OUTPUT_BUF_SIZE: usize = 4096; 88 89 /// @brief 创建一个TTY核心组件 90 pub fn new() -> TtyCore { 91 let (stdin_tx, stdin_rx) = mpsc::channel::<u8>(Self::STDIN_BUF_SIZE); 92 let (output_tx, output_rx) = mpsc::channel::<u8>(Self::OUTPUT_BUF_SIZE); 93 let state: RwLock<TtyCoreState> = RwLock::new(TtyCoreState { bits: 0 }); 94 95 return TtyCore { 96 stdin_rx, 97 stdin_tx, 98 output_rx, 99 output_tx, 100 state, 101 }; 102 } 103 104 /// @brief 向tty的输入端口输入数据 105 /// 106 /// @param buf 输入数据 107 /// 108 /// @param block 是否允许阻塞 109 /// 110 /// @return Ok(成功传送的字节数) 111 /// @return Err(TtyError) 内部错误信息 112 pub fn input(&self, buf: &[u8], block: bool) -> Result<usize, TtyError> { 113 let val = self.write_stdin(buf, block)?; 114 // 如果开启了输入回显,那么就写一份到输出缓冲区 115 if self.echo_enabled() { 116 self.write_output(&buf[0..val], true)?; 117 } 118 return Ok(val); 119 } 120 121 /// @brief 从tty的输出端口读出数据 122 /// 123 /// @param buf 输出缓冲区 124 /// 125 /// @return Ok(成功传送的字节数) 126 /// @return Err(TtyError) 内部错误信息 127 #[inline] 128 pub fn output(&self, buf: &mut [u8], block: bool) -> Result<usize, TtyError> { 129 return self.read_output(buf, block); 130 } 131 132 /// @brief tty的stdout接口 133 /// 134 /// @param buf 输入缓冲区 135 /// 136 /// @return Ok(成功传送的字节数) 137 /// @return Err(TtyError) 内部错误信息 138 #[inline] 139 pub fn stdout(&self, buf: &[u8], block: bool) -> Result<usize, TtyError> { 140 return self.write_output(buf, block); 141 } 142 143 /// @brief tty的stderr接口 144 /// 145 /// @param buf 输入缓冲区 146 /// 147 /// @return Ok(成功传送的字节数) 148 /// @return Err(TtyError) 内部错误信息 149 #[inline] 150 pub fn stderr(&self, buf: &[u8], block: bool) -> Result<usize, TtyError> { 151 return self.write_output(buf, block); 152 } 153 154 /// @brief 读取TTY的stdin缓冲区 155 /// 156 /// @param buf 读取到的位置 157 /// @param block 是否阻塞读 158 /// 159 /// @return Ok(成功读取的字节数) 160 /// @return Err(TtyError) 内部错误信息 161 pub fn read_stdin(&self, buf: &mut [u8], block: bool) -> Result<usize, TtyError> { 162 // TODO: 增加对EOF的处理 163 let mut cnt = 0; 164 while cnt < buf.len() { 165 let val: Result<mpsc::RecvRef<u8>, TryRecvError> = self.stdin_rx.try_recv_ref(); 166 if let Err(err) = val { 167 match err { 168 TryRecvError::Closed => return Err(TtyError::Closed), 169 TryRecvError::Empty => { 170 if block { 171 continue; 172 } else { 173 return Ok(cnt); 174 } 175 } 176 _ => return Err(TtyError::Unknown(format!("{err:?}"))), 177 } 178 } else { 179 let x = *val.unwrap(); 180 buf[cnt] = x; 181 cnt += 1; 182 183 if unlikely(self.stdin_should_return(x)) { 184 return Ok(cnt); 185 } 186 } 187 } 188 return Ok(cnt); 189 } 190 191 fn stdin_should_return(&self, c: u8) -> bool { 192 // 如果是换行符或者是ctrl+d,那么就应该返回 193 return c == b'\n' || c == 4; 194 } 195 196 /// @brief 向stdin缓冲区内写入数据 197 /// 198 /// @param buf 输入缓冲区 199 /// 200 /// @param block 当缓冲区满的时候,是否阻塞 201 /// 202 /// @return Ok(成功传送的字节数) 203 /// @return Err(BufferFull(成功传送的字节数)) 缓冲区满,成功传送的字节数 204 /// @return Err(TtyError) 内部错误信息 205 fn write_stdin(&self, buf: &[u8], block: bool) -> Result<usize, TtyError> { 206 let mut cnt = 0; 207 while cnt < buf.len() { 208 let r: Result<mpsc::SendRef<u8>, TrySendError> = self.stdin_tx.try_send_ref(); 209 if let Err(e) = r { 210 match e { 211 TrySendError::Closed(_) => return Err(TtyError::Closed), 212 TrySendError::Full(_) => { 213 if block { 214 continue; 215 } else { 216 return Err(TtyError::BufferFull(cnt)); 217 } 218 } 219 _ => return Err(TtyError::Unknown(format!("{e:?}"))), 220 } 221 } else { 222 *r.unwrap() = buf[cnt]; 223 cnt += 1; 224 } 225 } 226 227 return Ok(cnt); 228 } 229 230 /// @brief 读取TTY的output缓冲区 231 /// 232 /// @param buf 读取到的位置 233 /// @param block 是否阻塞读 234 /// 235 /// @return Ok(成功读取的字节数) 236 /// @return Err(TtyError) 内部错误信息 237 fn read_output(&self, buf: &mut [u8], block: bool) -> Result<usize, TtyError> { 238 let mut cnt = 0; 239 while cnt < buf.len() { 240 let val: Result<mpsc::RecvRef<u8>, TryRecvError> = self.output_rx.try_recv_ref(); 241 if let Err(err) = val { 242 match err { 243 TryRecvError::Closed => return Err(TtyError::Closed), 244 TryRecvError::Empty => { 245 if block { 246 continue; 247 } else { 248 return Ok(cnt); 249 } 250 } 251 _ => return Err(TtyError::Unknown(format!("{err:?}"))), 252 } 253 } else { 254 buf[cnt] = *val.unwrap(); 255 cnt += 1; 256 } 257 } 258 return Ok(cnt); 259 } 260 261 /// @brief 向output缓冲区内写入数据 262 /// 263 /// @param buf 输入缓冲区 264 /// 265 /// @param block 当缓冲区满的时候,是否阻塞 266 /// 267 /// @return Ok(成功传送的字节数) 268 /// @return Err(BufferFull(成功传送的字节数)) 缓冲区满,成功传送的字节数 269 /// @return Err(TtyError) 内部错误信息 270 fn write_output(&self, buf: &[u8], block: bool) -> Result<usize, TtyError> { 271 let mut cnt = 0; 272 while cnt < buf.len() { 273 let r: Result<mpsc::SendRef<u8>, TrySendError> = self.output_tx.try_send_ref(); 274 if let Err(e) = r { 275 match e { 276 TrySendError::Closed(_) => return Err(TtyError::Closed), 277 TrySendError::Full(_) => { 278 if block { 279 continue; 280 } else { 281 return Err(TtyError::BufferFull(cnt)); 282 } 283 } 284 _ => return Err(TtyError::Unknown(format!("{e:?}"))), 285 } 286 } else { 287 // TODO: 在这里考虑增加对信号发送的处理 288 // if buf[cnt] == 3 { 289 // let pid = ProcessManager::current_pcb().pid(); 290 // Signal::SIGKILL.send_signal_info( 291 // Some(&mut SigInfo::new( 292 // Signal::SIGKILL, 293 // 0, 294 // SigCode::SI_USER, 295 // SigType::Kill(pid), 296 // )), 297 // pid, 298 // ); 299 // return Err(TtyError::Stopped(cnt)); 300 // } 301 *r.unwrap() = buf[cnt]; 302 cnt += 1; 303 } 304 } 305 return Ok(cnt); 306 } 307 308 /// @brief 开启tty输入回显(也就是将输入数据传送一份到输出缓冲区) 309 #[inline] 310 pub fn enable_echo(&self) { 311 self.state.write().set(TtyCoreState::ECHO_ON, true); 312 } 313 314 /// @brief 关闭输入回显 315 #[inline] 316 #[allow(dead_code)] 317 pub fn disable_echo(&self) { 318 self.state.write().set(TtyCoreState::ECHO_ON, false); 319 } 320 321 /// @brief 判断当前tty核心,是否开启了输入回显 322 /// 323 /// @return true 开启了输入回显 324 /// 325 /// @return false 未开启输入回显 326 #[inline] 327 #[allow(dead_code)] 328 pub fn echo_enabled(&self) -> bool { 329 return self.state.read().contains(TtyCoreState::ECHO_ON); 330 } 331 } 332 333 // ======= 以下代码考虑了“缓冲区满,然后睡眠,当缓冲区有空位就唤醒”的逻辑。 334 // 但是由于在开发过程中的调整,并且由于数据结构发生变化,因此暂时不实现上述优化,因此先注释。 335 // 336 // @brief 读取TTY的stdin缓冲区 337 // 338 // @param buf 读取到的位置 339 // @param block 是否阻塞读 340 // 341 // @return Ok(成功读取的字节数) 342 // @return Err(TtyError) 内部错误信息 343 // pub fn read_stdin(&mut self, buf: &mut [u8], block: bool) -> Result<usize, TtyError> { 344 // let mut cnt = 0; 345 // loop{ 346 // if cnt == buf.len(){ 347 // break; 348 // } 349 // let val:Option<u8> = self.stdin_queue.dequeue(); 350 // // 如果没读到 351 // if val.is_none() { 352 // // 如果阻塞读 353 // if block { 354 // let state_guard: RwLockUpgradableGuard<TtyCoreState> = 355 // self.state.upgradeable_read(); 356 // // 判断是否有进程正在stdin上睡眠,如果有,则忙等读 357 // // 理论上,这种情况应该不存在,因为stdin是单读者的 358 // if state_guard.contains(TtyCoreState::BLOCK_AT_STDIN_READ) { 359 // kwarn!("Read stdin: Process {} want to read its' stdin, but previous process {} is sleeping on the stdin.", current_pcb().pid, self.stdin_waiter.read().as_ref().unwrap().pid); 360 // drop(state_guard); 361 // Self::ringbuf_spin_dequeue(&mut buf[cnt], &mut self.stdin_queue); 362 // cnt += 1; 363 // } else { 364 // // 正常情况,阻塞读,将当前进程休眠 365 // let mut state_guard: RwLockWriteGuard<TtyCoreState> = state_guard.upgrade(); 366 // let mut stdin_waiter_guard: RwLockWriteGuard< 367 // Option<&mut process_control_block>, 368 // > = self.stdin_waiter.write(); 369 370 // // 由于输入数据到stdin的时候,必须先获得state guard的读锁。而这里我们已经获取了state的写锁。 371 // // 因此可以保证,此时没有新的数据会进入stdin_queue. 因此再次尝试读取stdin_queue 372 // let val:Option<u8> = self.stdin_queue.dequeue(); 373 // // 读到数据,不用睡眠 374 // if val.is_some(){ 375 // buf[cnt] = val.unwrap(); 376 // cnt += 1; 377 // continue; 378 // } 379 // // 没读到数据,准备睡眠 380 381 // // 设置等待标志位 382 // state_guard.set(TtyCoreState::BLOCK_AT_STDIN_READ, true); 383 384 // // 将当前进程标记为被其他机制管理 385 // unsafe { 386 // current_pcb().mark_sleep_interruptible(); 387 // } 388 389 // *stdin_waiter_guard = Some(current_pcb()); 390 // drop(stdin_waiter_guard); 391 // drop(state_guard); 392 // sched(); 393 // continue; 394 // } 395 // } else { 396 // // 非阻塞读,没读到就直接返回了 397 // return Ok(cnt); 398 // } 399 // }else{ 400 // buf[cnt] = val.unwrap(); 401 // cnt += 1; 402 // } 403 // } 404 405 // return Ok(cnt); 406 // } 407 408 // fn write_stdin(&self) 409 410 // /// @brief 非休眠的,自旋地读队列,直到有元素被读出来 411 // fn ringbuf_spin_dequeue(dst: &mut u8, queue: &mut AllocRingBuffer<u8>) { 412 // loop { 413 // if let Some(val) = queue.dequeue() { 414 // *dst = val; 415 // return; 416 // } 417 // } 418 // } 419