1pub use crate::{
4 assign_child_to_windows_job, cancel_capture_reader, canonical_environment_pairs,
5 capture_reader_done, compat_shell_command, configure_exact_trace, configure_process_command,
6 configure_sync_contained_command, configure_sync_daemon_command, configure_trampoline_command,
7 current_executable_build_id, exact_trace_capability, exit_code, monitor_console_windows,
8 parent_has_console, prepare_capture_reader, set_process_name, shell_command,
9 soft_terminate_process_group, spawn_sync, spawn_sync_daemon, start_descendant_monitor,
10 start_exact_trace, sync_child_native_handle, trampoline_exit_code,
11 unix_mark_extra_fds_close_on_exec, CaptureCancellation, TracedChild, WindowsJobHandle,
12};
13
14#[cfg(feature = "async-process")]
15pub use crate::{
16 PlatformChild, PlatformEmergencySignal, PlatformLifecycle, PlatformOutput, PlatformStdin,
17 SpawnSpec, StreamMode,
18};
19
20#[cfg(feature = "process-inspection")]
21pub use crate::{kill_tree, process_snapshot, process_snapshot_for_pid};
22
23#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
25pub struct ProcessCommandConfig {
26 pub creation_flags: Option<u32>,
27 pub create_process_group: bool,
28 pub nice: Option<i32>,
29 pub address_space_limit_bytes: Option<u64>,
30}
31
32#[derive(Clone, Debug, Eq, PartialEq)]
34pub struct ExactTraceCapability {
35 pub available: bool,
36 pub backend: &'static str,
37 pub reason: &'static str,
38 pub non_invasive_backend: &'static str,
39 pub non_invasive_grade: NonInvasiveObservationGrade,
40}
41
42#[derive(Clone, Copy, Debug, Eq, PartialEq)]
43pub enum NonInvasiveObservationGrade {
44 KernelNotification,
45 KernelHintReconciled,
46 SnapshotInferred,
47}
48
49#[derive(Clone, Debug, Default, Eq, PartialEq)]
51pub struct TraceOriginArtifact {
52 pub origin_pid: u32,
53 pub thread_id: u32,
54 pub architecture: String,
55 pub register_format: String,
56 pub executable: Option<std::path::PathBuf>,
57 pub registers: Vec<u8>,
58 pub stack_pointer: Option<u64>,
59 pub instruction_pointer: Option<u64>,
60 pub stack: Vec<u8>,
61 pub truncated: bool,
62 pub module_map: Vec<u8>,
63 pub module_map_truncated: bool,
64}
65
66#[derive(Clone, Debug, Eq, PartialEq)]
68pub struct ExactTraceEvent {
69 pub sequence: u64,
70 pub pid: u32,
71 pub parent_pid: Option<u32>,
72 pub parent_start_key: Option<u64>,
73 pub start_key: Option<u64>,
74 pub timestamp: std::time::SystemTime,
75 pub kind: ExactTraceEventKind,
76 pub executable: Option<std::path::PathBuf>,
77 pub argv: Option<Vec<std::ffi::OsString>>,
78 pub origin: Option<TraceOriginArtifact>,
79}
80
81#[derive(Clone, Debug, Eq, PartialEq)]
82pub enum ExactTraceEventKind {
83 Spawn,
84 Exec,
85 Exit {
86 exit_code: Option<i32>,
87 signal: Option<i32>,
88 raw_status: i64,
89 },
90 Loss {
91 reason: String,
92 },
93}
94
95#[derive(Clone, Copy, Debug, Eq, PartialEq)]
97pub enum DescendantEvent {
98 Started {
99 pid: u32,
100 parent_pid: Option<u32>,
106 },
107 Exited(u32),
108 Completed,
111}
112
113pub struct DescendantMonitorStop {
115 stopped: std::sync::atomic::AtomicBool,
116 mutex: std::sync::Mutex<()>,
117 wake: std::sync::Condvar,
118}
119
120impl DescendantMonitorStop {
121 pub fn new() -> Self {
123 Self {
124 stopped: std::sync::atomic::AtomicBool::new(false),
125 mutex: std::sync::Mutex::new(()),
126 wake: std::sync::Condvar::new(),
127 }
128 }
129
130 pub fn is_stopped(&self) -> bool {
132 self.stopped.load(std::sync::atomic::Ordering::Acquire)
133 }
134
135 pub fn stop(&self) {
137 let _guard = self.mutex.lock().unwrap_or_else(|error| error.into_inner());
138 if !self.stopped.swap(true, std::sync::atomic::Ordering::AcqRel) {
139 self.wake.notify_all();
140 }
141 }
142
143 pub fn wait_timeout(&self, timeout: std::time::Duration) -> bool {
145 if self.is_stopped() {
146 return true;
147 }
148 let guard = self.mutex.lock().unwrap_or_else(|error| error.into_inner());
149 if self.is_stopped() {
150 return true;
151 }
152 let (_guard, _wait_result) = self
153 .wake
154 .wait_timeout(guard, timeout)
155 .unwrap_or_else(|error| error.into_inner());
156 self.is_stopped()
157 }
158}
159
160impl Default for DescendantMonitorStop {
161 fn default() -> Self {
162 Self::new()
163 }
164}
165
166#[derive(Clone, Copy)]
168pub enum CaptureStream {
169 Stdout,
170 Stderr,
171}
172
173#[derive(Debug, Clone)]
175pub struct ConsoleWindowInfo {
176 pub pid: u32,
177 pub title: String,
178 pub hwnd: u64,
179}
180
181#[derive(Clone, Copy, Debug, Eq, PartialEq)]
185pub struct ProcessSnapshot {
186 pub pid: u32,
187 pub parent_pid: u32,
188 pub start_time_a: u64,
189 pub start_time_b: u64,
190}
191
192#[derive(Clone, Debug, Eq, PartialEq)]
197pub enum SyncEnvironment {
198 Inherit,
200 Explicit(Vec<(std::ffi::OsString, std::ffi::OsString)>),
202}
203
204pub struct SpawnStdio<'a> {
210 pub stdin: StdioSource<'a>,
212 pub stdout: StdioSource<'a>,
214 pub stderr: StdioSource<'a>,
216 pub drain_timeout: Option<std::time::Duration>,
218 pub show_console: bool,
220}
221
222impl Default for SpawnStdio<'_> {
223 fn default() -> Self {
224 Self {
225 stdin: StdioSource::Null,
226 stdout: StdioSource::Parent,
227 stderr: StdioSource::Parent,
228 drain_timeout: Some(std::time::Duration::from_secs(2)),
229 show_console: false,
230 }
231 }
232}
233
234pub struct DaemonStdio<'a> {
240 pub stdout: DaemonStdioSource<'a>,
242 pub stderr: DaemonStdioSource<'a>,
244}
245
246impl Default for DaemonStdio<'_> {
247 fn default() -> Self {
248 Self {
249 stdout: DaemonStdioSource::Null,
250 stderr: DaemonStdioSource::Null,
251 }
252 }
253}
254
255pub enum DaemonStdioSource<'a> {
257 Null,
259 File(&'a std::fs::File),
261}
262
263pub enum StdioSource<'a> {
265 Null,
267 Parent,
269 File(&'a std::fs::File),
271 Pipe,
273}
274
275pub struct DaemonChild {
277 pub(crate) pid: u32,
278 pub(crate) inner: Box<dyn DaemonChildControl>,
279}
280
281pub(crate) trait DaemonChildControl:
282 Send + Sync + std::panic::UnwindSafe + std::panic::RefUnwindSafe
283{
284 fn kill(&mut self) -> std::io::Result<()>;
285 fn wait(&mut self) -> std::io::Result<i32>;
286 fn try_wait(&mut self) -> std::io::Result<Option<i32>>;
287}
288
289impl DaemonChild {
290 pub fn id(&self) -> u32 {
292 self.pid
293 }
294
295 pub fn kill(&mut self) -> std::io::Result<()> {
297 self.inner.kill()
298 }
299
300 pub fn wait(&mut self) -> std::io::Result<i32> {
302 self.inner.wait()
303 }
304
305 pub fn try_wait(&mut self) -> std::io::Result<Option<i32>> {
307 self.inner.try_wait()
308 }
309}
310
311pub struct SpawnedChild {
315 pub stdin: Option<std::process::ChildStdin>,
317 pub stdout: Option<std::process::ChildStdout>,
319 pub stderr: Option<std::process::ChildStderr>,
321 pub(crate) pid: u32,
322 pub(crate) inner: Box<dyn SpawnedChildControl>,
323}
324
325pub(crate) trait SpawnedChildControl:
326 Send + Sync + std::panic::UnwindSafe + std::panic::RefUnwindSafe
327{
328 fn kill(&mut self) -> std::io::Result<()>;
329 fn wait(&mut self) -> std::io::Result<i32>;
330 fn try_wait(&mut self) -> std::io::Result<Option<i32>>;
331 fn shutdown(&mut self);
332}
333
334impl SpawnedChild {
335 pub fn id(&self) -> u32 {
337 self.pid
338 }
339
340 pub fn kill(&mut self) -> std::io::Result<()> {
342 self.inner.kill()
343 }
344
345 pub fn wait(&mut self) -> std::io::Result<i32> {
347 self.inner.wait()
348 }
349
350 pub fn try_wait(&mut self) -> std::io::Result<Option<i32>> {
352 self.inner.try_wait()
353 }
354}
355
356impl Drop for SpawnedChild {
357 fn drop(&mut self) {
358 self.inner.shutdown();
359 }
360}
361
362#[derive(Clone, Copy)]
363pub enum ObserverScope {
364 SystemWide,
365 LaunchedProcessTree,
366}
367#[derive(Clone, Copy)]
368pub enum ObserverCategory {
369 File,
370 Network,
371 Process,
372}
373#[derive(Clone, Copy)]
374pub enum ObserverSupport {
375 Supported,
376 Partial,
377 Unavailable,
378}
379#[derive(Clone, Copy)]
380pub struct ObserverBackend {
381 pub support: ObserverSupport,
382 pub backend: &'static str,
383 pub reason: &'static str,
384}
385pub use crate::platform_imp::observer_backend;
386pub use crate::platform_imp::read_process_cmdline;
387pub use crate::platform_imp::read_process_file_handles;
388
389#[derive(Debug, Clone, Copy, PartialEq, Eq)]
391pub enum UnixSignalKind {
392 Interrupt,
393 Terminate,
394 Kill,
395}
396
397pub use crate::{
398 unix_set_priority, unix_signal_process, unix_signal_process_group, unix_signal_raw,
399};
400
401#[derive(Debug, Clone, Copy, PartialEq, Eq)]
409pub enum OwnerDeathCleanup {
410 OwnerDeathSignal,
412 KillOnOwnerHandleClose,
414 AlreadyContained,
416 SupervisorRequired,
418 Unsupported,
420}
421
422#[derive(Debug, Clone, Copy, PartialEq, Eq)]
430pub enum OwnerDeathCleanupStage {
431 RequestSignal,
433 CreateContainer,
435 JoinContainer,
437}
438
439#[derive(Debug)]
441pub struct OwnerDeathCleanupError {
442 pub stage: OwnerDeathCleanupStage,
444 pub source: std::io::Error,
446}
447
448impl std::fmt::Display for OwnerDeathCleanupError {
449 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
450 write!(f, "{:?}: {}", self.stage, self.source)
451 }
452}
453
454impl std::error::Error for OwnerDeathCleanupError {
455 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
456 Some(&self.source)
457 }
458}
459
460pub use crate::{
461 process_install_owner_death_cleanup as install_owner_death_cleanup,
462 process_owner_death_cleanup_target as owner_death_cleanup_target,
463};
464
465#[derive(Debug, Clone, Copy, PartialEq, Eq)]
472pub enum ProcessInspectErrorKind {
473 InvalidPid,
475 NotFound,
477 Unsupported,
479 Host,
481}
482
483#[derive(Debug)]
485pub struct ProcessInspectError {
486 pub kind: ProcessInspectErrorKind,
488 pub source: std::io::Error,
490}
491
492impl ProcessInspectError {
493 pub fn last_os_error(kind: ProcessInspectErrorKind) -> Self {
495 Self {
496 kind,
497 source: std::io::Error::last_os_error(),
498 }
499 }
500
501 pub fn stated(kind: ProcessInspectErrorKind, message: &str) -> Self {
503 Self {
504 kind,
505 source: std::io::Error::other(message.to_string()),
506 }
507 }
508}
509
510impl std::fmt::Display for ProcessInspectError {
511 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
512 write!(f, "{:?}: {}", self.kind, self.source)
513 }
514}
515
516impl std::error::Error for ProcessInspectError {
517 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
518 Some(&self.source)
519 }
520}
521
522pub use crate::{
523 process_executable_path as executable_path, process_force_kill as force_kill,
524 process_same_executable_path as same_executable_path,
525 process_signal_terminate as signal_terminate, ProcessLiveness,
526};
527
528pub struct ShutdownRequest {
540 flag: &'static std::sync::atomic::AtomicBool,
541}
542
543impl ShutdownRequest {
544 pub fn watching(flag: &'static std::sync::atomic::AtomicBool) -> Self {
555 Self { flag }
556 }
557
558 pub fn requested(&self) -> bool {
564 self.flag.load(std::sync::atomic::Ordering::Relaxed)
565 }
566}
567
568impl std::fmt::Debug for ShutdownRequest {
569 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
570 f.debug_struct("ShutdownRequest")
571 .field("requested", &self.requested())
572 .finish()
573 }
574}
575
576pub use crate::process_install_shutdown_request_handler as install_shutdown_request_handler;
577
578pub use crate::{
590 process_can_replace_current_image as can_replace_current_image,
591 process_replace_current_image as replace_current_image,
592};