use std::io;
pub fn daemonize() -> io::Result<()> {
fork_and_leave_parent()?;
if unsafe { libc::setsid() } == -1 {
return Err(io::Error::last_os_error());
}
fork_and_leave_parent()?;
if unsafe { libc::chdir(c"/".as_ptr()) } == -1 {
return Err(io::Error::last_os_error());
}
redirect_std_to_dev_null()
}
fn fork_and_leave_parent() -> io::Result<()> {
match unsafe { libc::fork() } {
-1 => Err(io::Error::last_os_error()),
0 => Ok(()),
_ => unsafe { libc::_exit(0) },
}
}
fn redirect_std_to_dev_null() -> io::Result<()> {
let fd = unsafe { libc::open(c"/dev/null".as_ptr(), libc::O_RDWR) };
if fd == -1 {
return Err(io::Error::last_os_error());
}
for target in [libc::STDIN_FILENO, libc::STDOUT_FILENO, libc::STDERR_FILENO] {
if unsafe { libc::dup2(fd, target) } == -1 {
let e = io::Error::last_os_error();
unsafe { libc::close(fd) };
return Err(e);
}
}
if fd > libc::STDERR_FILENO {
unsafe { libc::close(fd) };
}
Ok(())
}