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
use PathBuf;
use ;
use ;
/// Test-only env var: when set, [`current_exe`] returns an error instead of resolving the real
/// path. `std::env::current_exe()` failing is otherwise unreachable from a test — the OS syscall
/// only errors if the running binary's own file was deleted mid-execution or under unusual
/// sandboxing — so this seam exists purely to exercise that error branch in its callers, mirroring
/// the `MOADIM_CRONTAB_BIN`/`MOADIM_LAUNCHCTL_BIN` test seams for external-binary resolution.
pub const CURRENT_EXE_FAIL_ENV: &str = "MOADIM_CURRENT_EXE_FAIL_FOR_TEST";
/// Resolve the path to the currently running executable.
///
/// Wraps [`std::env::current_exe`]; see `CURRENT_EXE_FAIL_ENV` for the test-only failure seam.
/// Spawn `command`, then hand the resulting child off to a detached reaper thread.
///
/// The daemon fires routine triggers from inside its own
/// long-running process. Rust's standard library does **not** reap a [`Child`]
/// when its handle is dropped, so a spawned process that exits would linger as a
/// zombie (`<defunct>`) in the process table for the daemon's entire lifetime,
/// slowly consuming PID-table slots. We [`wait`](Child::wait) on the child in a
/// background thread so the trigger stays fire-and-forget while the finished
/// child is still reaped.
///
/// `context` labels the spawn in the failure log. On success the reaper's
/// [`JoinHandle`] is returned so callers (and tests) may observe it; production
/// callers simply drop it and the thread runs to completion on its own.
/// Detach a thread that [`wait`](Child::wait)s on `child`, reaping it once it exits.