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
// SAFETY: unsafe_code is legitimately required for `rt_sigaction(2)` FFI and
// the per-architecture inline assembly. All unsafe sites carry per-block
// SAFETY comments and are guarded by compile-time layout assertions.
//! Signal-handler installation for `varta-watch`.
//!
//! The single public entry point is [`install`], which installs handlers for
//! `SIGINT` and `SIGTERM` that flip an atomic shutdown latch provided by the
//! caller.
//!
//! On Linux the default path (`mode = Direct`) issues `rt_sigaction(2)`
//! directly through inline assembly, bypassing the libc wrapper (which
//! unconditionally substitutes its own `__restore_rt`). A startup readback
//! asserts the kernel preserved every field, and a live SIGUSR1 smoke test
//! proves the trampoline round-trips correctly before the first real signal
//! arrives. An operator opt-in (`mode = Libc`) delegates to libc's
//! `sigaction(3)` for kernels not yet certified against the direct path.
//!
//! On macOS and FreeBSD libc's `sigaction(3)` is always used (no restorer
//! issue exists on those platforms). On other Unix targets the POSIX
//! `signal(2)` fallback is used.
/// Signal-handler mode selection (`Direct` vs `Libc`).
pub
pub use SignalHandlerMode;
use io;
/// Install `SIGINT` and `SIGTERM` handlers that call `handler(sig)`.
///
/// `mode` selects the installation path on Linux:
/// - `Direct` (default): direct `rt_sigaction(2)` syscall — owns the kernel
/// ABI end-to-end, including the x86_64 signal-return trampoline. A
/// readback + live-delivery smoke test run at startup.
/// - `Libc`: libc `sigaction(3)` wrapper — the restorer is libc's own
/// `__restore_rt`. Use when running on a kernel not yet certified for the
/// direct path.
///
/// On macOS, FreeBSD, and other Unix, `mode` is ignored; libc / POSIX APIs
/// are the only option.
///
/// # Safety
///
/// Must be called exactly once, before any other threads are spawned and
/// before any competing code installs handlers for `SIGINT` or `SIGTERM`.
/// `handler` must be async-signal-safe; storing to an `AtomicI32` that is
/// `is_always_lock_free()` qualifies — richer operations (allocation, locking,
/// non-reentrant libc) do not.
// cfg-gated returns prevent fall-through to dead branches
pub unsafe