diff --git a/services/libs/jinux-std/src/device/tty/line_discipline.rs b/services/libs/jinux-std/src/device/tty/line_discipline.rs index f130bd437..9efde2330 100644 --- a/services/libs/jinux-std/src/device/tty/line_discipline.rs +++ b/services/libs/jinux-std/src/device/tty/line_discipline.rs @@ -1,4 +1,5 @@ use crate::fs::utils::{IoEvents, Pollee, Poller}; +use crate::process::process_group::ProcessGroup; use crate::process::signal::constants::{SIGINT, SIGQUIT}; use crate::{ prelude::*, @@ -19,7 +20,7 @@ pub struct LineDiscipline { /// The read buffer read_buffer: SpinLock>, /// The foreground process group - foreground: SpinLock>, + foreground: SpinLock>, /// termios termios: SpinLock, /// Pollee @@ -67,7 +68,7 @@ impl LineDiscipline { Self { current_line: SpinLock::new(CurrentLine::new()), read_buffer: SpinLock::new(StaticRb::default()), - foreground: SpinLock::new(None), + foreground: SpinLock::new(Weak::new()), termios: SpinLock::new(KernelTermios::default()), pollee: Pollee::new(IoEvents::empty()), } @@ -85,19 +86,17 @@ impl LineDiscipline { if item == *termios.get_special_char(CC_C_CHAR::VINTR) { // type Ctrl + C, signal SIGINT if termios.contains_isig() { - if let Some(fg) = *self.foreground.lock_irq_disabled() { + if let Some(foreground) = self.foreground.lock_irq_disabled().upgrade() { let kernel_signal = KernelSignal::new(SIGINT); - let fg_group = process_table::pgid_to_process_group(fg).unwrap(); - fg_group.kernel_signal(kernel_signal); + foreground.kernel_signal(kernel_signal); } } } else if item == *termios.get_special_char(CC_C_CHAR::VQUIT) { // type Ctrl + \, signal SIGQUIT if termios.contains_isig() { - if let Some(fg) = *self.foreground.lock_irq_disabled() { + if let Some(foreground) = self.foreground.lock_irq_disabled().upgrade() { let kernel_signal = KernelSignal::new(SIGQUIT); - let fg_group = process_table::pgid_to_process_group(fg).unwrap(); - fg_group.kernel_signal(kernel_signal); + foreground.kernel_signal(kernel_signal); } } } else if item == *termios.get_special_char(CC_C_CHAR::VKILL) { @@ -196,7 +195,7 @@ impl LineDiscipline { } pub fn try_read(&self, dst: &mut [u8]) -> Result { - if !self.current_belongs_to_foreground() { + if !self.current_can_read() { return_errno!(Errno::EAGAIN); } @@ -288,23 +287,19 @@ impl LineDiscipline { todo!() } - /// whether the current process belongs to foreground process group - fn current_belongs_to_foreground(&self) -> bool { + /// Determine whether current process can read the line discipline. If current belongs to the foreground process group. + /// or the foreground process group is None, returns true. + fn current_can_read(&self) -> bool { let current = current!(); - if let Some(fg_pgid) = *self.foreground.lock_irq_disabled() { - if let Some(process_group) = process_table::pgid_to_process_group(fg_pgid) { - if process_group.contains_process(current.pid()) { - return true; - } - } - } - - false + let Some(foreground) = self.foreground.lock_irq_disabled().upgrade() else { + return true; + }; + foreground.contains_process(current.pid()) } /// set foreground process group - pub fn set_fg(&self, fg_pgid: Pgid) { - *self.foreground.lock_irq_disabled() = Some(fg_pgid); + pub fn set_fg(&self, foreground: Weak) { + *self.foreground.lock_irq_disabled() = foreground; // Some background processes may be waiting on the wait queue, when set_fg, the background processes may be able to read. if self.is_readable() { self.pollee.add_events(IoEvents::IN); @@ -313,7 +308,10 @@ impl LineDiscipline { /// get foreground process group id pub fn fg_pgid(&self) -> Option { - *self.foreground.lock_irq_disabled() + self.foreground + .lock_irq_disabled() + .upgrade() + .and_then(|foreground| Some(foreground.pgid())) } /// whether there is buffered data diff --git a/services/libs/jinux-std/src/device/tty/mod.rs b/services/libs/jinux-std/src/device/tty/mod.rs index 2419c12ae..6db7bf530 100644 --- a/services/libs/jinux-std/src/device/tty/mod.rs +++ b/services/libs/jinux-std/src/device/tty/mod.rs @@ -5,7 +5,8 @@ use self::line_discipline::LineDiscipline; use super::*; use crate::fs::utils::{IoEvents, IoctlCmd, Poller}; use crate::prelude::*; -use crate::process::Pgid; +use crate::process::process_group::ProcessGroup; +use crate::process::{process_table, Pgid}; use crate::util::{read_val_from_user, write_val_to_user}; pub mod driver; @@ -40,8 +41,8 @@ impl Tty { } /// Set foreground process group - pub fn set_fg(&self, pgid: Pgid) { - self.ldisc.set_fg(pgid); + pub fn set_fg(&self, process_group: Weak) { + self.ldisc.set_fg(process_group); } pub fn set_driver(&self, driver: Weak) { @@ -90,21 +91,20 @@ impl Device for Tty { Ok(0) } IoctlCmd::TIOCGPGRP => { - // FIXME: Get the process group ID of the foreground process group on this terminal. - let fg_pgid = self.ldisc.fg_pgid(); - match fg_pgid { - None => return_errno_with_message!(Errno::ENOENT, "No fg process group"), - Some(fg_pgid) => { - debug!("fg_pgid = {}", fg_pgid); - write_val_to_user(arg, &fg_pgid)?; - Ok(0) - } - } + let Some(fg_pgid) = self.ldisc.fg_pgid() else { + return_errno_with_message!(Errno::ENOENT, "No fg process group") + }; + debug!("fg_pgid = {}", fg_pgid); + write_val_to_user(arg, &fg_pgid)?; + Ok(0) } IoctlCmd::TIOCSPGRP => { // Set the process group id of fg progress group let pgid = read_val_from_user::(arg)?; - self.ldisc.set_fg(pgid); + match process_table::pgid_to_process_group(pgid) { + None => self.ldisc.set_fg(Weak::new()), + Some(process_group) => self.ldisc.set_fg(Arc::downgrade(&process_group)), + } Ok(0) } IoctlCmd::TCSETS => { diff --git a/services/libs/jinux-std/src/process/mod.rs b/services/libs/jinux-std/src/process/mod.rs index 52785e2fd..03c75de5e 100644 --- a/services/libs/jinux-std/src/process/mod.rs +++ b/services/libs/jinux-std/src/process/mod.rs @@ -144,10 +144,10 @@ impl Process { debug_assert!(executable_path.starts_with('/')); let process = Process::create_user_process(executable_path, argv, envp)?; // FIXME: How to determine the fg process group? - let pgid = process.pgid(); + let process_group = Weak::clone(&process.process_group.lock()); // FIXME: tty should be a parameter? let tty = get_n_tty(); - tty.set_fg(pgid); + tty.set_fg(process_group); process.run(); Ok(process) }