Foreground process group should be none if the process group exits

This commit is contained in:
Jianfeng Jiang
2023-07-26 16:12:23 +08:00
committed by Tate, Hongliang Tian
parent dbfb2e1a62
commit a088acd0ec
3 changed files with 37 additions and 39 deletions

View File

@ -1,4 +1,5 @@
use crate::fs::utils::{IoEvents, Pollee, Poller}; use crate::fs::utils::{IoEvents, Pollee, Poller};
use crate::process::process_group::ProcessGroup;
use crate::process::signal::constants::{SIGINT, SIGQUIT}; use crate::process::signal::constants::{SIGINT, SIGQUIT};
use crate::{ use crate::{
prelude::*, prelude::*,
@ -19,7 +20,7 @@ pub struct LineDiscipline {
/// The read buffer /// The read buffer
read_buffer: SpinLock<StaticRb<u8, BUFFER_CAPACITY>>, read_buffer: SpinLock<StaticRb<u8, BUFFER_CAPACITY>>,
/// The foreground process group /// The foreground process group
foreground: SpinLock<Option<Pgid>>, foreground: SpinLock<Weak<ProcessGroup>>,
/// termios /// termios
termios: SpinLock<KernelTermios>, termios: SpinLock<KernelTermios>,
/// Pollee /// Pollee
@ -67,7 +68,7 @@ impl LineDiscipline {
Self { Self {
current_line: SpinLock::new(CurrentLine::new()), current_line: SpinLock::new(CurrentLine::new()),
read_buffer: SpinLock::new(StaticRb::default()), read_buffer: SpinLock::new(StaticRb::default()),
foreground: SpinLock::new(None), foreground: SpinLock::new(Weak::new()),
termios: SpinLock::new(KernelTermios::default()), termios: SpinLock::new(KernelTermios::default()),
pollee: Pollee::new(IoEvents::empty()), pollee: Pollee::new(IoEvents::empty()),
} }
@ -85,19 +86,17 @@ impl LineDiscipline {
if item == *termios.get_special_char(CC_C_CHAR::VINTR) { if item == *termios.get_special_char(CC_C_CHAR::VINTR) {
// type Ctrl + C, signal SIGINT // type Ctrl + C, signal SIGINT
if termios.contains_isig() { 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 kernel_signal = KernelSignal::new(SIGINT);
let fg_group = process_table::pgid_to_process_group(fg).unwrap(); foreground.kernel_signal(kernel_signal);
fg_group.kernel_signal(kernel_signal);
} }
} }
} else if item == *termios.get_special_char(CC_C_CHAR::VQUIT) { } else if item == *termios.get_special_char(CC_C_CHAR::VQUIT) {
// type Ctrl + \, signal SIGQUIT // type Ctrl + \, signal SIGQUIT
if termios.contains_isig() { 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 kernel_signal = KernelSignal::new(SIGQUIT);
let fg_group = process_table::pgid_to_process_group(fg).unwrap(); foreground.kernel_signal(kernel_signal);
fg_group.kernel_signal(kernel_signal);
} }
} }
} else if item == *termios.get_special_char(CC_C_CHAR::VKILL) { } 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<usize> { pub fn try_read(&self, dst: &mut [u8]) -> Result<usize> {
if !self.current_belongs_to_foreground() { if !self.current_can_read() {
return_errno!(Errno::EAGAIN); return_errno!(Errno::EAGAIN);
} }
@ -288,23 +287,19 @@ impl LineDiscipline {
todo!() todo!()
} }
/// whether the current process belongs to foreground process group /// Determine whether current process can read the line discipline. If current belongs to the foreground process group.
fn current_belongs_to_foreground(&self) -> bool { /// or the foreground process group is None, returns true.
fn current_can_read(&self) -> bool {
let current = current!(); let current = current!();
if let Some(fg_pgid) = *self.foreground.lock_irq_disabled() { let Some(foreground) = self.foreground.lock_irq_disabled().upgrade() else {
if let Some(process_group) = process_table::pgid_to_process_group(fg_pgid) { return true;
if process_group.contains_process(current.pid()) { };
return true; foreground.contains_process(current.pid())
}
}
}
false
} }
/// set foreground process group /// set foreground process group
pub fn set_fg(&self, fg_pgid: Pgid) { pub fn set_fg(&self, foreground: Weak<ProcessGroup>) {
*self.foreground.lock_irq_disabled() = Some(fg_pgid); *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. // 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() { if self.is_readable() {
self.pollee.add_events(IoEvents::IN); self.pollee.add_events(IoEvents::IN);
@ -313,7 +308,10 @@ impl LineDiscipline {
/// get foreground process group id /// get foreground process group id
pub fn fg_pgid(&self) -> Option<Pgid> { pub fn fg_pgid(&self) -> Option<Pgid> {
*self.foreground.lock_irq_disabled() self.foreground
.lock_irq_disabled()
.upgrade()
.and_then(|foreground| Some(foreground.pgid()))
} }
/// whether there is buffered data /// whether there is buffered data

View File

@ -5,7 +5,8 @@ use self::line_discipline::LineDiscipline;
use super::*; use super::*;
use crate::fs::utils::{IoEvents, IoctlCmd, Poller}; use crate::fs::utils::{IoEvents, IoctlCmd, Poller};
use crate::prelude::*; 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}; use crate::util::{read_val_from_user, write_val_to_user};
pub mod driver; pub mod driver;
@ -40,8 +41,8 @@ impl Tty {
} }
/// Set foreground process group /// Set foreground process group
pub fn set_fg(&self, pgid: Pgid) { pub fn set_fg(&self, process_group: Weak<ProcessGroup>) {
self.ldisc.set_fg(pgid); self.ldisc.set_fg(process_group);
} }
pub fn set_driver(&self, driver: Weak<TtyDriver>) { pub fn set_driver(&self, driver: Weak<TtyDriver>) {
@ -90,21 +91,20 @@ impl Device for Tty {
Ok(0) Ok(0)
} }
IoctlCmd::TIOCGPGRP => { IoctlCmd::TIOCGPGRP => {
// FIXME: Get the process group ID of the foreground process group on this terminal. let Some(fg_pgid) = self.ldisc.fg_pgid() else {
let fg_pgid = self.ldisc.fg_pgid(); return_errno_with_message!(Errno::ENOENT, "No fg process group")
match fg_pgid { };
None => return_errno_with_message!(Errno::ENOENT, "No fg process group"), debug!("fg_pgid = {}", fg_pgid);
Some(fg_pgid) => { write_val_to_user(arg, &fg_pgid)?;
debug!("fg_pgid = {}", fg_pgid); Ok(0)
write_val_to_user(arg, &fg_pgid)?;
Ok(0)
}
}
} }
IoctlCmd::TIOCSPGRP => { IoctlCmd::TIOCSPGRP => {
// Set the process group id of fg progress group // Set the process group id of fg progress group
let pgid = read_val_from_user::<i32>(arg)?; let pgid = read_val_from_user::<i32>(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) Ok(0)
} }
IoctlCmd::TCSETS => { IoctlCmd::TCSETS => {

View File

@ -144,10 +144,10 @@ impl Process {
debug_assert!(executable_path.starts_with('/')); debug_assert!(executable_path.starts_with('/'));
let process = Process::create_user_process(executable_path, argv, envp)?; let process = Process::create_user_process(executable_path, argv, envp)?;
// FIXME: How to determine the fg process group? // 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? // FIXME: tty should be a parameter?
let tty = get_n_tty(); let tty = get_n_tty();
tty.set_fg(pgid); tty.set_fg(process_group);
process.run(); process.run();
Ok(process) Ok(process)
} }