pub use crate::{
assign_child_to_windows_job, cancel_capture_reader, canonical_environment_pairs,
capture_reader_done, compat_shell_command, configure_exact_trace, configure_process_command,
configure_sync_contained_command, configure_sync_daemon_command,
configure_sync_daemon_command_with_inheritance, configure_trampoline_command,
current_executable_build_id, exact_trace_capability, exit_code, monitor_console_windows,
parent_has_console, prepare_capture_reader, set_process_name, shell_command,
soft_terminate_process_group, spawn_sync, spawn_sync_daemon,
spawn_sync_daemon_with_inheritance, start_descendant_monitor, start_exact_trace,
sync_child_native_handle, trampoline_exit_code, unix_mark_extra_fds_close_on_exec,
CaptureCancellation, TracedChild, WindowsJobHandle,
};
#[cfg(feature = "async-process")]
pub use crate::{
PlatformChild, PlatformEmergencySignal, PlatformLifecycle, PlatformOutput, PlatformStdin,
SpawnSpec, StreamMode,
};
#[cfg(feature = "process-inspection")]
pub use crate::{kill_tree, process_snapshot, process_snapshot_for_pid};
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct ProcessCommandConfig {
pub creation_flags: Option<u32>,
pub create_process_group: bool,
pub nice: Option<i32>,
pub address_space_limit_bytes: Option<u64>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct DaemonExecInheritance {
descriptor: i32,
}
impl DaemonExecInheritance {
#[allow(dead_code)]
pub(crate) fn preserving_descriptor(descriptor: i32) -> Self {
Self { descriptor }
}
#[allow(dead_code)]
pub(crate) fn descriptor(self) -> i32 {
self.descriptor
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ExactTraceCapability {
pub available: bool,
pub backend: &'static str,
pub reason: &'static str,
pub non_invasive_backend: &'static str,
pub non_invasive_grade: NonInvasiveObservationGrade,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum NonInvasiveObservationGrade {
KernelNotification,
KernelHintReconciled,
SnapshotInferred,
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct TraceOriginArtifact {
pub origin_pid: u32,
pub thread_id: u32,
pub architecture: String,
pub register_format: String,
pub executable: Option<std::path::PathBuf>,
pub registers: Vec<u8>,
pub stack_pointer: Option<u64>,
pub instruction_pointer: Option<u64>,
pub stack: Vec<u8>,
pub truncated: bool,
pub module_map: Vec<u8>,
pub module_map_truncated: bool,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ExactTraceEvent {
pub sequence: u64,
pub pid: u32,
pub parent_pid: Option<u32>,
pub parent_start_key: Option<u64>,
pub start_key: Option<u64>,
pub timestamp: std::time::SystemTime,
pub kind: ExactTraceEventKind,
pub executable: Option<std::path::PathBuf>,
pub argv: Option<Vec<std::ffi::OsString>>,
pub origin: Option<TraceOriginArtifact>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ExactTraceEventKind {
Spawn,
Exec,
Exit {
exit_code: Option<i32>,
signal: Option<i32>,
raw_status: i64,
},
Loss {
reason: String,
},
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum DescendantEvent {
Started {
pid: u32,
parent_pid: Option<u32>,
},
Exited(u32),
Completed,
}
pub struct DescendantMonitorStop {
stopped: std::sync::atomic::AtomicBool,
mutex: std::sync::Mutex<()>,
wake: std::sync::Condvar,
}
impl DescendantMonitorStop {
pub fn new() -> Self {
Self {
stopped: std::sync::atomic::AtomicBool::new(false),
mutex: std::sync::Mutex::new(()),
wake: std::sync::Condvar::new(),
}
}
pub fn is_stopped(&self) -> bool {
self.stopped.load(std::sync::atomic::Ordering::Acquire)
}
pub fn stop(&self) {
let _guard = self.mutex.lock().unwrap_or_else(|error| error.into_inner());
if !self.stopped.swap(true, std::sync::atomic::Ordering::AcqRel) {
self.wake.notify_all();
}
}
pub fn wait_timeout(&self, timeout: std::time::Duration) -> bool {
if self.is_stopped() {
return true;
}
let guard = self.mutex.lock().unwrap_or_else(|error| error.into_inner());
if self.is_stopped() {
return true;
}
let (_guard, _wait_result) = self
.wake
.wait_timeout(guard, timeout)
.unwrap_or_else(|error| error.into_inner());
self.is_stopped()
}
}
impl Default for DescendantMonitorStop {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Copy)]
pub enum CaptureStream {
Stdout,
Stderr,
}
#[derive(Debug, Clone)]
pub struct ConsoleWindowInfo {
pub pid: u32,
pub title: String,
pub hwnd: u64,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ProcessSnapshot {
pub pid: u32,
pub parent_pid: u32,
pub start_time_a: u64,
pub start_time_b: u64,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum SyncEnvironment {
Inherit,
Explicit(Vec<(std::ffi::OsString, std::ffi::OsString)>),
}
pub struct SpawnStdio<'a> {
pub stdin: StdioSource<'a>,
pub stdout: StdioSource<'a>,
pub stderr: StdioSource<'a>,
pub drain_timeout: Option<std::time::Duration>,
pub show_console: bool,
}
impl Default for SpawnStdio<'_> {
fn default() -> Self {
Self {
stdin: StdioSource::Null,
stdout: StdioSource::Parent,
stderr: StdioSource::Parent,
drain_timeout: Some(std::time::Duration::from_secs(2)),
show_console: false,
}
}
}
pub struct DaemonStdio<'a> {
pub stdout: DaemonStdioSource<'a>,
pub stderr: DaemonStdioSource<'a>,
}
impl Default for DaemonStdio<'_> {
fn default() -> Self {
Self {
stdout: DaemonStdioSource::Null,
stderr: DaemonStdioSource::Null,
}
}
}
pub enum DaemonStdioSource<'a> {
Null,
File(&'a std::fs::File),
}
pub enum StdioSource<'a> {
Null,
Parent,
File(&'a std::fs::File),
Pipe,
}
pub struct DaemonChild {
pub(crate) pid: u32,
pub(crate) inner: Box<dyn DaemonChildControl>,
}
pub(crate) trait DaemonChildControl:
Send + Sync + std::panic::UnwindSafe + std::panic::RefUnwindSafe
{
fn kill(&mut self) -> std::io::Result<()>;
fn wait(&mut self) -> std::io::Result<i32>;
fn try_wait(&mut self) -> std::io::Result<Option<i32>>;
}
impl DaemonChild {
pub fn id(&self) -> u32 {
self.pid
}
pub fn kill(&mut self) -> std::io::Result<()> {
self.inner.kill()
}
pub fn wait(&mut self) -> std::io::Result<i32> {
self.inner.wait()
}
pub fn try_wait(&mut self) -> std::io::Result<Option<i32>> {
self.inner.try_wait()
}
}
pub struct SpawnedChild {
pub stdin: Option<std::process::ChildStdin>,
pub stdout: Option<std::process::ChildStdout>,
pub stderr: Option<std::process::ChildStderr>,
pub(crate) pid: u32,
pub(crate) inner: Box<dyn SpawnedChildControl>,
}
pub(crate) trait SpawnedChildControl:
Send + Sync + std::panic::UnwindSafe + std::panic::RefUnwindSafe
{
fn kill(&mut self) -> std::io::Result<()>;
fn wait(&mut self) -> std::io::Result<i32>;
fn try_wait(&mut self) -> std::io::Result<Option<i32>>;
fn shutdown(&mut self);
}
impl SpawnedChild {
pub fn id(&self) -> u32 {
self.pid
}
pub fn kill(&mut self) -> std::io::Result<()> {
self.inner.kill()
}
pub fn wait(&mut self) -> std::io::Result<i32> {
self.inner.wait()
}
pub fn try_wait(&mut self) -> std::io::Result<Option<i32>> {
self.inner.try_wait()
}
}
impl Drop for SpawnedChild {
fn drop(&mut self) {
self.inner.shutdown();
}
}
#[derive(Clone, Copy)]
pub enum ObserverScope {
SystemWide,
LaunchedProcessTree,
}
#[derive(Clone, Copy)]
pub enum ObserverCategory {
File,
Network,
Process,
}
#[derive(Clone, Copy)]
pub enum ObserverSupport {
Supported,
Partial,
Unavailable,
}
#[derive(Clone, Copy)]
pub struct ObserverBackend {
pub support: ObserverSupport,
pub backend: &'static str,
pub reason: &'static str,
}
pub use crate::platform_imp::observer_backend;
pub use crate::platform_imp::read_process_cmdline;
pub use crate::platform_imp::read_process_file_handles;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnixSignalKind {
Interrupt,
Terminate,
Kill,
}
pub use crate::{
unix_set_priority, unix_signal_process, unix_signal_process_group, unix_signal_raw,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OwnerDeathCleanup {
OwnerDeathSignal,
KillOnOwnerHandleClose,
AlreadyContained,
SupervisorRequired,
Unsupported,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OwnerDeathCleanupStage {
RequestSignal,
CreateContainer,
JoinContainer,
}
#[derive(Debug)]
pub struct OwnerDeathCleanupError {
pub stage: OwnerDeathCleanupStage,
pub source: std::io::Error,
}
impl std::fmt::Display for OwnerDeathCleanupError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}: {}", self.stage, self.source)
}
}
impl std::error::Error for OwnerDeathCleanupError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.source)
}
}
pub use crate::{
process_install_owner_death_cleanup as install_owner_death_cleanup,
process_owner_death_cleanup_target as owner_death_cleanup_target,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProcessInspectErrorKind {
InvalidPid,
NotFound,
Unsupported,
Host,
}
#[derive(Debug)]
pub struct ProcessInspectError {
pub kind: ProcessInspectErrorKind,
pub source: std::io::Error,
}
impl ProcessInspectError {
pub fn last_os_error(kind: ProcessInspectErrorKind) -> Self {
Self {
kind,
source: std::io::Error::last_os_error(),
}
}
pub fn stated(kind: ProcessInspectErrorKind, message: &str) -> Self {
Self {
kind,
source: std::io::Error::other(message.to_string()),
}
}
}
impl std::fmt::Display for ProcessInspectError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}: {}", self.kind, self.source)
}
}
impl std::error::Error for ProcessInspectError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.source)
}
}
pub use crate::{
process_executable_path as executable_path, process_force_kill as force_kill,
process_same_executable_path as same_executable_path,
process_signal_terminate as signal_terminate, ProcessLiveness,
};
pub struct ShutdownRequest {
flag: &'static std::sync::atomic::AtomicBool,
}
impl ShutdownRequest {
pub fn watching(flag: &'static std::sync::atomic::AtomicBool) -> Self {
Self { flag }
}
pub fn requested(&self) -> bool {
self.flag.load(std::sync::atomic::Ordering::Relaxed)
}
}
impl std::fmt::Debug for ShutdownRequest {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ShutdownRequest")
.field("requested", &self.requested())
.finish()
}
}
pub use crate::process_install_shutdown_request_handler as install_shutdown_request_handler;
pub use crate::{
process_can_replace_current_image as can_replace_current_image,
process_replace_current_image as replace_current_image,
};