Skip to main content

daemon

Function daemon 

Source
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)

  1. First fork — Parent calls _exit(0) immediately.
  2. Session setup — Child calls setsid(), optionally chdir("/"), and optionally redirects stdio.
  3. Second (double) fork — Session-leader child calls _exit(0) immediately.
  4. 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 nochdir is false)
  • redirect_stdio fails (when noclose is 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");
}