mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-14 15:56:47 +00:00
Foreground process group should be none if the process group exits
This commit is contained in:
parent
dbfb2e1a62
commit
a088acd0ec
@ -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
|
||||
|
@ -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 => {
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user