|
|
|
use nix::{
|
|
|
|
unistd::{
|
|
|
|
getppid,
|
|
|
|
setsid,
|
|
|
|
fork,
|
|
|
|
ForkResult,
|
|
|
|
close as fdclose,
|
|
|
|
chdir
|
|
|
|
},
|
|
|
|
sys::signal::{
|
|
|
|
signal,
|
|
|
|
Signal,
|
|
|
|
SigHandler
|
|
|
|
}
|
|
|
|
};
|
|
|
|
use std::process::exit;
|
|
|
|
|
|
|
|
pub trait OneOrMany<T> {
|
|
|
|
fn into_vec(self) -> Vec<T>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> OneOrMany<T> for T {
|
|
|
|
fn into_vec(self) -> Vec<T> {
|
|
|
|
vec![self]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> OneOrMany<T> for Vec<T> {
|
|
|
|
fn into_vec(self) -> Vec<T> {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn daemonize() {
|
|
|
|
if getppid().as_raw() != 1 {
|
|
|
|
setsig(Signal::SIGTTOU, SigHandler::SigIgn);
|
|
|
|
setsig(Signal::SIGTTIN, SigHandler::SigIgn);
|
|
|
|
setsig(Signal::SIGTSTP, SigHandler::SigIgn);
|
|
|
|
}
|
|
|
|
for fd in 0..=2 {
|
|
|
|
match fdclose(fd) { _ => () }
|
|
|
|
}
|
|
|
|
match chdir("/") { _ => () };
|
|
|
|
|
|
|
|
match fork() {
|
|
|
|
Ok(ForkResult::Parent {..}) => {
|
|
|
|
exit(0);
|
|
|
|
},
|
|
|
|
Ok(ForkResult::Child) => {
|
|
|
|
match setsid() { _ => () }
|
|
|
|
}
|
|
|
|
Err(_) => {
|
|
|
|
exit(255)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn setsig(sig: Signal, hnd: SigHandler) {
|
|
|
|
unsafe {
|
|
|
|
signal(sig, hnd).unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn vec_to_string(v: &[u8]) -> String {
|
|
|
|
String::from_utf8_lossy(v).to_string()
|
|
|
|
}
|