crate::ix!();
#[cfg(HAVE_DECL_FORK)]
pub fn fork_daemon(
nochdir: bool,
noclose: bool,
endpoint: &mut TokenPipeEnd) -> Result<i32,&'static str> {
let umbilical = TokenPipe::make();
if umbilical.is_none() {
return Err("pipe or pipe2 failed");
}
let pid: i32 = libc::fork();
if pid < 0 {
return Err("fork failed");
}
if pid != 0 {
endpoint = umbilical.unwrap().take_read_end();
umbilical.as_ref().unwrap().take_write_end().close();
let status: i32 = endpoint.token_read();
if status != 0 {
endpoint.close();
return Err("something went wrong while setting up child process.");
}
return Ok(pid);
}
endpoint = umbilical.as_ref().unwrap().take_write_end();
umbilical.as_ref().unwrap().take_read_end().close();
#[cfg(HAVE_DECL_SETSID)]
if libc::setsid() < 0 {
libc::exit(1); }
if !nochdir {
if libc::chdir("/") != 0 {
libc::exit(1); }
}
if !noclose {
let fd: i32 = libc::open("/dev/null", O_RDWR);
if fd >= 0 {
let err: bool =
libc::dup2(fd, STDIN_FILENO) < 0
|| libc::dup2(fd, STDOUT_FILENO) < 0
|| libc::dup2(fd, STDERR_FILENO) < 0;
if fd > 2 {
libc::close(fd);
}
if err {
libc::exit(1); }
} else {
libc::exit(1); }
}
endpoint.token_write(0);
Ok(0)
}