mirror of
https://github.com/nushell/nushell.git
synced 2025-08-19 23:38:37 +02:00
config
commands now add frozen jobs to job table (#15556)
# Description `config nu/env` used to ignore the frozen wait job status response and did not add processes to the job table when they were frozen. This PR refactors the PostWaitCallback used in run_external and allows frozen processes spawned by `config_.rs` to be added to the job table. Closes #15389 # User-Facing Changes `config nu` now respects the job freezing semantics. # Tests + Formatting This behavior can be verified by running `config nu` or `config env`, hitting Ctrl-Z, and then running `job list`.
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
use crate::{byte_stream::convert_file, shell_error::io::IoError, ShellError, Span};
|
||||
use crate::{
|
||||
byte_stream::convert_file,
|
||||
engine::{EngineState, FrozenJob, Job},
|
||||
shell_error::io::IoError,
|
||||
ShellError, Span,
|
||||
};
|
||||
use nu_system::{ExitStatus, ForegroundChild, ForegroundWaitStatus};
|
||||
|
||||
use os_pipe::PipeReader;
|
||||
@@ -166,8 +171,45 @@ pub struct ChildProcess {
|
||||
span: Span,
|
||||
}
|
||||
|
||||
/// A wrapper for a closure that runs once the shell finishes waiting on the process.
|
||||
pub struct PostWaitCallback(pub Box<dyn FnOnce(ForegroundWaitStatus) + Send>);
|
||||
|
||||
impl PostWaitCallback {
|
||||
pub fn new<F>(f: F) -> Self
|
||||
where
|
||||
F: FnOnce(ForegroundWaitStatus) + Send + 'static,
|
||||
{
|
||||
PostWaitCallback(Box::new(f))
|
||||
}
|
||||
|
||||
/// Creates a PostWaitCallback that checks creates a frozen job in the job table
|
||||
/// if the incoming wait status indicates that the job was frozen.
|
||||
///
|
||||
/// If `child_pid` is provided, the returned callback will also remove
|
||||
/// it from the pid list of the current running job.
|
||||
pub fn for_job_control(engine_state: &EngineState, child_pid: Option<u32>) -> Self {
|
||||
let this_job = engine_state.current_thread_job.clone();
|
||||
let jobs = engine_state.jobs.clone();
|
||||
let is_interactive = engine_state.is_interactive;
|
||||
|
||||
PostWaitCallback::new(move |status| {
|
||||
if let (Some(this_job), Some(child_pid)) = (this_job, child_pid) {
|
||||
this_job.remove_pid(child_pid);
|
||||
}
|
||||
|
||||
if let ForegroundWaitStatus::Frozen(unfreeze) = status {
|
||||
let mut jobs = jobs.lock().expect("jobs lock is poisoned!");
|
||||
|
||||
let job_id = jobs.add_job(Job::Frozen(FrozenJob { unfreeze }));
|
||||
|
||||
if is_interactive {
|
||||
println!("\nJob {} is frozen", job_id.get());
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for PostWaitCallback {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "<wait_callback>")
|
||||
|
Reference in New Issue
Block a user