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