mirror of
https://github.com/nushell/nushell.git
synced 2025-02-18 03:21:05 +01:00
Some broken doc links I saw when compiling with `cargo +stable doc --no-deps --document-private-items --workspace --open`
91 lines
2.9 KiB
Rust
91 lines
2.9 KiB
Rust
use std::sync::{atomic::AtomicU32, Arc, Mutex, MutexGuard};
|
|
|
|
use nu_protocol::{ShellError, Span};
|
|
use nu_system::ForegroundGuard;
|
|
|
|
/// Provides a utility interface for a plugin interface to manage the process the plugin is running
|
|
/// in.
|
|
#[derive(Debug)]
|
|
pub(crate) struct PluginProcess {
|
|
pid: u32,
|
|
mutable: Mutex<MutablePart>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct MutablePart {
|
|
foreground_guard: Option<ForegroundGuard>,
|
|
}
|
|
|
|
impl PluginProcess {
|
|
/// Manage a plugin process.
|
|
pub(crate) fn new(pid: u32) -> PluginProcess {
|
|
PluginProcess {
|
|
pid,
|
|
mutable: Mutex::new(MutablePart {
|
|
foreground_guard: None,
|
|
}),
|
|
}
|
|
}
|
|
|
|
/// The process ID of the plugin.
|
|
pub(crate) fn pid(&self) -> u32 {
|
|
self.pid
|
|
}
|
|
|
|
fn lock_mutable(&self) -> Result<MutexGuard<MutablePart>, ShellError> {
|
|
self.mutable.lock().map_err(|_| ShellError::NushellFailed {
|
|
msg: "the PluginProcess mutable lock has been poisoned".into(),
|
|
})
|
|
}
|
|
|
|
/// Move the plugin process to the foreground. See [`ForegroundGuard::new`].
|
|
///
|
|
/// This produces an error if the plugin process was already in the foreground.
|
|
///
|
|
/// Returns `Some()` on Unix with the process group ID if the plugin process will need to join
|
|
/// another process group to be part of the foreground.
|
|
pub(crate) fn enter_foreground(
|
|
&self,
|
|
span: Span,
|
|
pipeline_state: &Arc<(AtomicU32, AtomicU32)>,
|
|
) -> Result<Option<u32>, ShellError> {
|
|
let pid = self.pid;
|
|
let mut mutable = self.lock_mutable()?;
|
|
if mutable.foreground_guard.is_none() {
|
|
let guard = ForegroundGuard::new(pid, pipeline_state).map_err(|err| {
|
|
ShellError::GenericError {
|
|
error: "Failed to enter foreground".into(),
|
|
msg: err.to_string(),
|
|
span: Some(span),
|
|
help: None,
|
|
inner: vec![],
|
|
}
|
|
})?;
|
|
let pgrp = guard.pgrp();
|
|
mutable.foreground_guard = Some(guard);
|
|
Ok(pgrp)
|
|
} else {
|
|
Err(ShellError::GenericError {
|
|
error: "Can't enter foreground".into(),
|
|
msg: "this plugin is already running in the foreground".into(),
|
|
span: Some(span),
|
|
help: Some(
|
|
"you may be trying to run the command in parallel, or this may be a bug in \
|
|
the plugin"
|
|
.into(),
|
|
),
|
|
inner: vec![],
|
|
})
|
|
}
|
|
}
|
|
|
|
/// Move the plugin process out of the foreground. See [`ForegroundGuard`].
|
|
///
|
|
/// This is a no-op if the plugin process was already in the background.
|
|
pub(crate) fn exit_foreground(&self) -> Result<(), ShellError> {
|
|
let mut mutable = self.lock_mutable()?;
|
|
drop(mutable.foreground_guard.take());
|
|
Ok(())
|
|
}
|
|
}
|