rmp/src/os_unix.rs

93 lines
2.5 KiB
Rust

use std::{
fs,
path::{Path, PathBuf},
process::{id, Command, Stdio},
};
use super::server::ServerError;
pub fn reserve_pid() -> Result<(), ServerError> {
let pid_path = get_pid_path()?;
is_running()?;
fs::write(&pid_path, id().to_string()).map_err(|err| ServerError::Io(err))?;
Command::new("chmod")
.args(&["600", &pid_path.to_string_lossy()])
.output()
.map_err(|err| ServerError::Io(err))?;
Ok(())
}
pub fn is_running() -> Result<bool, ServerError> {
let pid_path = get_pid_path()?;
match fs::read(&pid_path) {
Ok(old_pid) => {
let old_pid =
String::from_utf8(old_pid).map_err(|err| ServerError::from_debuggable(err))?;
let old_pid = old_pid.trim();
Ok(Command::new("ps")
.args(&["-p", old_pid])
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.map_err(|err| ServerError::Io(err))?
.success())
}
_ => Ok(false),
}
}
pub fn run_in_background() -> Result<(), ServerError> {
let this = std::env::args().next().unwrap();
Command::new(this)
.stdout(Stdio::null())
.stderr(Stdio::null())
.args(&["-s"])
.spawn()
.map_err(|err| ServerError::Io(err))?;
Ok(())
}
pub fn kill() -> Result<(), ServerError> {
let pid_path = get_pid_path()?;
let socket_path = get_socket_path()?;
let pid = fs::read(&pid_path).map_err(|_| ServerError::NotRunning)?;
let pid = String::from_utf8(pid).map_err(|err| ServerError::from_debuggable(err))?;
let pid = pid.trim();
Command::new("kill")
.arg(pid)
.spawn()
.map_err(|err| ServerError::Io(err))?;
Command::new("rm")
.args(&[
"-f",
&pid_path.to_string_lossy(),
&socket_path.to_string_lossy(),
])
.spawn()
.map_err(|err| ServerError::Io(err))?;
Ok(())
}
pub fn get_socket_path() -> Result<PathBuf, ServerError> {
Ok(get_runtime_dir()?.join("rmp.socket"))
}
fn get_runtime_dir() -> Result<PathBuf, ServerError> {
let uid = String::from_utf8(
Command::new("id")
.arg("-u")
.output()
.map_err(|err| ServerError::Io(err))?
.stdout,
)
.map_err(|err| ServerError::from_debuggable(err))?;
let dir = Path::new("/run/user").join(uid.trim().to_string());
Ok(dir)
}
fn get_pid_path() -> Result<PathBuf, ServerError> {
Ok(get_runtime_dir()?.join("rmp.pid"))
}