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_process_command_for_bounded_owner_death, configure_sync_contained_command,
7 configure_sync_daemon_command, configure_sync_daemon_command_with_inheritance,
8 configure_trampoline_command, current_executable_build_id, exact_trace_capability, exit_code,
9 monitor_console_windows, parent_has_console, prepare_capture_reader, set_process_name,
10 shell_command, soft_terminate_process_group, spawn_sync, spawn_sync_daemon,
11 spawn_sync_daemon_with_inheritance, start_descendant_monitor, start_exact_trace,
12 sync_child_native_handle, trampoline_exit_code, unix_mark_extra_fds_close_on_exec,
13 CaptureCancellation, TracedChild, WindowsJobHandle,
14};
15
16#[cfg(feature = "async-process")]
17pub use crate::{
18 PlatformChild, PlatformEmergencySignal, PlatformLifecycle, PlatformOutput, PlatformStdin,
19 SpawnSpec, StreamMode,
20};
21
22#[cfg(feature = "process-inspection")]
23pub use crate::{kill_tree, process_snapshot, process_snapshot_for_pid};
24
25#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
27pub struct ProcessCommandConfig {
28 pub creation_flags: Option<u32>,
29 pub create_process_group: bool,
30 pub nice: Option<i32>,
31 pub address_space_limit_bytes: Option<u64>,
32}
33
34#[derive(Clone, Copy, Debug, Eq, PartialEq)]
41pub struct DaemonExecInheritance {
42 descriptor: i32,
43}
44
45impl DaemonExecInheritance {
46 #[allow(dead_code)]
50 pub(crate) fn preserving_descriptor(descriptor: i32) -> Self {
51 Self { descriptor }
52 }
53
54 #[allow(dead_code)]
55 pub(crate) fn descriptor(self) -> i32 {
56 self.descriptor
57 }
58}
59
60#[derive(Clone, Debug, Eq, PartialEq)]
62pub struct ExactTraceCapability {
63 pub available: bool,
64 pub backend: &'static str,
65 pub reason: &'static str,
66 pub non_invasive_backend: &'static str,
67 pub non_invasive_grade: NonInvasiveObservationGrade,
68}
69
70#[derive(Clone, Copy, Debug, Eq, PartialEq)]
71pub enum NonInvasiveObservationGrade {
72 KernelNotification,
73 KernelHintReconciled,
74 SnapshotInferred,
75}
76
77#[derive(Clone, Debug, Default, Eq, PartialEq)]
79pub struct TraceOriginArtifact {
80 pub origin_pid: u32,
81 pub thread_id: u32,
82 pub architecture: String,
83 pub register_format: String,
84 pub executable: Option<std::path::PathBuf>,
85 pub registers: Vec<u8>,
86 pub stack_pointer: Option<u64>,
87 pub instruction_pointer: Option<u64>,
88 pub stack: Vec<u8>,
89 pub truncated: bool,
90 pub module_map: Vec<u8>,
91 pub module_map_truncated: bool,
92}
93
94#[derive(Clone, Debug, Eq, PartialEq)]
96pub struct ExactTraceEvent {
97 pub sequence: u64,
98 pub pid: u32,
99 pub parent_pid: Option<u32>,
100 pub parent_start_key: Option<u64>,
101 pub start_key: Option<u64>,
102 pub timestamp: std::time::SystemTime,
103 pub kind: ExactTraceEventKind,
104 pub executable: Option<std::path::PathBuf>,
105 pub argv: Option<Vec<std::ffi::OsString>>,
106 pub origin: Option<TraceOriginArtifact>,
107}
108
109#[derive(Clone, Debug, Eq, PartialEq)]
110pub enum ExactTraceEventKind {
111 Spawn,
112 Exec,
113 Exit {
114 exit_code: Option<i32>,
115 signal: Option<i32>,
116 raw_status: i64,
117 },
118 Loss {
119 reason: String,
120 },
121}
122
123#[derive(Clone, Copy, Debug, Eq, PartialEq)]
125pub enum DescendantEvent {
126 Started {
127 pid: u32,
128 parent_pid: Option<u32>,
134 },
135 Exited(u32),
136 Completed,
139}
140
141pub struct DescendantMonitorStop {
143 stopped: std::sync::atomic::AtomicBool,
144 mutex: std::sync::Mutex<()>,
145 wake: std::sync::Condvar,
146}
147
148impl DescendantMonitorStop {
149 pub fn new() -> Self {
151 Self {
152 stopped: std::sync::atomic::AtomicBool::new(false),
153 mutex: std::sync::Mutex::new(()),
154 wake: std::sync::Condvar::new(),
155 }
156 }
157
158 pub fn is_stopped(&self) -> bool {
160 self.stopped.load(std::sync::atomic::Ordering::Acquire)
161 }
162
163 pub fn stop(&self) {
165 let _guard = self.mutex.lock().unwrap_or_else(|error| error.into_inner());
166 if !self.stopped.swap(true, std::sync::atomic::Ordering::AcqRel) {
167 self.wake.notify_all();
168 }
169 }
170
171 pub fn wait_timeout(&self, timeout: std::time::Duration) -> bool {
173 if self.is_stopped() {
174 return true;
175 }
176 let guard = self.mutex.lock().unwrap_or_else(|error| error.into_inner());
177 if self.is_stopped() {
178 return true;
179 }
180 let (_guard, _wait_result) = self
181 .wake
182 .wait_timeout(guard, timeout)
183 .unwrap_or_else(|error| error.into_inner());
184 self.is_stopped()
185 }
186}
187
188impl Default for DescendantMonitorStop {
189 fn default() -> Self {
190 Self::new()
191 }
192}
193
194#[derive(Clone, Copy)]
196pub enum CaptureStream {
197 Stdout,
198 Stderr,
199}
200
201#[derive(Debug, Clone)]
203pub struct ConsoleWindowInfo {
204 pub pid: u32,
205 pub title: String,
206 pub hwnd: u64,
207}
208
209#[derive(Clone, Copy, Debug, Eq, PartialEq)]
213pub struct ProcessSnapshot {
214 pub pid: u32,
215 pub parent_pid: u32,
216 pub start_time_a: u64,
217 pub start_time_b: u64,
218}
219
220#[derive(Clone, Debug, Eq, PartialEq)]
225pub enum SyncEnvironment {
226 Inherit,
228 Explicit(Vec<(std::ffi::OsString, std::ffi::OsString)>),
230}
231
232pub struct SpawnStdio<'a> {
238 pub stdin: StdioSource<'a>,
240 pub stdout: StdioSource<'a>,
242 pub stderr: StdioSource<'a>,
244 pub drain_timeout: Option<std::time::Duration>,
246 pub show_console: bool,
248}
249
250impl Default for SpawnStdio<'_> {
251 fn default() -> Self {
252 Self {
253 stdin: StdioSource::Null,
254 stdout: StdioSource::Parent,
255 stderr: StdioSource::Parent,
256 drain_timeout: Some(std::time::Duration::from_secs(2)),
257 show_console: false,
258 }
259 }
260}
261
262pub struct DaemonStdio<'a> {
268 pub stdout: DaemonStdioSource<'a>,
270 pub stderr: DaemonStdioSource<'a>,
272}
273
274impl Default for DaemonStdio<'_> {
275 fn default() -> Self {
276 Self {
277 stdout: DaemonStdioSource::Null,
278 stderr: DaemonStdioSource::Null,
279 }
280 }
281}
282
283pub enum DaemonStdioSource<'a> {
285 Null,
287 File(&'a std::fs::File),
289}
290
291pub enum StdioSource<'a> {
293 Null,
295 Parent,
297 File(&'a std::fs::File),
299 Pipe,
301}
302
303pub struct DaemonChild {
305 pub(crate) pid: u32,
306 pub(crate) inner: Box<dyn DaemonChildControl>,
307}
308
309pub(crate) trait DaemonChildControl:
310 Send + Sync + std::panic::UnwindSafe + std::panic::RefUnwindSafe
311{
312 fn kill(&mut self) -> std::io::Result<()>;
313 fn wait(&mut self) -> std::io::Result<i32>;
314 fn try_wait(&mut self) -> std::io::Result<Option<i32>>;
315}
316
317impl DaemonChild {
318 pub fn id(&self) -> u32 {
320 self.pid
321 }
322
323 pub fn kill(&mut self) -> std::io::Result<()> {
325 self.inner.kill()
326 }
327
328 pub fn wait(&mut self) -> std::io::Result<i32> {
330 self.inner.wait()
331 }
332
333 pub fn try_wait(&mut self) -> std::io::Result<Option<i32>> {
335 self.inner.try_wait()
336 }
337}
338
339pub struct SpawnedChild {
343 pub stdin: Option<std::process::ChildStdin>,
345 pub stdout: Option<std::process::ChildStdout>,
347 pub stderr: Option<std::process::ChildStderr>,
349 pub(crate) pid: u32,
350 pub(crate) inner: Box<dyn SpawnedChildControl>,
351}
352
353pub(crate) trait SpawnedChildControl:
354 Send + Sync + std::panic::UnwindSafe + std::panic::RefUnwindSafe
355{
356 fn kill(&mut self) -> std::io::Result<()>;
357 fn wait(&mut self) -> std::io::Result<i32>;
358 fn try_wait(&mut self) -> std::io::Result<Option<i32>>;
359 fn shutdown(&mut self);
360}
361
362impl SpawnedChild {
363 pub fn id(&self) -> u32 {
365 self.pid
366 }
367
368 pub fn kill(&mut self) -> std::io::Result<()> {
370 self.inner.kill()
371 }
372
373 pub fn wait(&mut self) -> std::io::Result<i32> {
375 self.inner.wait()
376 }
377
378 pub fn try_wait(&mut self) -> std::io::Result<Option<i32>> {
380 self.inner.try_wait()
381 }
382}
383
384impl Drop for SpawnedChild {
385 fn drop(&mut self) {
386 self.inner.shutdown();
387 }
388}
389
390#[derive(Clone, Copy)]
391pub enum ObserverScope {
392 SystemWide,
393 LaunchedProcessTree,
394}
395#[derive(Clone, Copy)]
396pub enum ObserverCategory {
397 File,
398 Network,
399 Process,
400}
401#[derive(Clone, Copy)]
402pub enum ObserverSupport {
403 Supported,
404 Partial,
405 Unavailable,
406}
407#[derive(Clone, Copy)]
408pub struct ObserverBackend {
409 pub support: ObserverSupport,
410 pub backend: &'static str,
411 pub reason: &'static str,
412}
413pub use crate::platform_imp::observer_backend;
414pub use crate::platform_imp::read_process_argv;
415pub use crate::platform_imp::read_process_cmdline;
416pub use crate::platform_imp::read_process_file_handles;
417
418#[derive(Debug, Clone, Copy, PartialEq, Eq)]
420pub enum UnixSignalKind {
421 Interrupt,
422 Terminate,
423 Kill,
424}
425
426pub use crate::{
427 unix_set_priority, unix_signal_process, unix_signal_process_group, unix_signal_raw,
428};
429
430#[derive(Debug, Clone, Copy, PartialEq, Eq)]
438pub enum OwnerDeathCleanup {
439 OwnerDeathSignal,
441 KillOnOwnerHandleClose,
443 AlreadyContained,
445 SupervisorRequired,
447 Unsupported,
449}
450
451#[derive(Debug, Clone, Copy, PartialEq, Eq)]
459pub enum OwnerDeathCleanupStage {
460 RequestSignal,
462 CreateContainer,
464 JoinContainer,
466}
467
468#[derive(Debug)]
470pub struct OwnerDeathCleanupError {
471 pub stage: OwnerDeathCleanupStage,
473 pub source: std::io::Error,
475}
476
477impl std::fmt::Display for OwnerDeathCleanupError {
478 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
479 write!(f, "{:?}: {}", self.stage, self.source)
480 }
481}
482
483impl std::error::Error for OwnerDeathCleanupError {
484 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
485 Some(&self.source)
486 }
487}
488
489pub use crate::{
490 process_install_owner_death_cleanup as install_owner_death_cleanup,
491 process_owner_death_cleanup_target as owner_death_cleanup_target,
492};
493
494#[derive(Debug, Clone, Copy, PartialEq, Eq)]
501pub enum ProcessInspectErrorKind {
502 InvalidPid,
504 NotFound,
506 Unsupported,
508 Host,
510}
511
512#[derive(Debug)]
514pub struct ProcessInspectError {
515 pub kind: ProcessInspectErrorKind,
517 pub source: std::io::Error,
519}
520
521impl ProcessInspectError {
522 pub fn last_os_error(kind: ProcessInspectErrorKind) -> Self {
524 Self {
525 kind,
526 source: std::io::Error::last_os_error(),
527 }
528 }
529
530 pub fn stated(kind: ProcessInspectErrorKind, message: &str) -> Self {
532 Self {
533 kind,
534 source: std::io::Error::other(message.to_string()),
535 }
536 }
537}
538
539impl std::fmt::Display for ProcessInspectError {
540 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
541 write!(f, "{:?}: {}", self.kind, self.source)
542 }
543}
544
545impl std::error::Error for ProcessInspectError {
546 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
547 Some(&self.source)
548 }
549}
550
551pub use crate::{
552 process_executable_path as executable_path, process_force_kill as force_kill,
553 process_same_executable_path as same_executable_path,
554 process_signal_terminate as signal_terminate, ProcessLiveness,
555};
556
557pub struct ShutdownRequest {
569 flag: &'static std::sync::atomic::AtomicBool,
570}
571
572impl ShutdownRequest {
573 pub fn watching(flag: &'static std::sync::atomic::AtomicBool) -> Self {
584 Self { flag }
585 }
586
587 pub fn requested(&self) -> bool {
593 self.flag.load(std::sync::atomic::Ordering::Relaxed)
594 }
595}
596
597impl std::fmt::Debug for ShutdownRequest {
598 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
599 f.debug_struct("ShutdownRequest")
600 .field("requested", &self.requested())
601 .finish()
602 }
603}
604
605pub use crate::process_install_shutdown_request_handler as install_shutdown_request_handler;
606
607pub use crate::{
619 process_can_replace_current_image as can_replace_current_image,
620 process_replace_current_image as replace_current_image,
621};