pub mod ipc;
pub mod manager;
pub mod process;
pub use ipc::{create_client_connection, socket_file_path, Connection};
pub use manager::{
ChangeRestartPolicyArgs, ExitStatus, ProcessStatus, RestartPolicy,
SendArgs, StartArgs, State,
};
pub use process::{Process, PID};
use serde::{Deserialize, Serialize};
use std::io;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub enum Error {
SocketError(io::Error),
SerializeError(serde_json::Error),
DeserializeError(serde_json::Error),
NoHomeDir,
ConnectionClosed,
WrongMessageKind,
EmptyProgram,
ProcessError(io::Error),
InvalidPID,
StayAliveError,
DirectoryCreationError(io::Error),
}
#[derive(PartialEq, Serialize, Deserialize, Debug)]
pub enum Command {
Hello,
Shutdown,
Start(StartArgs),
Output(PID),
Status(Option<usize>),
Stop(PID),
Restart(PID),
Send(SendArgs),
ChangeRestartPolicy(ChangeRestartPolicyArgs),
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Response {
pub success: bool,
pub message: String,
pub status: Option<Vec<ProcessStatus>>,
}
#[derive(Serialize, Deserialize)]
pub enum Message {
Command(Command),
Response(Response),
}
pub fn create_local_dirs() -> Result<()> {
let fp = socket_file_path()?;
match std::fs::create_dir_all(fp.parent().unwrap()) {
Ok(_) => Ok(()),
Err(e) => Err(Error::DirectoryCreationError(e)),
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::SocketError(e) => write!(f, "{}", e),
Error::SerializeError(e) => write!(f, "{}", e),
Error::DeserializeError(e) => {
write!(f, "{}", e)
}
Error::NoHomeDir => write!(f, "no home directory found for user"),
Error::ConnectionClosed => write!(f, "connection closed"),
Error::WrongMessageKind => write!(f, "got wrong kind of message"),
Error::EmptyProgram => write!(f, "empty program string"),
Error::ProcessError(e) => write!(f, "{}", e),
Error::InvalidPID => write!(f, "invalid PID"),
Error::StayAliveError => {
write!(f, "process did not stay alive long enough")
}
Error::DirectoryCreationError(e) => write!(f, "{}", e),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::SocketError(e) => Some(e),
Error::SerializeError(e) => Some(e),
Error::DeserializeError(e) => Some(e),
Error::ProcessError(e) => Some(e),
Error::DirectoryCreationError(e) => Some(e),
_ => None,
}
}
}