fork 0.1.0

Library for creating a new process using the fork and setsid syscalls
Documentation
use libc;
use std::process::exit;

/*
 * The parent forks the child
 * The parent exits
 * The child calls setsid() to start a new session with no controlling terminals
 * The child forks a grandchild
 * The child exits
 * The grandchild is now the daemon
 * ps -axo ppid,pid,pgid,sess,tty,tpgid,stat,uid,user,command | egrep "fork|sleep|PID"
 */

pub enum DaemonError {
    Fork,
}

impl DaemonError {
    fn __description(&self) -> &str {
        match *self {
            DaemonError::Fork => "unable to fork",
        }
    }
}

pub fn fork() -> Result<(), DaemonError> {
    unsafe {
        let pid = libc::fork();
        if pid < 0 {
            Err(DaemonError::Fork)
        } else if pid == 0 {
            Ok(())
        } else {
            exit(0);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::process::{id, Command};

    #[test]
    fn test_fork() {
        if let Ok(_) = fork() {
            println!("My pid is {}", id());
            unsafe {
                libc::setsid();
            }
            if let Ok(_) = fork() {
                println!("My pid is {}", id());
                Command::new("sleep")
                    .arg("300")
                    .output()
                    .expect("failed to execute process");
            }
        }
    }
}