blob: 6433bcd7d25b4eabffc869cb7918a78548e82a55 [file] [log] [blame]
use core::convert::Infallible;
use super::{
clone,
CloneFlags,
close,
EIO,
Error,
exit,
pipe2,
read,
Result,
write,
};
#[must_use = "Daemon::ready must be called"]
pub struct Daemon {
write_pipe: usize,
}
impl Daemon {
pub fn new<F: FnOnce(Daemon) -> Infallible>(f: F) -> Result<Infallible> {
let mut pipes = [0; 2];
pipe2(&mut pipes, 0)?;
let [read_pipe, write_pipe] = pipes;
if unsafe { clone(CloneFlags::empty())? } == 0 {
let _ = close(read_pipe);
f(Daemon {
write_pipe,
});
// TODO: Replace Infallible with the never type once it is stabilized.
unreachable!();
} else {
let _ = close(write_pipe);
let mut data = [0];
let res = read(read_pipe, &mut data);
let _ = close(read_pipe);
if res? == 1 {
exit(data[0] as usize)?;
unreachable!();
} else {
Err(Error::new(EIO))
}
}
}
pub fn ready(self) -> Result<()> {
let res = write(self.write_pipe, &[0]);
let _ = close(self.write_pipe);
if res? == 1 {
Ok(())
} else {
Err(Error::new(EIO))
}
}
}