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::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<StaticRb<u8, BUFFER_CAPACITY>>,
/// The foreground process group
foreground: SpinLock<Option<Pgid>>,
foreground: SpinLock<Weak<ProcessGroup>>,
/// termios
termios: SpinLock<KernelTermios>,
/// 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<usize> {
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<ProcessGroup>) {
*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<Pgid> {
*self.foreground.lock_irq_disabled()
self.foreground
.lock_irq_disabled()
.upgrade()
.and_then(|foreground| Some(foreground.pgid()))
}
/// whether there is buffered data

View File

@ -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<ProcessGroup>) {
self.ldisc.set_fg(process_group);
}
pub fn set_driver(&self, driver: Weak<TtyDriver>) {
@ -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::<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)
}
IoctlCmd::TCSETS => {

View File

@ -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)
}