1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! [`ParentDeathCleanup`] — the scope of process-tree teardown that
//! [`Command::kill_on_parent_death`](crate::Command::kill_on_parent_death)
//! achieves when the **owning** process dies *abruptly* on the current platform.
/// The reach of the parent-death hardening
/// ([`Command::kill_on_parent_death`](crate::Command::kill_on_parent_death))
/// when the owning process dies **abruptly** — a `SIGKILL` of the owner or a
/// crash, where `Drop` never runs to tear the containment group down.
///
/// This is an **honest capability report**, not a request: query it with
/// [`Command::kill_on_parent_death_scope`](crate::Command::kill_on_parent_death_scope)
/// so a caller (for example a CLI wrapping this crate) can state the *actual*
/// reach of the hardening on the platform it runs on instead of overpromising a
/// whole-tree guarantee the OS cannot keep. The kernel offers no portable
/// "kill the tree when its creator dies" primitive on Unix — only Windows Job
/// Objects give it for free — so this value tells the truth per platform rather
/// than papering over the gap.
///
/// It describes **only the abrupt-death path**. The ordinary graceful teardown —
/// the owner exits or panics, so the [`ProcessGroup`](crate::ProcessGroup)'s
/// `Drop` runs — kills the whole tree on every supported platform regardless of
/// this value; that unconditional kill-on-drop guarantee is unchanged.
///
/// The variant is fixed per target at build time: it reflects which kernel
/// primitive backs the hardening, not any runtime state (nor whether
/// [`kill_on_parent_death`](crate::Command::kill_on_parent_death) was actually
/// called).
///
/// | Platform | Scope | Mechanism |
/// |---|---|---|
/// | Windows | [`WholeTree`](Self::WholeTree) | The kernel closes the Job Object handle when the owner dies and `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE` reaps the whole tree — guaranteed regardless of the knob. |
/// | Linux | [`DirectChildOnly`](Self::DirectChildOnly) | `PR_SET_PDEATHSIG(SIGKILL)` reaches only the **direct child**; with the owner gone nothing triggers `cgroup.kill`, so grandchildren survive. |
/// | macOS / the BSDs | [`Unsupported`](Self::Unsupported) | No `pdeathsig` equivalent exists, so an abrupt owner death triggers no cleanup at all. |
///
/// Non-exhaustive: a future platform — or a future whole-tree Linux mechanism —
/// may report a scope not listed here, so match it with a wildcard arm.