xref: /DragonOS/kernel/src/driver/tty/tty_job_control.rs (revision 52da9a59374752b4d01907b052135a0d317781dd)
1*52da9a59SGnoCiYeH use alloc::sync::Arc;
2*52da9a59SGnoCiYeH use system_error::SystemError;
3*52da9a59SGnoCiYeH 
4*52da9a59SGnoCiYeH use crate::{
5*52da9a59SGnoCiYeH     arch::ipc::signal::{SigSet, Signal},
6*52da9a59SGnoCiYeH     mm::VirtAddr,
7*52da9a59SGnoCiYeH     process::{Pid, ProcessManager},
8*52da9a59SGnoCiYeH     syscall::{user_access::UserBufferWriter, Syscall},
9*52da9a59SGnoCiYeH };
10*52da9a59SGnoCiYeH 
11*52da9a59SGnoCiYeH use super::tty_core::{TtyCore, TtyIoctlCmd};
12*52da9a59SGnoCiYeH 
13*52da9a59SGnoCiYeH pub struct TtyJobCtrlManager;
14*52da9a59SGnoCiYeH 
15*52da9a59SGnoCiYeH impl TtyJobCtrlManager {
16*52da9a59SGnoCiYeH     /// ### 设置当前进程的tty
17*52da9a59SGnoCiYeH     pub fn proc_set_tty(tty: Arc<TtyCore>) {
18*52da9a59SGnoCiYeH         let core = tty.core();
19*52da9a59SGnoCiYeH         let mut ctrl = core.contorl_info_irqsave();
20*52da9a59SGnoCiYeH         let pcb = ProcessManager::current_pcb();
21*52da9a59SGnoCiYeH 
22*52da9a59SGnoCiYeH         // todo 目前将pgid设置为pid
23*52da9a59SGnoCiYeH         ctrl.pgid = Some(pcb.pid());
24*52da9a59SGnoCiYeH         ctrl.session = Some(pcb.pid());
25*52da9a59SGnoCiYeH 
26*52da9a59SGnoCiYeH         assert!(pcb.sig_info_irqsave().tty().is_none());
27*52da9a59SGnoCiYeH 
28*52da9a59SGnoCiYeH         let mut singal = pcb.sig_info_mut();
29*52da9a59SGnoCiYeH         drop(ctrl);
30*52da9a59SGnoCiYeH         singal.set_tty(tty);
31*52da9a59SGnoCiYeH     }
32*52da9a59SGnoCiYeH 
33*52da9a59SGnoCiYeH     /// ### 检查tty
34*52da9a59SGnoCiYeH     pub fn tty_check_change(tty: Arc<TtyCore>, sig: Signal) -> Result<(), SystemError> {
35*52da9a59SGnoCiYeH         let pcb = ProcessManager::current_pcb();
36*52da9a59SGnoCiYeH 
37*52da9a59SGnoCiYeH         if pcb.sig_info().tty().is_none() || !Arc::ptr_eq(&pcb.sig_info().tty().unwrap(), &tty) {
38*52da9a59SGnoCiYeH             return Ok(());
39*52da9a59SGnoCiYeH         }
40*52da9a59SGnoCiYeH 
41*52da9a59SGnoCiYeH         let core = tty.core();
42*52da9a59SGnoCiYeH         let ctrl = core.contorl_info_irqsave();
43*52da9a59SGnoCiYeH 
44*52da9a59SGnoCiYeH         // todo pgid
45*52da9a59SGnoCiYeH         let pgid = pcb.pid();
46*52da9a59SGnoCiYeH         let tty_pgid = ctrl.pgid;
47*52da9a59SGnoCiYeH 
48*52da9a59SGnoCiYeH         if tty_pgid.is_some() && tty_pgid.unwrap() != pgid {
49*52da9a59SGnoCiYeH             if pcb
50*52da9a59SGnoCiYeH                 .sig_info_irqsave()
51*52da9a59SGnoCiYeH                 .sig_block()
52*52da9a59SGnoCiYeH                 .contains(SigSet::from_bits_truncate(1 << sig as u64))
53*52da9a59SGnoCiYeH                 || pcb.sig_struct_irqsave().handlers[sig as usize].is_ignore()
54*52da9a59SGnoCiYeH             {
55*52da9a59SGnoCiYeH                 // 忽略该信号
56*52da9a59SGnoCiYeH                 if sig == Signal::SIGTTIN {
57*52da9a59SGnoCiYeH                     return Err(SystemError::EIO);
58*52da9a59SGnoCiYeH                 }
59*52da9a59SGnoCiYeH             } else {
60*52da9a59SGnoCiYeH                 // 暂时使用kill而不是killpg
61*52da9a59SGnoCiYeH                 Syscall::kill(pgid, sig as i32)?;
62*52da9a59SGnoCiYeH                 return Err(SystemError::ERESTART);
63*52da9a59SGnoCiYeH             }
64*52da9a59SGnoCiYeH         }
65*52da9a59SGnoCiYeH 
66*52da9a59SGnoCiYeH         Ok(())
67*52da9a59SGnoCiYeH     }
68*52da9a59SGnoCiYeH 
69*52da9a59SGnoCiYeH     pub fn job_ctrl_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
70*52da9a59SGnoCiYeH         match cmd {
71*52da9a59SGnoCiYeH             TtyIoctlCmd::TIOCSPGRP => {
72*52da9a59SGnoCiYeH                 match Self::tty_check_change(tty.clone(), Signal::SIGTTOU) {
73*52da9a59SGnoCiYeH                     Ok(_) => {}
74*52da9a59SGnoCiYeH                     Err(e) => {
75*52da9a59SGnoCiYeH                         if e == SystemError::EIO {
76*52da9a59SGnoCiYeH                             return Err(SystemError::ENOTTY);
77*52da9a59SGnoCiYeH                         }
78*52da9a59SGnoCiYeH                         return Err(e);
79*52da9a59SGnoCiYeH                     }
80*52da9a59SGnoCiYeH                 };
81*52da9a59SGnoCiYeH 
82*52da9a59SGnoCiYeH                 // let user_reader = UserBufferReader::new(
83*52da9a59SGnoCiYeH                 //     VirtAddr::new(arg).as_ptr::<usize>(),
84*52da9a59SGnoCiYeH                 //     core::mem::size_of::<usize>(),
85*52da9a59SGnoCiYeH                 //     true,
86*52da9a59SGnoCiYeH                 // )?;
87*52da9a59SGnoCiYeH 
88*52da9a59SGnoCiYeH                 // let pgrp = user_reader.read_one_from_user::<usize>(0)?;
89*52da9a59SGnoCiYeH 
90*52da9a59SGnoCiYeH                 let current = ProcessManager::current_pcb();
91*52da9a59SGnoCiYeH 
92*52da9a59SGnoCiYeH                 let mut ctrl = tty.core().contorl_info_irqsave();
93*52da9a59SGnoCiYeH 
94*52da9a59SGnoCiYeH                 if current.sig_info().tty().is_none()
95*52da9a59SGnoCiYeH                     || !Arc::ptr_eq(&current.sig_info().tty().clone().unwrap(), &tty)
96*52da9a59SGnoCiYeH                     || ctrl.session.is_none()
97*52da9a59SGnoCiYeH                     || ctrl.session.unwrap() != current.pid()
98*52da9a59SGnoCiYeH                 {
99*52da9a59SGnoCiYeH                     return Err(SystemError::ENOTTY);
100*52da9a59SGnoCiYeH                 }
101*52da9a59SGnoCiYeH 
102*52da9a59SGnoCiYeH                 ctrl.pgid = Some(Pid::new(arg));
103*52da9a59SGnoCiYeH 
104*52da9a59SGnoCiYeH                 return Ok(0);
105*52da9a59SGnoCiYeH             }
106*52da9a59SGnoCiYeH 
107*52da9a59SGnoCiYeH             TtyIoctlCmd::TIOCGPGRP => {
108*52da9a59SGnoCiYeH                 let current = ProcessManager::current_pcb();
109*52da9a59SGnoCiYeH                 if current.sig_info().tty().is_some()
110*52da9a59SGnoCiYeH                     && !Arc::ptr_eq(&current.sig_info().tty().unwrap(), &tty)
111*52da9a59SGnoCiYeH                 {
112*52da9a59SGnoCiYeH                     return Err(SystemError::ENOTTY);
113*52da9a59SGnoCiYeH                 }
114*52da9a59SGnoCiYeH 
115*52da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
116*52da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<i32>(),
117*52da9a59SGnoCiYeH                     core::mem::size_of::<i32>(),
118*52da9a59SGnoCiYeH                     true,
119*52da9a59SGnoCiYeH                 )?;
120*52da9a59SGnoCiYeH 
121*52da9a59SGnoCiYeH                 user_writer.copy_one_to_user(
122*52da9a59SGnoCiYeH                     &(tty
123*52da9a59SGnoCiYeH                         .core()
124*52da9a59SGnoCiYeH                         .contorl_info_irqsave()
125*52da9a59SGnoCiYeH                         .pgid
126*52da9a59SGnoCiYeH                         .unwrap_or(Pid::new(0))
127*52da9a59SGnoCiYeH                         .data() as i32),
128*52da9a59SGnoCiYeH                     0,
129*52da9a59SGnoCiYeH                 )?;
130*52da9a59SGnoCiYeH 
131*52da9a59SGnoCiYeH                 return Ok(0);
132*52da9a59SGnoCiYeH             }
133*52da9a59SGnoCiYeH 
134*52da9a59SGnoCiYeH             _ => {
135*52da9a59SGnoCiYeH                 return Err(SystemError::ENOIOCTLCMD);
136*52da9a59SGnoCiYeH             }
137*52da9a59SGnoCiYeH         }
138*52da9a59SGnoCiYeH     }
139*52da9a59SGnoCiYeH }
140