Browse Source

修改tty几个bug (#549)

* 更改ioctl一处逻辑错误

* 删除不必要的impl

* 修改一处bug,并且加入tty的link,为pty做准备

* 修改一处因为vc的pos和x计算错误导致的溢出
GnoCiYeH 1 year ago
parent
commit
be60c929c8

+ 2 - 1
kernel/src/driver/tty/termios.rs

@@ -26,7 +26,7 @@ pub struct Termios {
     pub output_speed: u32,
 }
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Default)]
 pub struct PosixTermios {
     pub c_iflag: u32,
     pub c_oflag: u32,
@@ -54,6 +54,7 @@ impl PosixTermios {
 
     #[allow(dead_code)]
     pub fn to_kernel_termios(&self) -> Termios {
+        // TODO:这里没有考虑非规范模式
         Termios {
             input_mode: InputMode::from_bits_truncate(self.c_iflag),
             output_mode: OutputMode::from_bits_truncate(self.c_oflag),

+ 36 - 24
kernel/src/driver/tty/tty_core.rs

@@ -12,7 +12,7 @@ use crate::{
     mm::VirtAddr,
     net::event_poll::EPollEventType,
     process::Pid,
-    syscall::user_access::UserBufferWriter,
+    syscall::user_access::{UserBufferReader, UserBufferWriter},
 };
 
 use super::{
@@ -51,6 +51,7 @@ impl TtyCore {
             ctrl: SpinLock::new(TtyContorlInfo::default()),
             closing: AtomicBool::new(false),
             flow: SpinLock::new(TtyFlowState::default()),
+            link: None,
         };
 
         return Arc::new(Self {
@@ -128,15 +129,19 @@ impl TtyCore {
             .wakeup(EPollEventType::EPOLLOUT.bits() as u64);
     }
 
-    pub fn tty_mode_ioctl(
-        &self,
-        tty: Arc<TtyCore>,
-        cmd: u32,
-        arg: usize,
-    ) -> Result<usize, SystemError> {
+    pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
+        let real_tty;
+        let core = tty.core();
+        if core.driver().tty_driver_type() == TtyDriverType::Pty
+            && core.driver().tty_driver_sub_type() == TtyDriverSubType::PtyMaster
+        {
+            real_tty = core.link().unwrap();
+        } else {
+            real_tty = tty;
+        }
         match cmd {
             TtyIoctlCmd::TCGETS => {
-                let termios = PosixTermios::from_kernel_termios(self.core.termios().clone());
+                let termios = PosixTermios::from_kernel_termios(real_tty.core.termios().clone());
                 let mut user_writer = UserBufferWriter::new(
                     VirtAddr::new(arg).as_ptr::<PosixTermios>(),
                     core::mem::size_of::<PosixTermios>(),
@@ -147,8 +152,8 @@ impl TtyCore {
                 return Ok(0);
             }
             TtyIoctlCmd::TCSETSW => {
-                return self.core_set_termios(
-                    tty,
+                return TtyCore::core_set_termios(
+                    real_tty,
                     VirtAddr::new(arg),
                     TtySetTermiosOpt::TERMIOS_WAIT | TtySetTermiosOpt::TERMIOS_OLD,
                 );
@@ -160,27 +165,31 @@ impl TtyCore {
     }
 
     pub fn core_set_termios(
-        &self,
         tty: Arc<TtyCore>,
         arg: VirtAddr,
         opt: TtySetTermiosOpt,
     ) -> Result<usize, SystemError> {
-        let tmp_termios = self.core().termios().clone();
+        #[allow(unused_assignments)]
+        // TERMIOS_TERMIO下会用到
+        let mut tmp_termios = tty.core().termios().clone();
 
         if opt.contains(TtySetTermiosOpt::TERMIOS_TERMIO) {
             todo!()
         } else {
-            let mut user_writer = UserBufferWriter::new(
+            let user_reader = UserBufferReader::new(
                 arg.as_ptr::<PosixTermios>(),
                 core::mem::size_of::<PosixTermios>(),
                 true,
             )?;
 
-            user_writer.copy_one_to_user(&tmp_termios, 0)?;
+            let mut term = PosixTermios::default();
+            user_reader.copy_one_from_user(&mut term, 0)?;
+
+            tmp_termios = term.to_kernel_termios();
         }
 
         if opt.contains(TtySetTermiosOpt::TERMIOS_FLUSH) {
-            let ld = self.ldisc();
+            let ld = tty.ldisc();
             let _ = ld.flush_buffer(tty.clone());
         }
 
@@ -188,16 +197,12 @@ impl TtyCore {
             // TODO
         }
 
-        self.set_termios_next(tty, tmp_termios)?;
+        TtyCore::set_termios_next(tty, tmp_termios)?;
         Ok(0)
     }
 
-    pub fn set_termios_next(
-        &self,
-        tty: Arc<TtyCore>,
-        new_termios: Termios,
-    ) -> Result<(), SystemError> {
-        let mut termios = self.core().termios_write();
+    pub fn set_termios_next(tty: Arc<TtyCore>, new_termios: Termios) -> Result<(), SystemError> {
+        let mut termios = tty.core().termios_write();
 
         let old_termios = termios.clone();
 
@@ -206,7 +211,7 @@ impl TtyCore {
         let tmp = termios.control_mode;
         termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
 
-        let ret = self.set_termios(tty.clone(), old_termios);
+        let ret = tty.set_termios(tty.clone(), old_termios);
         if ret.is_err() {
             termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL;
             termios.control_mode |= old_termios.control_mode
@@ -216,7 +221,7 @@ impl TtyCore {
         }
 
         drop(termios);
-        let ld = self.ldisc();
+        let ld = tty.ldisc();
         ld.set_termios(tty, Some(old_termios))?;
 
         Ok(())
@@ -285,6 +290,8 @@ pub struct TtyCoreData {
     closing: AtomicBool,
     /// 流控状态
     flow: SpinLock<TtyFlowState>,
+    /// 链接tty
+    link: Option<Arc<TtyCore>>,
 }
 
 impl TtyCoreData {
@@ -374,6 +381,11 @@ impl TtyCoreData {
     pub fn vc_data_irqsave(&self) -> SpinLockGuard<VirtualConsoleData> {
         VIRT_CONSOLES[self.index].lock_irqsave()
     }
+
+    #[inline]
+    pub fn link(&self) -> Option<Arc<TtyCore>> {
+        self.link.clone()
+    }
 }
 
 /// TTY 核心接口,不同的tty需要各自实现这个trait

+ 1 - 1
kernel/src/driver/tty/tty_ldisc/ntty.rs

@@ -59,7 +59,7 @@ impl NTtyLinediscipline {
                 todo!()
             }
             _ => {
-                return tty.tty_mode_ioctl(tty.clone(), cmd, arg);
+                return TtyCore::tty_mode_ioctl(tty.clone(), cmd, arg);
             }
         }
     }

+ 0 - 2
kernel/src/driver/tty/virtual_terminal/mod.rs

@@ -96,8 +96,6 @@ pub struct TtyConsoleDriverInner {
     console: Arc<BlittingFbConsole>,
 }
 
-unsafe impl Sync for TtyConsoleDriverInner {}
-
 impl TtyConsoleDriverInner {
     pub fn new() -> Result<Self, SystemError> {
         Ok(Self {

+ 4 - 3
kernel/src/driver/tty/virtual_terminal/virtual_console.rs

@@ -581,7 +581,7 @@ impl VirtualConsoleData {
             self.state.y = y as usize;
         }
 
-        self.pos = self.state.y * self.cols + (self.state.x << 1);
+        self.pos = self.state.y * self.cols + self.state.x;
         self.need_wrap = false;
     }
 
@@ -1200,12 +1200,13 @@ impl VirtualConsoleData {
             }
         }
 
-        for i in self.screen_buf[start..(start + count)].iter_mut() {
+        let max_idx = self.screen_buf.len();
+        for i in self.screen_buf[start..max_idx.min(start + count)].iter_mut() {
             *i = self.erase_char;
         }
 
         if self.should_update() {
-            self.do_update_region(start, count)
+            self.do_update_region(start, count.min(max_idx - start))
         }
 
         self.need_wrap = false;