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
//! Run the Moon MCHN daemon.
use crateEngine;
use crate::;
use Write;
use PathBuf;
use Command;
use Duration;
pub use Client;
pub use Start;
pub use ;
/// The timeout for the daemon to become ready after launch.
const READY_TIMEOUT: Duration = from_secs;
/// Starts the daemon by spawning `command` as a child process and returns once the
/// daemon is ready, or reports that one is already running.
///
/// The caller chooses the executable and arguments because the library cannot know
/// which binary implements the daemon mode. The spawned process must run [`serve`]
/// (or [`serve_in`] with [`Mode::Detached`]) with its standard output as the writer,
/// so the ready line reaches the launcher.
///
/// The launcher sets the child's standard input to null and captures its standard
/// output and standard error, replacing any redirection already set on `command`.
/// Once the ready line arrives, the launcher returns and the child keeps running as
/// the daemon. A background thread waits on the child so the daemon is reaped when
/// it exits, and the caller never needs to wait on it.
///
/// Before spawning, the launcher marks every descriptor from 3 up in the calling
/// process close-on-exec, so the daemon inherits none of them. The flag stays set
/// in the calling process: a caller that needs a later child of its own to inherit
/// one of those descriptors must clear the flag again.
///
/// # Errors
///
/// Returns an error if [`locate_state_directory`] fails, if `command` cannot be
/// spawned or its ready line cannot be read, or if the daemon fails to start or does
/// not become ready in time. The variants of [`Error`](crate::Error) describe each case.
/// Runs the detached daemon in this process until SIGTERM or a shutdown request,
/// writing its ready line to `out`.
///
/// # Errors
///
/// Returns an error if the state directory cannot be resolved, or if [`serve_in`] fails.
/// Locates the daemon's private state directory and checks it, creating nothing, and returns
/// its path.
///
/// The directory is `$MOONMCHN_HOME`, else `$XDG_STATE_HOME/moonmchn`, else
/// `$HOME/.local/state/moonmchn`; an empty variable counts as unset. A missing directory
/// comes back as resolved from those variables: no daemon has run there, and only the daemon
/// creates it, when it starts. An existing one must pass the daemon's checks: every directory
/// above it must belong to root or the effective user and must not be writable by other
/// users, unless it is a root-owned sticky directory such as `/tmp`; symlinks among them,
/// such as macOS's `/var`, are resolved. The state directory itself must be a real
/// directory, not a symlink, owned by the effective user with mode `0700`.
///
/// # Errors
///
/// Returns an error if none of those variables is set, if the chosen path is relative or
/// contains `..`, if an existing directory breaks the rules above, or if one cannot be
/// inspected. The variants of [`Error`](crate::Error) describe each case.