liana/src/daemonize.rs
Antoine Poinsot f10c35e964
daemonize: switch the pid and log file arguments
The caller and the definition had them swapped.. So it was logging to
the PID file and writing the PID to the log file..
2023-02-13 10:56:22 +01:00

70 lines
2.0 KiB
Rust

use std::env::set_current_dir;
use std::fs::File;
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::os::unix::io::AsRawFd;
use std::path::Path;
// This code was highly inspired from Frank Denis (@jedisct1) 'daemonize-simple' crate,
// available at https://github.com/jedisct1/rust-daemonize-simple/blob/master/src/unix.rs .
// MIT licensed according to https://github.com/jedisct1/rust-daemonize-simple/blob/master/Cargo.toml
pub unsafe fn daemonize(
chdir: &Path,
log_file: &Path,
pid_file: &Path,
) -> Result<(), &'static str> {
match libc::fork() {
-1 => return Err("fork() failed"),
0 => {}
_ => {
libc::_exit(0);
}
}
libc::setsid();
match libc::fork() {
-1 => return Err("Second fork() failed"),
0 => {}
_ => {
libc::_exit(0);
}
};
let fd = OpenOptions::new()
.read(true)
.open("/dev/null")
.map_err(|_| "Unable to open the stdin file")?;
if libc::dup2(fd.as_raw_fd(), 0) == -1 {
return Err("dup2(stdin) failed");
}
let fd = OpenOptions::new()
.create(true)
.append(true)
.open(log_file)
.map_err(|_| "Unable to open the stdout file")?;
if libc::dup2(fd.as_raw_fd(), 1) == -1 {
return Err("dup2(stdout) failed");
}
let fd = OpenOptions::new()
.create(true)
.append(true)
.open(log_file)
.map_err(|_| "Unable to open the stderr file")?;
if libc::dup2(fd.as_raw_fd(), 2) == -1 {
return Err("dup2(stderr) failed");
}
let pid = match libc::getpid() {
-1 => return Err("getpid() failed"),
pid => pid,
};
let pid_str = format!("{}", pid);
File::create(pid_file)
.map_err(|_| "Creating the PID file failed")?
.write_all(pid_str.as_bytes())
.map_err(|_| "Writing to the PID file failed")?;
set_current_dir(chdir).map_err(|_| "chdir() failed")?;
Ok(())
}