procdog-agent 0.1.0

procdog process watchdog agent library
Documentation
use std::{
    env,
    io::{PipeWriter, Write},
    os::fd::{FromRawFd, RawFd},
};

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("Not running under procdog supervisor")]
    Unsupervised,
    #[error("procdog file descriptor number invalid")]
    FdInvalid,
    #[error("I/O error on procdog file handle ({0})")]
    IoError(nix::Error),
}

pub struct ProcdogAgent {
    writer: Option<PipeWriter>,
}

pub fn init(allow_unsupervised: bool) -> Result<ProcdogAgent, Error> {
    if let Ok(s_fd) = env::var("PROCDOG_FD") {
        let fd = RawFd::from_str_radix(&s_fd, 10).map_err(|_| Error::FdInvalid)?;
        let writer = unsafe { PipeWriter::from_raw_fd(fd) };
        nix::fcntl::fcntl(
            &writer,
            nix::fcntl::FcntlArg::F_SETFL(nix::fcntl::OFlag::O_NONBLOCK),
        )
        .map_err(|errno| Error::IoError(errno))?;
        Ok(ProcdogAgent {
            writer: Some(writer),
        })
    } else if allow_unsupervised {
        Ok(ProcdogAgent { writer: None })
    } else {
        Err(Error::Unsupervised)
    }
}

impl ProcdogAgent {
    pub fn heartbeat(&mut self) {
        if let Some(writer) = self.writer.as_mut() {
            let buf = [b'H'];
            writer
                .write(&buf)
                .expect("Error writing to procdog supervisor");
        }
    }
}