xref: /DragonOS/kernel/src/driver/tty/pty/unix98pty.rs (revision 9365e8017b39582eca620ba93c64f1b3c87c73d4)
1dfe53cf0SGnoCiYeH use alloc::{string::ToString, sync::Arc};
2dfe53cf0SGnoCiYeH use system_error::SystemError;
3dfe53cf0SGnoCiYeH 
4dfe53cf0SGnoCiYeH use crate::{
5dfe53cf0SGnoCiYeH     driver::tty::{
6*9365e801SGnoCiYeH         termios::{ControlCharIndex, ControlMode, InputMode, LocalMode, Termios},
7dfe53cf0SGnoCiYeH         tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
8dfe53cf0SGnoCiYeH         tty_device::TtyFilePrivateData,
9dfe53cf0SGnoCiYeH         tty_driver::{TtyDriver, TtyDriverPrivateData, TtyDriverSubType, TtyOperation},
10dfe53cf0SGnoCiYeH     },
11dfe53cf0SGnoCiYeH     filesystem::{
12dfe53cf0SGnoCiYeH         devpts::DevPtsFs,
13dfe53cf0SGnoCiYeH         vfs::{
14dfe53cf0SGnoCiYeH             file::FileMode, syscall::ModeType, FilePrivateData, FileType, MountFS, ROOT_INODE,
15dfe53cf0SGnoCiYeH             VFS_MAX_FOLLOW_SYMLINK_TIMES,
16dfe53cf0SGnoCiYeH         },
17dfe53cf0SGnoCiYeH     },
18dfe53cf0SGnoCiYeH     libs::spinlock::SpinLockGuard,
19dfe53cf0SGnoCiYeH     mm::VirtAddr,
20dfe53cf0SGnoCiYeH     net::event_poll::EPollEventType,
21dfe53cf0SGnoCiYeH     syscall::user_access::UserBufferWriter,
22dfe53cf0SGnoCiYeH };
23dfe53cf0SGnoCiYeH 
24dfe53cf0SGnoCiYeH use super::{ptm_driver, pts_driver, PtyCommon};
25dfe53cf0SGnoCiYeH 
26dfe53cf0SGnoCiYeH pub const NR_UNIX98_PTY_MAX: u32 = 128;
27dfe53cf0SGnoCiYeH 
28dfe53cf0SGnoCiYeH #[derive(Debug)]
29dfe53cf0SGnoCiYeH pub struct Unix98PtyDriverInner;
30dfe53cf0SGnoCiYeH 
31dfe53cf0SGnoCiYeH impl Unix98PtyDriverInner {
new() -> Self32dfe53cf0SGnoCiYeH     pub fn new() -> Self {
33dfe53cf0SGnoCiYeH         Self
34dfe53cf0SGnoCiYeH     }
35dfe53cf0SGnoCiYeH }
36dfe53cf0SGnoCiYeH 
37dfe53cf0SGnoCiYeH impl TtyOperation for Unix98PtyDriverInner {
install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError>38dfe53cf0SGnoCiYeH     fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
39dfe53cf0SGnoCiYeH         PtyCommon::pty_common_install(driver, tty, false)
40dfe53cf0SGnoCiYeH     }
41dfe53cf0SGnoCiYeH 
open(&self, tty: &TtyCoreData) -> Result<(), SystemError>42dfe53cf0SGnoCiYeH     fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
43dfe53cf0SGnoCiYeH         PtyCommon::pty_common_open(tty)
44dfe53cf0SGnoCiYeH     }
45dfe53cf0SGnoCiYeH 
write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError>46dfe53cf0SGnoCiYeH     fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
47dfe53cf0SGnoCiYeH         let to = tty.checked_link()?;
48dfe53cf0SGnoCiYeH 
49dfe53cf0SGnoCiYeH         if nr == 0 || tty.flow_irqsave().stopped {
50dfe53cf0SGnoCiYeH             return Ok(0);
51dfe53cf0SGnoCiYeH         }
52dfe53cf0SGnoCiYeH 
53dfe53cf0SGnoCiYeH         to.core().port().unwrap().receive_buf(buf, &[], nr)
54dfe53cf0SGnoCiYeH     }
55dfe53cf0SGnoCiYeH 
write_room(&self, tty: &TtyCoreData) -> usize56dfe53cf0SGnoCiYeH     fn write_room(&self, tty: &TtyCoreData) -> usize {
57dfe53cf0SGnoCiYeH         // TODO 暂时
58dfe53cf0SGnoCiYeH         if tty.flow_irqsave().stopped {
59dfe53cf0SGnoCiYeH             return 0;
60dfe53cf0SGnoCiYeH         }
61dfe53cf0SGnoCiYeH 
62dfe53cf0SGnoCiYeH         8192
63dfe53cf0SGnoCiYeH     }
64dfe53cf0SGnoCiYeH 
flush_buffer(&self, tty: &TtyCoreData) -> Result<(), SystemError>65dfe53cf0SGnoCiYeH     fn flush_buffer(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
66dfe53cf0SGnoCiYeH         let to = tty.checked_link()?;
67dfe53cf0SGnoCiYeH 
68dfe53cf0SGnoCiYeH         let mut ctrl = to.core().contorl_info_irqsave();
69dfe53cf0SGnoCiYeH         ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_FLUSHWRITE);
70dfe53cf0SGnoCiYeH 
71dfe53cf0SGnoCiYeH         to.core().read_wq().wakeup_all();
72dfe53cf0SGnoCiYeH 
73dfe53cf0SGnoCiYeH         Ok(())
74dfe53cf0SGnoCiYeH     }
75dfe53cf0SGnoCiYeH 
ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError>76dfe53cf0SGnoCiYeH     fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
77dfe53cf0SGnoCiYeH         let core = tty.core();
78dfe53cf0SGnoCiYeH         if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtyMaster {
79*9365e801SGnoCiYeH             return Err(SystemError::ENOIOCTLCMD);
80dfe53cf0SGnoCiYeH         }
81dfe53cf0SGnoCiYeH 
82dfe53cf0SGnoCiYeH         match cmd {
83dfe53cf0SGnoCiYeH             TtyIoctlCmd::TIOCSPTLCK => {
84dfe53cf0SGnoCiYeH                 return PtyCommon::pty_set_lock(core, VirtAddr::new(arg));
85dfe53cf0SGnoCiYeH             }
86dfe53cf0SGnoCiYeH             TtyIoctlCmd::TIOCGPTLCK => {
87dfe53cf0SGnoCiYeH                 return PtyCommon::pty_get_lock(core, VirtAddr::new(arg));
88dfe53cf0SGnoCiYeH             }
89dfe53cf0SGnoCiYeH             TtyIoctlCmd::TIOCPKT => {
90dfe53cf0SGnoCiYeH                 return PtyCommon::pty_set_packet_mode(core, VirtAddr::new(arg));
91dfe53cf0SGnoCiYeH             }
92dfe53cf0SGnoCiYeH             TtyIoctlCmd::TIOCGPKT => {
93dfe53cf0SGnoCiYeH                 return PtyCommon::pty_get_packet_mode(core, VirtAddr::new(arg));
94dfe53cf0SGnoCiYeH             }
95dfe53cf0SGnoCiYeH             TtyIoctlCmd::TIOCGPTN => {
96dfe53cf0SGnoCiYeH                 let mut user_writer =
97dfe53cf0SGnoCiYeH                     UserBufferWriter::new(arg as *mut u32, core::mem::size_of::<u32>(), true)?;
98dfe53cf0SGnoCiYeH 
99dfe53cf0SGnoCiYeH                 return user_writer.copy_one_to_user(&(core.index() as u32), 0);
100dfe53cf0SGnoCiYeH             }
101dfe53cf0SGnoCiYeH             _ => {
102dfe53cf0SGnoCiYeH                 return Err(SystemError::ENOIOCTLCMD);
103dfe53cf0SGnoCiYeH             }
104dfe53cf0SGnoCiYeH         }
105dfe53cf0SGnoCiYeH     }
106dfe53cf0SGnoCiYeH 
set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError>107*9365e801SGnoCiYeH     fn set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError> {
108dfe53cf0SGnoCiYeH         let core = tty.core();
109dfe53cf0SGnoCiYeH         if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
110dfe53cf0SGnoCiYeH             return Err(SystemError::ENOSYS);
111dfe53cf0SGnoCiYeH         }
112*9365e801SGnoCiYeH 
113*9365e801SGnoCiYeH         let core = tty.core();
114*9365e801SGnoCiYeH         if let Some(link) = core.link() {
115*9365e801SGnoCiYeH             let link = link.core();
116*9365e801SGnoCiYeH             if link.contorl_info_irqsave().packet {
117*9365e801SGnoCiYeH                 let curr_termios = *core.termios();
118*9365e801SGnoCiYeH                 let extproc = old_termios.local_mode.contains(LocalMode::EXTPROC)
119*9365e801SGnoCiYeH                     | curr_termios.local_mode.contains(LocalMode::EXTPROC);
120*9365e801SGnoCiYeH 
121*9365e801SGnoCiYeH                 let old_flow = old_termios.input_mode.contains(InputMode::IXON)
122*9365e801SGnoCiYeH                     && old_termios.control_characters[ControlCharIndex::VSTOP] == 0o023
123*9365e801SGnoCiYeH                     && old_termios.control_characters[ControlCharIndex::VSTART] == 0o021;
124*9365e801SGnoCiYeH 
125*9365e801SGnoCiYeH                 let new_flow = curr_termios.input_mode.contains(InputMode::IXON)
126*9365e801SGnoCiYeH                     && curr_termios.control_characters[ControlCharIndex::VSTOP] == 0o023
127*9365e801SGnoCiYeH                     && curr_termios.control_characters[ControlCharIndex::VSTART] == 0o021;
128*9365e801SGnoCiYeH 
129*9365e801SGnoCiYeH                 if old_flow != new_flow || extproc {
130*9365e801SGnoCiYeH                     let mut ctrl = core.contorl_info_irqsave();
131*9365e801SGnoCiYeH                     if old_flow != new_flow {
132*9365e801SGnoCiYeH                         ctrl.pktstatus.remove(
133*9365e801SGnoCiYeH                             TtyPacketStatus::TIOCPKT_DOSTOP | TtyPacketStatus::TIOCPKT_NOSTOP,
134*9365e801SGnoCiYeH                         );
135*9365e801SGnoCiYeH 
136*9365e801SGnoCiYeH                         if new_flow {
137*9365e801SGnoCiYeH                             ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_DOSTOP);
138*9365e801SGnoCiYeH                         } else {
139*9365e801SGnoCiYeH                             ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_NOSTOP);
140*9365e801SGnoCiYeH                         }
141*9365e801SGnoCiYeH                     }
142*9365e801SGnoCiYeH 
143*9365e801SGnoCiYeH                     if extproc {
144*9365e801SGnoCiYeH                         ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_IOCTL);
145*9365e801SGnoCiYeH                     }
146*9365e801SGnoCiYeH 
147*9365e801SGnoCiYeH                     link.read_wq().wakeup_all();
148*9365e801SGnoCiYeH                 }
149*9365e801SGnoCiYeH             }
150*9365e801SGnoCiYeH         }
151*9365e801SGnoCiYeH         let mut termois = core.termios_write();
152*9365e801SGnoCiYeH         termois
153*9365e801SGnoCiYeH             .control_mode
154*9365e801SGnoCiYeH             .remove(ControlMode::CSIZE | ControlMode::PARENB);
155*9365e801SGnoCiYeH         termois
156*9365e801SGnoCiYeH             .control_mode
157*9365e801SGnoCiYeH             .insert(ControlMode::CS8 | ControlMode::CREAD);
158*9365e801SGnoCiYeH         Ok(())
159dfe53cf0SGnoCiYeH     }
160dfe53cf0SGnoCiYeH 
start(&self, core: &TtyCoreData) -> Result<(), SystemError>161dfe53cf0SGnoCiYeH     fn start(&self, core: &TtyCoreData) -> Result<(), SystemError> {
162dfe53cf0SGnoCiYeH         if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
163dfe53cf0SGnoCiYeH             return Err(SystemError::ENOSYS);
164dfe53cf0SGnoCiYeH         }
165dfe53cf0SGnoCiYeH 
166dfe53cf0SGnoCiYeH         let link = core.checked_link()?;
167dfe53cf0SGnoCiYeH 
168dfe53cf0SGnoCiYeH         let mut ctrl = core.contorl_info_irqsave();
169dfe53cf0SGnoCiYeH         ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_STOP);
170dfe53cf0SGnoCiYeH         ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_START);
171dfe53cf0SGnoCiYeH 
172dfe53cf0SGnoCiYeH         link.core()
173dfe53cf0SGnoCiYeH             .read_wq()
174dfe53cf0SGnoCiYeH             .wakeup_any(EPollEventType::EPOLLIN.bits() as u64);
175dfe53cf0SGnoCiYeH 
176dfe53cf0SGnoCiYeH         Ok(())
177dfe53cf0SGnoCiYeH     }
178dfe53cf0SGnoCiYeH 
stop(&self, core: &TtyCoreData) -> Result<(), SystemError>179dfe53cf0SGnoCiYeH     fn stop(&self, core: &TtyCoreData) -> Result<(), SystemError> {
180dfe53cf0SGnoCiYeH         if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
181dfe53cf0SGnoCiYeH             return Err(SystemError::ENOSYS);
182dfe53cf0SGnoCiYeH         }
183dfe53cf0SGnoCiYeH 
184dfe53cf0SGnoCiYeH         let link = core.checked_link()?;
185dfe53cf0SGnoCiYeH 
186dfe53cf0SGnoCiYeH         let mut ctrl = core.contorl_info_irqsave();
187dfe53cf0SGnoCiYeH         ctrl.pktstatus.remove(TtyPacketStatus::TIOCPKT_START);
188dfe53cf0SGnoCiYeH         ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_STOP);
189dfe53cf0SGnoCiYeH 
190dfe53cf0SGnoCiYeH         link.core()
191dfe53cf0SGnoCiYeH             .read_wq()
192dfe53cf0SGnoCiYeH             .wakeup_any(EPollEventType::EPOLLIN.bits() as u64);
193dfe53cf0SGnoCiYeH 
194dfe53cf0SGnoCiYeH         Ok(())
195dfe53cf0SGnoCiYeH     }
196dfe53cf0SGnoCiYeH 
flush_chars(&self, _tty: &TtyCoreData)197dfe53cf0SGnoCiYeH     fn flush_chars(&self, _tty: &TtyCoreData) {
198dfe53cf0SGnoCiYeH         // 不做处理
199dfe53cf0SGnoCiYeH     }
200dfe53cf0SGnoCiYeH 
lookup( &self, index: usize, priv_data: TtyDriverPrivateData, ) -> Result<Arc<TtyCore>, SystemError>201dfe53cf0SGnoCiYeH     fn lookup(
202dfe53cf0SGnoCiYeH         &self,
203dfe53cf0SGnoCiYeH         index: usize,
204dfe53cf0SGnoCiYeH         priv_data: TtyDriverPrivateData,
205dfe53cf0SGnoCiYeH     ) -> Result<Arc<TtyCore>, SystemError> {
206dfe53cf0SGnoCiYeH         if let TtyDriverPrivateData::Pty(false) = priv_data {
207dfe53cf0SGnoCiYeH             return pts_driver()
208dfe53cf0SGnoCiYeH                 .ttys()
209dfe53cf0SGnoCiYeH                 .get(&index)
210dfe53cf0SGnoCiYeH                 .cloned()
211dfe53cf0SGnoCiYeH                 .ok_or(SystemError::ENODEV);
212dfe53cf0SGnoCiYeH         }
213dfe53cf0SGnoCiYeH 
214dfe53cf0SGnoCiYeH         return Err(SystemError::ENOSYS);
215dfe53cf0SGnoCiYeH     }
216dfe53cf0SGnoCiYeH 
close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>217dfe53cf0SGnoCiYeH     fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
218dfe53cf0SGnoCiYeH         let driver = tty.core().driver();
219dfe53cf0SGnoCiYeH 
220dfe53cf0SGnoCiYeH         if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave {
221*9365e801SGnoCiYeH             driver.ttys().remove(&tty.core().index());
222dfe53cf0SGnoCiYeH             let pts_root_inode =
223dfe53cf0SGnoCiYeH                 ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
224dfe53cf0SGnoCiYeH             let _ = pts_root_inode.unlink(&tty.core().index().to_string());
225dfe53cf0SGnoCiYeH         }
226dfe53cf0SGnoCiYeH 
227dfe53cf0SGnoCiYeH         Ok(())
228dfe53cf0SGnoCiYeH     }
229*9365e801SGnoCiYeH 
resize( &self, tty: Arc<TtyCore>, winsize: crate::driver::tty::termios::WindowSize, ) -> Result<(), SystemError>230*9365e801SGnoCiYeH     fn resize(
231*9365e801SGnoCiYeH         &self,
232*9365e801SGnoCiYeH         tty: Arc<TtyCore>,
233*9365e801SGnoCiYeH         winsize: crate::driver::tty::termios::WindowSize,
234*9365e801SGnoCiYeH     ) -> Result<(), SystemError> {
235*9365e801SGnoCiYeH         let core = tty.core();
236*9365e801SGnoCiYeH         if *core.window_size() == winsize {
237*9365e801SGnoCiYeH             return Ok(());
238*9365e801SGnoCiYeH         }
239*9365e801SGnoCiYeH 
240*9365e801SGnoCiYeH         // TODO:向进程发送SIGWINCH信号
241*9365e801SGnoCiYeH 
242*9365e801SGnoCiYeH         *core.window_size_write() = winsize;
243*9365e801SGnoCiYeH         *core.link().unwrap().core().window_size_write() = winsize;
244*9365e801SGnoCiYeH 
245*9365e801SGnoCiYeH         Ok(())
246*9365e801SGnoCiYeH     }
247dfe53cf0SGnoCiYeH }
248dfe53cf0SGnoCiYeH 
ptmx_open( mut data: SpinLockGuard<FilePrivateData>, mode: &FileMode, ) -> Result<(), SystemError>249dfe53cf0SGnoCiYeH pub fn ptmx_open(
250dfe53cf0SGnoCiYeH     mut data: SpinLockGuard<FilePrivateData>,
251dfe53cf0SGnoCiYeH     mode: &FileMode,
252dfe53cf0SGnoCiYeH ) -> Result<(), SystemError> {
253dfe53cf0SGnoCiYeH     let pts_root_inode =
254dfe53cf0SGnoCiYeH         ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
255dfe53cf0SGnoCiYeH 
256dfe53cf0SGnoCiYeH     let fs = pts_root_inode
257dfe53cf0SGnoCiYeH         .fs()
258dfe53cf0SGnoCiYeH         .as_any_ref()
259dfe53cf0SGnoCiYeH         .downcast_ref::<MountFS>()
260dfe53cf0SGnoCiYeH         .unwrap()
261dfe53cf0SGnoCiYeH         .inner_filesystem();
262dfe53cf0SGnoCiYeH     let fsinfo = fs.as_any_ref().downcast_ref::<DevPtsFs>().unwrap();
263dfe53cf0SGnoCiYeH 
264dfe53cf0SGnoCiYeH     let index = fsinfo.alloc_index()?;
265dfe53cf0SGnoCiYeH 
266dfe53cf0SGnoCiYeH     let tty = TtyDriver::init_tty_device(ptm_driver(), index)?;
267dfe53cf0SGnoCiYeH 
268dfe53cf0SGnoCiYeH     // 设置privdata
269dfe53cf0SGnoCiYeH     *data = FilePrivateData::Tty(TtyFilePrivateData {
270dfe53cf0SGnoCiYeH         tty: tty.clone(),
271dfe53cf0SGnoCiYeH         mode: *mode,
272dfe53cf0SGnoCiYeH     });
273dfe53cf0SGnoCiYeH 
274dfe53cf0SGnoCiYeH     let core = tty.core();
275dfe53cf0SGnoCiYeH     core.flags_write().insert(TtyFlag::PTY_LOCK);
276dfe53cf0SGnoCiYeH 
277dfe53cf0SGnoCiYeH     let _ = pts_root_inode.create(
278dfe53cf0SGnoCiYeH         &index.to_string(),
279dfe53cf0SGnoCiYeH         FileType::CharDevice,
280dfe53cf0SGnoCiYeH         ModeType::from_bits_truncate(0x666),
281dfe53cf0SGnoCiYeH     )?;
282dfe53cf0SGnoCiYeH 
283dfe53cf0SGnoCiYeH     ptm_driver().driver_funcs().open(core)?;
284dfe53cf0SGnoCiYeH 
285dfe53cf0SGnoCiYeH     Ok(())
286dfe53cf0SGnoCiYeH }
287