pub fn daemon(nochdir: bool, noclose: bool) -> Result<Fork>Expand description
The daemon function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons.
nochdir = false, changes the current working directory to the root (/).noclose = false, redirects stdin, stdout, and stderr to/dev/null
§Return Value
This function only ever returns in the daemon (grandchild) process:
Ok(Fork::Child)— You are the daemon. The original process and the intermediate child have already exited via_exit(0).Err(...)— A system call failed before the daemon could be created.
Ok(Fork::Parent(_)) is never returned because both parent processes
call _exit(0) internally. You do not need to match on it:
use fork::{daemon, Fork};
// Recommended: use `if let` — no dead Parent arm needed
if let Ok(Fork::Child) = daemon(false, false) {
// Only the daemon reaches here
loop {
// daemon work…
std::thread::sleep(std::time::Duration::from_secs(60));
}
}If you prefer match for explicit error handling, mark the parent arm
unreachable:
use fork::{daemon, Fork};
match daemon(false, false) {
Ok(Fork::Child) => {
// daemon work…
}
Ok(Fork::Parent(_)) => unreachable!("daemon() exits both parent processes"),
Err(err) => eprintln!("daemon failed: {err}"),
}§Implementation (double-fork)
- First fork — Parent calls
_exit(0)immediately. - Session setup — Child calls
setsid(), optionallychdir("/"), and optionally redirects stdio. - Second (double) fork — Session-leader child calls
_exit(0)immediately. - Daemon continues — Grandchild (daemon) runs with no controlling terminal.
§Behavior Change in v0.4.0
Previously, noclose = false would close stdio file descriptors.
Now it redirects them to /dev/null instead, which is safer and prevents
file descriptor reuse bugs. This matches industry standard implementations
(libuv, systemd, BSD daemon(3)).
§Errors
Returns an io::Error if any of the underlying system calls fail:
- fork fails (e.g., resource limits)
- setsid fails (e.g., already a session leader)
- chdir fails (when
nochdiris false) redirect_stdiofails (whennocloseis false)
Example:
use fork::{daemon, Fork};
use std::process::Command;
if let Ok(Fork::Child) = daemon(false, false) {
Command::new("sleep")
.arg("3")
.output()
.expect("failed to execute process");
}